OpenMP矩阵乘法嵌套循环

时间:2012-11-27 00:44:12

标签: c++ c multithreading parallel-processing 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];       
            }
        }
    }
 }

 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 个答案:

答案 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开始)。