OpenMP 嵌套,数量不等。迭代次数

Jak*_* M. 2 c c++ openmp

我正在使用 OpenMP 并行化循环。在正常情况下,人们会使用:

#pragma omp for schedule(static, N_CHUNK)
for(int i = 0; i < N; i++) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

对于嵌套循环,我可以放置pragma内部或外部循环

#pragma omp for schedule(static, N_CHUNK) // can be here...
for(int i = 0; i < N; i++) {
#pragma omp for schedule(static, N_CHUNK) // or here...
    for(int k = 0; k < N; k++) {
    // both loops have consant number of iterations
    // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

但!我有两个循环,其中第二个循环中的迭代次数取决于第一个循环:

for(int i = 0; i < N; i++) {
    for(int k = i; k < N; k++) {
    // k starts from i, not from 0...
    }
}
Run Code Online (Sandbox Code Playgroud)

平衡这种循环的 CPU 使用率的最佳方法是什么?

seh*_*ehe 5

一如既往:

这里没有显示会产生影响的事情:

  • (非线性)线性内存寻址(还要注意循环的顺序
  • 使用共享变量;

至于你的最后一个场景:

for(int i = 0; i < N; i++) {
    for(int k = i; k < N; k++) {
    // k starts from i, not from 0...
    }
}
Run Code Online (Sandbox Code Playgroud)

我建议并行化外循环,原因如下:

  • 所有其他条件相同的粗粒度并行化通常会带来更好的性能,因为

    • 增加缓存局部性
    • 减少所需锁定的频率(请注意,这取决于我无法真正做出的循环内容的假设;我基于我/通常/并行化代码的经验)
  • 内部循环可能会变得如此短,以至于并行化效率低下(IOW:外部循环的范围是可预测的,内部循环的范围较小,或者也不适合静态调度)

  • 嵌套并行性很少能很好地扩展