使用OpenMP减少

时间:2012-11-08 13:48:53

标签: openmp

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

我正在进行线程划分数据。例如,如果我有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;
}

2 个答案:

答案 0 :(得分:20)

是的,您可以 - 还原子句适用于整个并行区域以及单个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;
   }
}

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

#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的累计值超过sum的值,就应该在每次迭代中执行threshold。当循环并行运行时,sum的私有值可能永远不会达到threshold,即使它们的总和也是如此。

答案 1 :(得分:0)

在您的情况下,sum = sum + val可以解释为1-d数组中的val[i] = val[i-1] + val[i](或2-d数组中的val[rows][cols] = val[rows][cols-1] + val[rows][cols]),这是prefix sum计算。< / p>

缩减是前缀和的解决方案之一,您可以将缩减用于任何可交换的关联运算符,例如&#39; +&#39;,&#39; - &#39;,&#39; *&# 39;,&#39; /&#39;。