c++ - OpenMP 嵌套,不等号。迭代次数

标签 c++ c openmp

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

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

对于嵌套循环,我可以将 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
    // ...
    }
}

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

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

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

最佳答案

一如既往:

此处未显示将产生差异的内容:

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

关于您的最后一个场景:

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

出于以下原因,我建议并行化外循环:

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

    • 增加缓存位置
    • 减少所需的锁定频率 (请注意,这取决于关于循环内容的假设,我无法真正做到;我基于我对/通常/并行代码的经验)
  • 内部循环可能会变得太短以至于并行化效率低下(换句话说:外部循环的范围是可预测的,内部循环则更少,或者也不适合静态调度)

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

关于c++ - OpenMP 嵌套,不等号。迭代次数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8008625/

相关文章:

c++ - 在 OpenMP 中并行化嵌套循环并使用更多线程执行内循环

c++ - 嵌套的 openMP 并行化结合 std::thread

c++ - CUDA - 简单的加法器程序总是给出零

c++ - 在 C++ 中 if(a=b) 是什么意思?对比 if(a==b)

c - printf 和 scanf 的逻辑问题

objective-c - 带有 BOOL 标志的应用程序状态

c++ - cython 中循环的并行化

c++ - 创建前 n 个整数的 std::set 的最有效方法是什么?

c++ - 使用 SOCI 从 PostgreSQL 数据库获取数据时出现错误

C:二进制命令行参数与二进制局部变量不同