【问题标题】:OpenMP matrix multiplication nested loopsOpenMP 矩阵乘法嵌套循环
【发布时间】: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];      
             }
         }
     }
 }

【问题讨论】:

    标签: c++ c multithreading parallel-processing openmp


    【解决方案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 开始)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-07
      • 2015-12-26
      • 2013-05-18
      • 2014-08-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多