我将在这里尝试以更明确的方式重新表述@HighPerformanceMark 的答案(即使用一些代码草图来支持语句)。只是为了解决想法,假设您的循环的串行版本如下所示:
for(int ii = 0; ii < max; ii++)
{
// Do a lot of work based on ii
if(ii==0)
{
//////////////////////////////////////////////////
// Do something special for the first iteration //
//////////////////////////////////////////////////
}
}
在之前的答案中简要提出的是用这个简单的逻辑将其并行化
// Move the loop body into a function
void loopIteration(const size_t ii) {
// Do a lot of work based on ii
}
#pragma omp parallel
{
// Single directive: the first one enters, the other wait at the implicit barrier
#pragma omp single
{
loopIteration(0);
//////////////////////////////////////////////////
// Do something special for the first iteration //
//////////////////////////////////////////////////
} // single: implicit barrier
// Loop work-sharing construct on the remaining iterations
#pragma omp for
for(int ii = 1; ii < max; ii++)
{
loopIteration(ii);
} // for: implicit barrier
} // parallel
主要思想是将循环体移动到一个函数中,以避免代码重复,并从循环中显式展开第一次迭代。