【问题标题】:Parallelization of nested loops with OpenMP使用 OpenMP 并行化嵌套循环
【发布时间】:2013-04-09 07:39:08
【问题描述】:

我试图在我的代码中使用 OpenMP 并行化以下循环

 double pottemp,pot2body;
 pot2body=0.0;
 pottemp=0.0;

 #pragma omp parallel for reduction(+:pot2body) private(pottemp) schedule(dynamic)
 for(int i=0;i<nc2;i++)
    {
     pottemp=ener2body[i]->calculatePot(ener2body[i]->m_mols);
     pot2body+=pottemp;
    }

对于函数'calculatePot',该函数内部的一个非常重要的循环也被OpenMP并行化了

   CEnergymulti::calculatePot(vector<CMolecule*> m_mols)
   {
        ...

        #pragma omp parallel for reduction(+:dev) schedule(dynamic)
        for (int i = 0; i < i_max; i++)
        {
         ...
         }
     }

看来我的并行化涉及嵌套循环。当我删除最外层循环的并行化时, 似乎该程序的运行速度比最外层循环并行化的程序快得多。测试在 8 个核心上进行。

我认为这种并行化的低效率可能与嵌套循环有关。有人建议我在并行化最外层循环时使用“折叠”。但是,由于最外层循环和内层循环之间仍然存在一些东西,因此据说在这种情况下不能使用“折叠”。在仍然使用 OpenMP 的同时,我还有其他方法可以尝试提高这种并行化的效率吗?

非常感谢。

【问题讨论】:

  • 为什么需要并行化 Poth 循环?如果calculatePot 运行时间足够长以保证包含循环的并行化,它应该提供足够的并行化来耗尽所有可用的并行资源。如果它并不总是这样做,您可以使用 omp if 子句在没有用时不并行化内部循环

标签: c++ parallel-processing nested openmp


【解决方案1】:

如果 i_max 与外循环中的 i 无关,您可以尝试融合循环(本质上是崩溃)。这是我经常做的事情,这通常会给我带来一点推动。我也更喜欢“手动”融合循环而不是使用 OpenMP,因为 Visual Studio 仅支持没有崩溃的 OpenMP 2.0,我希望我的代码可以在 Windows 和 Linux 上运行。

#pragma omp parallel for reduction(+:pot2body) schedule(dynamic)
for(int n=0; n<(nc2*i_max); n++) {
    int i = n/i_max; //i from outer loop
    int j = n%i_max; //i from inner loop 
    double pottmp_j = ... 
    pot2body += pottmp_j;
}

如果 i_max 依赖于 j 那么这将不起作用。在这种情况下,请遵循灰熊的建议。但是您可以尝试另一件事。 OpenMP 有开销。如果 i_max 太小,那么使用 OpenMP 实际上可能会更慢。如果在 pragma 末尾添加 if 子句,则 OpenMP 将仅在语句为真时运行。像这样:

const int threshold = ... // smallest value for which OpenMP gives a speedup.
#pragma omp parallel for reduction(+:dev) schedule(dynamic) if(i_max > threshold)

【讨论】:

  • 谢谢。我认为带阈值的 if 语句是有道理的。
  • 还有一件事要尝试。如果你只并行化最外层的循环会发生什么?只要 nc2 足够大并且由于您使用的是 schedule(dynamic) 这也可能会产生良好的结果,因为 dynamic 会处理 i_max 小和 i_max 大的情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-05
  • 1970-01-01
相关资源
最近更新 更多