Python 多处理 - 从池中动态重新分配作业 - 无需异步?

标签 python synchronization multiprocessing pool

所以我有一批 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/

相关文章:

python - 如何删除字符串中某个字符后的所有内容?

java - 在同步代码段中使用 wait() 而不使用 notification() (java)

python多处理模块,共享多维数组

python - 如何在多个 scrapy 蜘蛛在同一进程中运行时停止 react 堆

python - 如何使用 re.compile 和 re.findall 删除括号内的文本?

python - yt.streams.get_by_resolution() 返回 None 即使流存在

Java 原子变量 native /内部实现

go - 对goroutines中的延迟感到困惑

python - 使用 TCP 同时在两个进程之间进行多处理连接

python - 由于后台 semaphore_tracker 进程导致多处理卡住