所以我有一批 1000 个任务,我使用 parmap/python 多处理模块将其分配给 8 个核心(双 Xeon 机器 16 个物理核心)。目前,它使用同步运行。
问题是,通常其中一个核心远远落后于其他核心,并且在所有其他核心完成其工作后仍然有多个作业/任务需要完成。这可能与核心速度(较旧的计算机)有关,但更可能是由于某些任务比其他任务更困难 - 因此,执行稍微困难的工作的 1 个核心会变得滞后......
我在这里有点困惑 - 但这是异步并行化的作用吗?我之前尝试过使用它,但由于此步骤是一个非常大的处理步骤的一部分 - 目前尚不清楚如何创建屏障来强制程序等待所有异步进程完成。
任何类似问题/答案的建议/链接都值得赞赏。
[编辑]澄清一下,这些进程可以独立运行,它们都将数据保存到磁盘并且不共享变量。
最佳答案
此处为 parmap 作者
默认情况下,在多处理和 parmap 中,任务都分为 block ,并将 block 发送到每个多处理进程(请参阅 multiprocessing documentation )。其背后的原因是,在许多情况下,将任务单独发送到进程会带来大量的计算开销。如果一次以 block 的形式发送多个任务,则开销会减少。
每个 block 上的任务数量由多处理中的 chunksize
控制(以及 parmap 中的 pm_chunksize
)。默认情况下,chunksize
的计算方式为“任务数量”/(4*“池大小”)
,向上舍入(请参阅 multiprocessing source code )。因此,对于您的情况,1000/(4*4) = 62.5 -> 每个 block 63 个任务。
如果像您的情况一样,许多计算量大的任务落入同一个 block 中,则该 block 将需要很长时间才能完成。
解决此问题的一种“廉价且简单”的方法是传递较小的 chunksize
值。请注意,使用极端的 chunksize=1
可能会带来不必要的较大 CPU 开销。
从长远来看,其他答案中建议的适当的排队系统是一个更好的解决方案,但对于一次性问题来说可能有点过分了。
关于Python 多处理 - 从池中动态重新分配作业 - 无需异步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51403964/