使用OpenMP减少

mku*_*use 13 openmp

我试图使用openmp计算2d矩阵的平均值.这个2d矩阵实际上是一个图像.

我正在进行线程划分数据.例如,如果我有N个线程,则使用thread0处理Rows/N个行,依此类推.

我的问题是我可以使用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;
}
Run Code Online (Sandbox Code Playgroud)

Hri*_*iev 24

是的,您可以 - 减少条款适用于整个并行区域以及单个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;
   }
}
Run Code Online (Sandbox Code Playgroud)

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

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

请注意,缩减变量是私有的,它们的中间值(即它们在parallel区域末尾减少之前保持的值)只是部分且不太有用.例如,以下串行循环不能(轻松?)转换为具有缩减操作的并行循环:

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

这里yada yada code应该在累计值sum超过值的每次迭代中执行threshold.当循环并行运行时,私有值sum可能永远不会达到threshold,即使它们的总和也是如此.