OpenMP 矩阵乘法嵌套循环
Posted
技术标签:
【中文标题】OpenMP 矩阵乘法嵌套循环【英文标题】:OpenMP matrix multiplication nested loops 【发布时间】:2012-11-14 13:40:22 【问题描述】:这是一个矩阵乘法代码,其中一个 i
循环并行化,另一个 j
循环并行化。对于这两个版本,C
数组的值都是正确的(我已经用小矩阵大小进行了测试)。与其他相比也没有性能提升。
谁能告诉我这两个版本有什么区别?无论矩阵大小如何,数组C
在两个版本中都准确吗?提前致谢
void mat_multiply ( void )
int t;
int i, j, k;
#pragma omp parallel for private(k) // parallelize i loop
for(i = 0; i < dimension; i++)
for(j = 0; j < dimension; j++)
for(k = 0; k < dimension; k++)
C[dimension*i+j] += A[dimension*i+k] * B[dimension*k+j];
void mat_multiply ( void )
int t;
int i, j, k;
for(i = 0; i < dimension; i++)
#pragma omp parallel for private(k) // parallelize j loop
for(j = 0; j < dimension; j++)
for(k = 0; k < dimension; k++)
C[dimension*i+j] += A[dimension*i+k] * B[dimension*k+j];
【问题讨论】:
【参考方案1】:起初,似乎第一个版本的线程创建开销较低,因为它只会创建一次线程。而在第二个版本中,线程似乎将被创建dimension
次。
但是根据this
人们可能会担心在内部创建新线程 环形。不用担心,GCC 中的 libgomp 足够聪明,实际上只 创建线程一次。团队完成工作后,线程 被送回“码头”,等待新的工作。
也就是说,clone系统调用被执行的次数 正好等于最大并发线程数。这 并行指令与 pthread_create 的组合不一样 和 pthread_join。
在第一个版本中,您应该保证变量j
也是私有的。
您可以只使用一种嵌套循环并行化的方法,而不是使用两种方法。在OpenMP 3.0中,嵌套循环的并行化可以通过for指令中的collapse子句来处理,即:
void mat_multiply ( void )
#pragma omp parallel for collapse(2)
for(int i = 0; i < dimension; i++)
for(int j = 0; j < dimension; j++)
for(int k = 0; k < dimension; k++)
C[dimension*i+j] += A[dimension*i+k] * B[dimension*k+j];
顺便说一句:看看块方法,您可以看到一个示例 here(从幻灯片 62 开始)。
【讨论】:
以上是关于OpenMP 矩阵乘法嵌套循环的主要内容,如果未能解决你的问题,请参考以下文章