如何使用OpenMP任务实现缩减?

时间:2018-11-24 15:49:57

标签: c parallel-processing openmp reduction

我有执行以下简化操作的OpenMP代码:

for(k = 0; k < m; k++) 
{
      #pragma omp parallel for private(i) reduction(+:mysum) schedule(static) 
      for (i = 0; i < m; i++)
      {
           mysum += a[i][k] * a[i][k];
      }
}

我想使用OpenMP Tasks创建与该代码等效的代码。这是我根据this文章尝试的内容:

for(k = 0; k < m; k++) 
{
    #pragma omp parallel reduction(+:mysum)
    {
         #pragma omp single 
         {
                  for (i = 0; i < m; i++) 
                  {
                        #pragma omp task private(i) shared(k)
                        {
                                partialSum += a[i][k] * a[i][k];
                        }
                   }
         }

         #pragma omp taskwait
         mysum += partialSum;
     }
 }

变量partialSum被声明为threadprivate,它也是一个全局变量:

int partialSum = 0;
#pragma omp threadprivate(partialSum)

a是一个简单的整数数组(m x m)。

问题是,当我多次运行上面的代码(带有任务的代码)时,我得到的结果是不同的。

您对我应该进行哪些更改以使它起作用有想法吗?

谢谢你

1 个答案:

答案 0 :(得分:1)

private变量未初始化(至少不通过其外部值初始化)。 i应该是firstprivate

如果您只是摆脱private(i) shared(k),则默认情况下一切正确。 k来自parallel部分之外,因此在shared部分中隐含parallel。这也使其在任务生成构造中隐式shared。目前i也已共享/共享。如果改为在本地定义(for (int i...,则它在private部分隐式变成parallel,在任务生成结构中隐式变成firstprivate

您还应该添加

#pragma omp atomic
mysum += partialSum;

另一方面,您不一定需要taskwait(请参阅this answer

请注意,演讲正确使用了firstprivate