C OpenMP优化?

C OpenMP优化?,c,gcc,openmp,C,Gcc,Openmp,我不明白为什么这个函数的性能这么差。我有一台core 2 Duo机器,我知道它只会创建2个trheads,所以不会有太多线程的问题。我希望结果更接近pthread结果 这些是我的编译标志(故意不做任何优化标志) gcc-fopenmp-lpthread-std=c99 matrixMul.c-o matrixMul 这是我的结果 Sequential matrix multiply: 2.344972 Pthread matrix multiply: 1.390983 OpenMP

我不明白为什么这个函数的性能这么差。我有一台core 2 Duo机器,我知道它只会创建2个trheads,所以不会有太多线程的问题。我希望结果更接近pthread结果

这些是我的编译标志(故意不做任何优化标志) gcc-fopenmp-lpthread-std=c99 matrixMul.c-o matrixMul

这是我的结果

Sequential matrix multiply: 2.344972
Pthread    matrix multiply: 1.390983
OpenMP     matrix multiply: 2.655910
CUDA       matrix multiply: 0.055871
Pthread Test PASSED
OpenMP  Test PASSED
CUDA    Test PASSED

void openMPMultiply(矩阵*a、矩阵*b、矩阵*p)
{
//int i,j,k;
memset(*p,0,sizeof(矩阵));
inttid,nthreads,i,j,k,chunk;
#pragma omp并行共享(a、b、p、n读取、块)私有(tid、i、j、k)
{
tid=omp_get_thread_num();
如果(tid==0)
{
nthreads=omp_get_num_threads();
}
区块=20;
//#pragma omp并行专用(i、j、k)
#计划的pragma omp(静态、块)
对于(i=0;i

感谢您的帮助。

由于矩阵乘法是一种令人尴尬的并行运算,所以在双核上其加速比应该接近2。由于缓存未命中率降低,矩阵乘法甚至通常会显示超线性加速(双核上大于2)。通过查看您的代码,我看不到明显的错误,但有些地方出了问题。以下是我的建议:

  • 只需再次检查工作线程的数量。在您的情况下,应该创建两个线程。或者,尝试通过调用
    omp\u set\u num\u threads
    进行设置。另外,查看2个内核是否得到充分利用(即,Windows上的CPU利用率为100%,Linux上的CPU利用率为200%)

  • 通过删除不必要的
    nthreads
    chunk
    来清理代码。这些可在平行段外制备。但是,即使是这样,也不应该影响加速

  • 矩阵是否为正方形(即高度==宽度==八小时)?如果它不是一个平方矩阵,那么可能存在工作负载不平衡,这会影响加速。但是,考虑到pthread的加速(大约1.6,这对我来说也很奇怪),我不认为有太多的工作负载不平衡

  • 尝试使用默认的静态调度:不要指定
    ,只需为
    编写
    #pragma omp

  • 我最好的猜测是
    矩阵的结构可能有问题。矩阵
    到底是什么样的?在最坏的情况下,虚假共享可能会严重影响性能。但是,在这样简单的矩阵乘法中,错误共享不应该是一个大问题。(如果你不知道细节,我可以解释更多细节)

  • 尽管您已经注释掉了,但千万不要将
    #pragma omp parallel for
    放在
    for-k
    上,这会导致嵌套并行循环。在矩阵乘法中,它是绝对浪费的,因为最外层的循环是可并行的

  • 最后,尝试运行以下非常简单的OpenMP矩阵乘法代码,并查看加速:

    double A[N][N], B[N][N], C[N][N];
    #pragma omp parallel for
    for (int row = 0; row < N; ++row)
      for (int col = 0; col < N; ++col)
        for (int k = 0; k < N; ++k)
          C[row][col] += A[row][k]*B[k][col];
    
    双A[N][N]、B[N][N]、C[N][N]; #pragma-omp并行 对于(int行=0;行
    如果对此函数应用优化,结果如何?使用-O2优化的结果\n顺序矩阵乘法:0.787335\n线程矩阵乘法:0.524749\n线程矩阵乘法:1.055698共享变量太多可能会导致死亡(取决于omp的gccs实现)。看到您的pthreads版本可能会很好,因为它可能忽略了一些可以让它运行得更快的东西
    double A[N][N], B[N][N], C[N][N];
    #pragma omp parallel for
    for (int row = 0; row < N; ++row)
      for (int col = 0; col < N; ++col)
        for (int k = 0; k < N; ++k)
          C[row][col] += A[row][k]*B[k][col];