对于相同的精确计算,无法解释的不同OMP_GET_WTIME()

Unexplained different omp_get_wtime() for the same exact computation

本文关键字:OMP GET WTIME 无法解释 于相同 计算      更新时间:2023-10-16

我在Visual Studio(实际上C (中编写代码,我意识到,在并行运行特定函数时(仅执行基本矩阵乘法(,所采用的计算时间非常不同,而不同的条件下运行。

具有以下令人困惑的输出:1/我第一次运行并行函数时,omg_get_wtime((给出了串行版本上方的计算时间方式2/我称之为的后续时间,它给出了大大改善的计算时间。我的问题是:首先,同一功能如何给出不同的时间(即第一次运行给出的时间与后续运行的时间截然不同...(

#include<iostream>
#include<conio.h>
#include<iomanip>
#include<omp.h>
#include<stdlib.h>
using namespace std;
const int ROW = 50;
const int COL = 50; 
class matmul
{
    int a[ROW][COL];
    int row;
    int col;
    //int* prow;
public:
    matmul() : row(0), col(0) {} 
    ~matmul() {} 
    void display();
    matmul multiply_par1(matmul m1, matmul m2);

    void generate_matrix(int row, int col);
};

void matmul::display()
{
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
            cout << setw(5) << a[i][j];
        cout << endl;
    }
}


matmul matmul::multiply_par1(matmul m1, matmul m2)
{
    int i = 0;
    int j = 0;
    int k = 0;
    matmul temp;
    temp.row = m1.row;
    temp.col = m2.col;
    double st = omp_get_wtime();
    int nbr = m1.row;
    int nbc = m2.col;
#pragma omp parallel private( i, j, k) // shared(nbr,nbc)
    for (i = 0; i < nbr; i++)
        for (j = 0; j < nbc; j++)
        {
            temp.a[i][j] = 0;
            {
                for (k = 0; k < temp.col; k++)
               temp.a[i][j] += m1.a[i][k] * m2.a[k][j];
            }
        }
    double en = omp_get_wtime();
    printf("Parallel run: %lfn", en - st);
    return temp;
}

void matmul::generate_matrix(int r, int c)
{
    //matrix temp;
    row = r;
    col = c;
    for (int i = 0; i < row; i++)
        for (int j = 0; j < col; j++)
        {
            a[i][j] = rand() % 10;
        }
}

int main()
{
    int Size = 10;
    int* arr = new int[Size];
    matmul m1, m2, m3, m4, m5,m6,m7;
    int r1, c1;
    if (Size > 100)
    {
        cout << "matrix quite large to display...n";
    }
    else
    {
        cout << "Generating 1rst matrix...n";
        m1.generate_matrix(10, 10);
        m1.display();
        cout << "Generating 2nd matrix...n";
        m2.generate_matrix(10, 10);
        m2.display();

        m4 = m3.multiply_par1(m1, m2);
        cout << "Resultant parallel matrix is :n";
        //m5.display();
        m5 = m3.multiply_par1(m1, m2);
        cout << "Resultant parallel matrix is :n";
        //m6.display();

        m6 = m3.multiply_par1(m1, m2);
        cout << "Resultant parallel matrix is :n";
        //m6.display();
        m7 = m3.multiply_par1(m1, m2);
        cout << "Resultant parallel matrix is :n";
        //m6.display();

    }
    return 0;
}

我希望运行时间相同,但是第一个跑步时间显着不同。我在执行时获得以下输出:

Parallel running time: 0.000583
Resultant parallel matrix is :
Parallel running time: 0.000016
Resultant parallel matrix is :
Parallel running time: 0.000014
Resultant parallel matrix is :
Parallel running time: 0.000014
Resultant parallel matrix is :

您看到的0.000583真的不合适,我不明白为什么...

至关重要的是,在上面使用一次代码(例如500x500矩阵(的情况下,我们是否可以对代码进行改进,可以产生更好的wtime((?

OpenMP必须在执行并行部分(详细信息(之前创建线程。创建线程需要时间,这是您在第一个测量中观察到的。

但是,OpenMP实现不会在并行区域之间创建新线程,因为它使用线程池(它回收先前创建的线程(。这就是为什么随后的测量要好得多的原因。

在您的情况下,矩阵很小,因此多线程的优势被线程创建的开销所遮蔽。对于后续的呼叫,使用多线程可能仍然有益。因此,始终测量第一个,后续和总平均值,以确保从长远来看,代码值得并行。