20

我正在尝试使用 openmp 计算二维矩阵的平均值。这个二维矩阵实际上是一个图像。

我正在对数据进行线程分割。例如,如果我有N线程而不是处理行数/N行数thread0,等等。

我的问题是:我可以将 openmp 缩减子句与“ #pragma omp parallel”一起使用吗?

#pragma omp parallel reduction( + : sum )
{
    if( thread == 0 )
       bla bla code 
       sum = sum + val;

    else if( thread == 1 )
       bla bla code
       sum = sum + val;
}
4

2 回答 2

30

是的,您可以 - 缩减条款适用于整个并行区域以及单个for工作共享结构。这允许例如减少在不同并行部分中完成的计算(重组代码的首选方式):

#pragma omp parallel sections private(val) reduction(+:sum)
{
   #pragma omp section
   {
      bla bla code
      sum += val;
   }
   #pragma omp section
   {
      bla bla code
      sum += val;
   }
}

您还可以使用 OpenMPfor工作共享构造在团队中的线程之间自动分配循环迭代,而不是使用部分重新实现它:

#pragma omp parallel for private(val) reduction(+:sum)
for (row = 0; row < Rows; row++)
{
   bla bla code
   sum += val;
}

请注意,归约变量是私有的,它们的中间值(即它们在parallel区域末端归约之前所持有的值)只是部分的,不是很有用。例如,下面的串行循环不能(很容易?)通过归约操作转换为并行循环:

for (row = 0; row < Rows; row++)
{
   bla bla code
   sum += val;
   if (sum > threshold)
      yada yada code
}

一旦 的累加值超过 的值,yada yada code应该在每次迭代中执行。当循环并行运行时, 的私有值可能永远不会达到,即使它们的总和达到了。sumthresholdsumthreshold

于 2012-11-08T14:13:03.730 回答
0

在您的情况下,sum = sum + val可以解释为val[i] = val[i-1] + val[i]一维数组(或val[rows][cols] = val[rows][cols-1] + val[rows][cols]二维数组),这是一个前缀和计算。

归约是前缀和的一种解决方案,您可以对任何交换关联运算符使用归约,例如“+”、“-”、“*”、“/”。

于 2014-05-07T20:14:53.237 回答