如何在不同处理器之间划分负载

时间:2011-04-11 01:04:21

标签: multithreading parallel-processing intel tbb

我在一台机器上运行一些并行代码,每台机器上有4个intel处理器和8个核心。我正在使用TBB。假设一个给定的循环(我并行化)有X次迭代我应该如何选择我的粒度以确保负载是均分的?

2 个答案:

答案 0 :(得分:1)

假设你有N个同样强大的CPU。

如果没有循环携带的依赖项(例如,迭代中没有任何内容,我通过以下迭代使用),那么您可以简单地在CPU 1上运行循环迭代0..X / N,并且迭代(X / N)+1假设每次迭代采用完全相同的时间量,或者至少其平均数量不会发生剧烈变化,则CPU 2等上的(2 * X / N)。

如果 循环携带 依赖关系,如果迭代我依赖于所有先前的迭代,您可能会遇到问题。如果它只依赖于前面的k次迭代,你可以让CPU1做迭代0..X / N,并且CPU2做迭代X / Nk ..(2 * X / N),浪费一些工作但是允许CPU2收集所有处理器都需要等等。

如果迭代花费了大量不同的时间,那么最好设置一个包含迭代的工作清单, 并且让CPU在完成先前的迭代时从工作列表中获取迭代。这样,工作就会随着需求的出现而分开。你必须确保每单位工作的时间比获得工作的工作量大得多,否则你将无法获得平行优势;一种方法是从工作清单中获取一小部分迭代,这样该范围内的总工作量就会大大超过调度开销。

答案 1 :(得分:0)

使用TBB,您无需为parallel_for选择粒度。在大多数情况下,TBB默认情况下会动态地平衡工作。 Ira Baxter的答案正确地描述了如何跨线程池划分工作;但TBB已经有类似的机制为您做到这一点。

补充:在复杂的情况下,手动工作分区肯定会得到更好的结果。虽然在这种情况下可能需要使用TBB任务,因为parallel_for可能无法提供足够的控制;例如,通常无法指定每线程块的确切大小。