嵌套在openmp中

时间:2018-10-21 11:05:35

标签: c loops openmp

使用openmp进行3个嵌套的并行循环的正确方法是什么? 这样:

#pragma omp parallel for
  for (i=0;i<SIZE;i++)
   for(j=0;j<SIZE;j++)
    for(k=0;k<SIZE;k++)
      mresult[i][j]=mresult[i][j] + matrixa[i][k]*matrixb[k][j];

或这种方式

  #pragma omp parallel for
  for (i=0;i<SIZE;i++)
   #pragma omp parallel for
   for(j=0;j<SIZE;j++)
    #pragma omp parallel for
    for(k=0;k<SIZE;k++)
      mresult[i][j]=mresult[i][j] + matrixa[i][k]*matrixb[k][j];

2 个答案:

答案 0 :(得分:1)

第二个严格来说是不正确的,因为存在比赛条件。同样,嵌套parallel通常不是一个好主意,因为它通常会产生比内核更多的线程,从而导致性能下降。

如果SIZE足够大以暴露足够的并行工作,则第一行就可以了。通常,由于在相同的并行化开销下需要做更多的工作,因此并行化最外面的循环是最好的。如果最外面的循环没有足够的并行性,则可以考虑添加collapse(2)-这是并行化循环的正确方法,尽管在这种情况下不是必需的。

总而言之,如果您想性能矩阵相乘,请使用tim18所示的库。从矩阵乘法获得最佳效率非常复杂,而且超出了此答案的范围。

正如Z-Boson指出的那样,您的第一个版本也不正确,因为默认情况下内部循环变量是共享的。您可以将它们标记为private(j,k)或更好,但只需在循环中定义它们就可以了,无论如何都更加清晰:

#pragma omp parallel for
for (int i=0;i<SIZE;i++)
  for (int j=0;j<SIZE;j++)
    for (int k=0;k<SIZE;k++)

答案 1 :(得分:-1)

这两个方法都无法达到netlib gemm的线程实现效率。毫无疑问,已经对此进行了许多次详细讨论。如果您的情况足够大,可以对并行性感兴趣,除非使用nvidia之类的特殊架构,否则外循环将足够大,以使每个线程都在几乎相等的连续内存块上忙碌,并且您将不希望阻止编译器应用内循环上的单线程优化。