gpt4 book ai didi

c++ - 使用 OpenMP 并行化嵌套循环

转载 作者:太空宇宙 更新时间:2023-11-04 11:56:47 25 4
gpt4 key购买 nike

我试图在我的代码中使用 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核上进行。

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

非常感谢。

最佳答案

如果 i_max 独立于 outerloop 中的 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 那么这将不起作用。在这种情况下,请遵循 Grizzly 的建议。但是你还可以尝试一件事。 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)

关于c++ - 使用 OpenMP 并行化嵌套循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15896048/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com