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

How can I achieve reduction using OpenMP Tasks?

我有执行简单缩减的 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 任务。这是我通过关注 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)。

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

你知道我应该改变什么来完成这项工作吗?

恭喜

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

如果你只是去掉 private(i) shared(k) 默认情况下一切都是正确的。 k 来自 parallel 部分之外,因此在 parallel 部分中隐式 shared。这也使得它在任务生成结构中隐含 shared。现在 i 也是 shared/shared。如果您在本地定义它,(for (int i...),它会隐式 privateparallel 部分,因此在任务生成结构中隐式 firstprivate

你还应该添加

#pragma omp atomic
mysum += partialSum;

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

请注意,演讲使用 firstprivate 是正确的。