OpenMP 和嵌套并行性

Ins*_*oop 3 c++ openmp

我想“嵌套”并行使用 OpenMP。这是一个玩具代码:

#include <iostream>
#include <cmath>

void subproblem(int m) {
  #pragma omp parallel for
  for (int j{0}; j < m; ++j) {
    double sum{0.0};
    for (int k{0}; k < 10000000; ++k) {
      sum += std::cos(static_cast<double>(k));
    }
    #pragma omp critical
    { std::cout << "Sum: " << sum << std::endl; }
  }
}

int main(int argc, const char *argv[]) {
  int n{2};
  int m{8};

  #pragma omp parallel for
  for (int i{0}; i < n; ++i) {
    subproblem(m);
  }

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这就是我想要的:

  • 如果 n >=(我的机器上的核心数),我只想并行化第一个循环。
  • 如果 n <(我的机器上的核心数),我希望 OpenMP 在内循环中启动线程,但我不希望线程总数超过我的机器上的核心数。

到目前为止,我只找到了一种禁用嵌套并行性或始终允许它的解决方案,但我正在寻找一种仅在启动的线程数低于核心数时才启用它的方法。

是否有针对使用任务的 OpenMP 解决方案?

Wyz*_*a-- 5

您可以告诉 OpenMP 将嵌套循环“折叠”为 n*m 迭代空间上的单个并行部分,而不是使用一对嵌套并行部分:

#pragma omp parallel for collapse(2)
for (int i{0}; i < n; ++i) {
  for (int j{0}; j < m; ++j) {
    // ...
  }
}
Run Code Online (Sandbox Code Playgroud)

这将允许它适当地划分工作,而不管 n 和 m 的相对值如何。