这是一个矩阵乘法码,其中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];
}
}
}
}
答案 0 :(得分:4)
首先,看起来第一个版本的线程创建开销较低,因为它只会创建一次线程。在第二个版本中,您将创建线程dimension
次。
但根据this
人们可能会担心在内部创建新线程 环。不用担心,GCC中的libgomp实际上只是智能化 创建一次线程。一旦团队完成了它的工作,线程 被送回“码头”,等待新工作。
换句话说,执行克隆系统调用的次数 完全等于最大并发线程数。该 parallel指令与pthread_create的组合不同 和pthread_join。
在第一个版本中,您应该保证J也是私有的。
您可以将嵌套循环并行化,而不是两种方法。在 OpenMP 3.0 中,可以使用for指令中的 collapse子句来解决循环嵌套问题。 e.g:
void mat_multiply ( void ) {
int t;
int i, j, k;
#pragma omp parallel for collapse(2) private (k)
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];
}
}
顺便说一下:看一下块方法,你可以看到一个例子here(从幻灯片62开始)。