[英]OpenMP matrix multiplication nested loops
这是一个矩阵乘法代码,其中一个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];
}
}
}
}
起初,似乎第一个版本的线程创建开销较低,因为它只会创建线程一次。 而在第二个版本中,似乎线程将被创建dimension
时间。
但是按照这个
人们可能会担心在内循环中创建新线程。 不用担心,GCC 中的 libgomp 足够聪明,实际上只创建一次线程。 一旦团队完成其工作,线程将返回到“停靠”,等待新的工作要做。
也就是说,clone系统调用的执行次数正好等于最大并发线程数。 parallel 指令与 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];
}
顺便说一句:看看块方法,你可以在这里看到一个例子(从幻灯片 62 开始)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.