OpenMP 和不平衡嵌套循环
OpenMP and unbalanced nested loops
我正在尝试使用 OpenMP 编译指示并行化用 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
是类Population
的实例的std::vector
。每个人口更新自己的元素,如下所示:
void Population::update(long long ts) {
for (unsigned int j = 0; j < this->size(); j++) {
if (check(j,ts)) {
doit(ts, j);
}
}
}
由于每个种群的大小不同,Population::update()
中的循环需要不同的时间,从而导致次优加速。通过在run()
方法中添加#pragma omp parallel for schedule(static)
。我在 2 个线程下获得了 4 倍的加速,但是它下降了 8 个线程。
我知道schedule(dynamic)
子句,允许平衡线程之间的计算。但是,当我尝试动态调度线程时,我没有观察到任何改进。
我走对了方向吗?你认为玩禅盘尺寸会有所帮助吗?任何建议不胜感激!
所以有两件事需要区分: 线程数和调度策略的影响。
对于线程数,线程数多于内核数通常会降低性能,因为上下文切换。所以这取决于您计算机上的内核数量
为静态和动态生成的代码(至少据我所知)之间的区别在于,使用静态调度时,循环迭代平均除以线程数,而使用动态调度时,分布是在运行时计算的(每次迭代结束后,使用 __builtin_GOMP_loop_dynamic_next 查询 omp 运行时)。 切换到动态时观察到的减速的原因可能是循环不包含足够的迭代/计算,因此动态计算迭代分布的开销无法被性能增益所覆盖。
(我假设每个人口实例不与其他实例共享数据)
只是抛出想法,希望这有帮助=)
相关文章:
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 了解嵌套循环打印星号图案
- 无法掌握嵌套循环的写作技巧
- 在 c++ 中实现嵌套循环的更短方法吗?
- 从嵌套循环中的 std::list 中删除将返回访问冲突
- C++从外部类继承的嵌套类;不允许使用不完整的类型
- 毕达哥拉斯三重嵌套循环误解
- T(n) 表示嵌套循环
- 2 个嵌套循环的时间复杂度
- 嵌套循环背后的逻辑
- 使用 %s C++嵌套循环
- 嵌套循环和重复迭代器
- 如何在 c++ 下使用嵌套循环和正则表达式降低时间复杂度?
- OpenMP 和不平衡嵌套循环
- 如何在不将其拆分为两个嵌套循环的情况下打印整个形状?
- C++ 嵌套循环输出不正确
- 在嵌套循环/循环不变量中检查一次
- 嵌套循环语句结果不正确
- 如何为嵌套循环配置openMP以保持内部循环不并行
- c++嵌套循环不给我任何值