OpenMP和不平衡的嵌套循环

时间:2017-08-29 14:57:47

标签: c++ parallel-processing openmp

我尝试使用OpenMP pragma并行化用C ++编写的模拟器。 我对它有基本的了解,但没有经验。

下面的代码显示了并行化的主要方法:

void run(long long end) {
  while (now + dt <= end) {
    now += dt;
    for (unsigned int i=0; i < populations.size(); i++) {
      populations[i]->update(now);
    }
  }
}

其中populations是类std::vector的{​​{1}}个实例。每个人口更新自己的元素如下:

Population

作为每个不同大小的人口,void Population::update(long long ts) { for (unsigned int j = 0; j < this->size(); j++) { if (check(j,ts)) { doit(ts, j); } } } 中的循环需要不同的时间,导致次优的加速。在Population::update()方法中添加#pragma omp parallel for schedule(static)。我获得了4个线程的2倍加速,但它下降了8个线程。

我知道run()子句,允许平衡线程之间的计算。但是,当我尝试动态调度线程时,我没有观察到任何改进。

我是朝着正确的方向前进的吗?你认为玩chunck大小会有帮助吗?任何建议表示赞赏!

1 个答案:

答案 0 :(得分:0)

因此有两件事需要区分: 线程数和调度策略的影响。

对于线程数,线程数多于核心数通常会因为上下文切换而降低性能。因此,这取决于您计算机上的核心数量

静态和动态生成的代码(至少就我记忆所预测的)之间的区别在于,使用静态调度,循环迭代除以线程数并且与动态调度一起,分布计算在运行时(在每次迭代结束后,使用__builtin_GOMP_loop_dynamic_next查询omp运行时)。 切换到动态时观察到的减速的原因可能是循环不包含足够的迭代/计算,因此动态计算迭代分布的开销不会被性能增益所覆盖。

(我假设每个人口实例都不与他人共享数据)

只是抛出想法,希望这个帮助=)