我尝试使用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大小会有帮助吗?任何建议表示赞赏!
答案 0 :(得分:0)
因此有两件事需要区分: 线程数和调度策略的影响。
对于线程数,线程数多于核心数通常会因为上下文切换而降低性能。因此,这取决于您计算机上的核心数量
静态和动态生成的代码(至少就我记忆所预测的)之间的区别在于,使用静态调度,循环迭代除以线程数并且与动态调度一起,分布计算在运行时(在每次迭代结束后,使用__builtin_GOMP_loop_dynamic_next查询omp运行时)。 切换到动态时观察到的减速的原因可能是循环不包含足够的迭代/计算,因此动态计算迭代分布的开销不会被性能增益所覆盖。
(我假设每个人口实例都不与他人共享数据)
只是抛出想法,希望这个帮助=)