目前,在我的代码深处,我正在使用嵌套的for循环(N1 = ~10000,N2 = ~500,x,y = 10-50)。我使用#pragma omp
让OpenMP在几个核心上分配我的计算。
#pragma omp parallel for
for (int i = 0; i < N1; ++i)
{
for (int j = 0; j < N2; ++j)
{
for (int k = x; k <= y; ++k)
{
// calculation
}
}
}
现在,我的两个内圈成为条件
#pragma omp parallel for
for (int i = 0; i < N1; ++i)
{
if (toExecute[i])
{
for (int j = 0; j < N2; ++j)
{
for (int k = x; k <= y; ++k)
{
// calculation
}
}
}
}
内部嵌套循环需要很长时间,或者立即完成。当然,我可以通过用更短的循环替换外循环和if语句并查找后面的索引来省略if语句。
我的问题是:OpenMP足够聪明,可以在外部循环中处理if语句,还是我必须手动执行某些操作?
我目前在Visual Studio 2017中使用C ++,如果这很重要(我认为OpenMP版本有点落后)。
答案 0 :(得分:2)
理想情况下,您应该让OpenMP为您处理。但是,当你做表演的时候,你一定要试着看看什么对你最好。实际上,通过手动操作可以获得极大的加速。 OpenMP并非无所不知,他不了解有关计算的所有细节和情报。
如果您的计算意味着任何迭代的金额相同,那么您的条件可能会导致关于最外部循环的一些不同的工作量。因此,理论上,动态调度应该更合适
#pragma omp parallel for schedule(dynamic)
您还可以尝试static
或guided
调度,这可能适合您的计算(我不知道您的计算细节,所以我不能说)并使用粒度块。
要做的其他测试,如果你能负担得起(即它是可并行化的吗?),你应该尝试在内部循环中移动并行化。 你甚至可以嵌套并行化,它有时会提供很好的加速。一步一步地尝试和调整,花点时间看看是什么给你最好的输出。只是为了提醒您,这些调整通常不是针对不同架构的通用,因此需要在性能和代码可重用性之间进行良好的权衡。