C++ 无法解释的不同omp_get_wtime()用于相同的精确计算

C++ 无法解释的不同omp_get_wtime()用于相同的精确计算,c++,c,openmp,C++,C,Openmp,我正在Visual Studio(实际上是C++)中编写一段代码,我意识到在并行运行特定函数时(只需执行基本矩阵乘法),在相同条件下运行不同的函数所需的计算时间是非常不同的 具有以下令人费解的输出: 1/在我第一次运行并行化函数时,omg_get_wtime()提供了一种高于串行版本的计算时间方式 2/以后我称之为它的时候,它会大大提高计算时间。 我的问题是:为什么同一个函数一开始给出的时间不同(即,第一次运行给出的时间与后续运行的时间非常不同…) 正如您所看到的,0.000583确实不适合,我

我正在Visual Studio(实际上是C++)中编写一段代码,我意识到在并行运行特定函数时(只需执行基本矩阵乘法),在相同条件下运行不同的函数所需的计算时间是非常不同的

具有以下令人费解的输出: 1/在我第一次运行并行化函数时,omg_get_wtime()提供了一种高于串行版本的计算时间方式 2/以后我称之为它的时候,它会大大提高计算时间。 我的问题是:为什么同一个函数一开始给出的时间不同(即,第一次运行给出的时间与后续运行的时间非常不同…)

正如您所看到的,0.000583确实不适合,我不明白为什么


至关重要的是,在上面的代码只使用一次的情况下(比如对于500x500矩阵),我们是否可以对代码进行改进以产生更好的wtime()?OpenMP必须在执行并行部分()之前创建线程。创建线程需要时间,这是您在第一次测量中观察到的

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


在您的例子中,矩阵非常小,因此线程创建的开销掩盖了多线程的优势。但是,对于后续调用,使用多线程可能仍然是有益的。因此,请始终测量第一个线程、后续线程和总平均值,以确保从长远来看,代码段值得并行化。

第一次创建线程的开销似乎很大。在这之后,它使用池,所以它变得更快。看看“线程启动开销”。对不起,Gilles Philippe,我不是openMP方面的专家,你说的“开销”是什么意思?(我不知道它是什么)[也谢谢你的评论顺便说一句]执行任务需要额外的计算。在您的情况下,在执行循环之前,OpenMP必须创建线程,这需要时间。如果矩阵非常小,那么如果在单个线程中创建线程,那么创建线程的成本可能会高于实际计算的成本。但是,如果OpenMP可以在后续的多线程部分中使用,那么使用多线程可能仍然是有益的。感谢Gilles Philippe的解释。关键的是,如果上面的代码只使用一次(比如500x500矩阵),我们是否可以对代码进行改进,从而生成更好的wtime()?[我可能会转移到主要问题]@Faissal如果您的应用程序启动,对500x500矩阵进行矩阵乘法,然后关闭,那么您必须进行测量,以确保并行化是有益的。如果您的意思是代码偶尔被调用一次,那么它可能仍然是有益的。在任何情况下,规则都是在做出任何结论之前进行测量。在这一点上,OpenMP标准不需要线程池,也不需要在并行部分之间重新创建线程。您的语句“OpenMP不会在每次进入并行部分时创建新线程”更准确地说是“OpenMP实现不会在并行区域之间创建新线程”。这句话在实践中似乎是正确的。@Zboson谢谢你的更正,我将根据你的建议编辑我的答案。
#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: %lf\n", 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 :