使用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];
答案 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之类的特殊架构,否则外循环将足够大,以使每个线程都在几乎相等的连续内存块上忙碌,并且您将不希望阻止编译器应用内循环上的单线程优化。