use*_*972 3 c c++ parallel-processing multithreading openmp
这是一个矩阵乘法代码,其中一个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];
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
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];
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
起初,似乎第一个版本的线程创建开销较低,因为它只会创建线程一次。而在第二个版本中,线程似乎会被创建dimension多次。
但是按照这个
人们可能会担心在内循环中创建新线程。不用担心,GCC 中的 libgomp 足够聪明,实际上只创建一次线程。一旦团队完成其工作,线程将返回到“停靠”,等待新的工作要做。
也就是说,clone系统调用的执行次数正好等于最大并发线程数。parallel 指令与 pthread_create 和 pthread_join 的组合不同。
在第一个版本中,您应该保证该变量j也是私有的。
您可以只使用一种嵌套循环并行化的方法,而不是使用两种方法。在OpenMP的3.0,嵌套循环的并行化可以通过处理崩溃子句中的指令,即:
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];
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句:看看块方法,你可以在这里看到一个例子(从幻灯片 62 开始)。