gpt4 book ai didi

performance - Python 3 多处理 : optimal chunk size

转载 作者:行者123 更新时间:2023-12-04 10:36:06 31 4
gpt4 key购买 nike

如何找到 multiprocessing.Pool 的最佳块大小实例?

我之前用它创建了一个 n 的生成器数独对象:

processes = multiprocessing.cpu_count()
worker_pool = multiprocessing.Pool(processes)
sudokus = worker_pool.imap_unordered(create_sudoku, range(n), n // processes + 1)

为了测量时间,我使用 time.time()在上面的代码片段之前,然后我按照描述初始化池,然后将生成器转换为列表( list(sudokus) )以触发生成项目(仅用于时间测量,我知道这在最终程序中是无稽之谈),然后我花点时间使用 time.time()再次输出差异。

我观察到 n // processes + 1 的块大小结果约为 0.425 毫秒 每个对象。但我也观察到 CPU 仅在进程的前半部分满载,最后使用率下降到 25%(在具有 2 个内核和超线程的 i3 上)。

如果我使用较小的块大小 int(l // (processes**2) + 1)相反,我得到的时间约为 0.355 毫秒 相反,CPU 负载分布得更好。它只是有一些小到大约的尖峰。 75%,但在下降到 25% 之前,在处理时间的更长时间内保持高位。

是否有更好的公式来计算块大小或其他更好的方法来最有效地使用 CPU?请帮助我提高这个多处理池的效率。

最佳答案

This answer提供了一个高层次的概述。

进入细节,每个 worker 被发送一块 chunksize一次处理任务。每次工作人员完成该块时,它都需要通过某种类型的进程间通信(IPC)请求更多输入,例如 queue.Queue .每个 IPC 请求都需要一个系统调用;由于上下文切换,它花费 anywhere in the range of 1-10 μs ,假设 10 μs。由于共享缓存,上下文切换可能会(在有限程度上)损害所有内核。因此,非常悲观地让我们估计 IPC 请求的最大可能成本为 100 μs。

您希望 IPC 开销无关紧要,假设 <1%。如果我的数字是正确的,您可以通过使块处理时间> 10 毫秒来确保。因此,如果每个任务需要 1 μs 来处理,您需要 chunksize至少 10000 .

不做的主要原因chunksize任意大的是,在执行的最后,其中一个工作人员可能仍在运行,而其他人都已完成——显然不必要地增加了完成时间。我想在大多数情况下 10 毫秒的延迟并不是什么大问题,所以我建议将 10 毫秒块处理时间作为目标似乎是安全的。

另一大原因chunksize可能导致的问题是准备输入可能需要时间,同时浪费 worker 的能力。大概输入准备比处理快(否则它也应该并行化,使用类似 RxPY 的东西)。因此,再次将处理时间设为 ~10 毫秒似乎是安全的(假设您不介意低于 10 毫秒的启动延迟)。

注意:对于现代 Linux 上的非实时进程,上下文切换每大约 1-20 毫秒发生一次。/Windows - 当然,除非进程更早地进行系统调用。所以在没有系统调用的情况下,上下文切换的开销不会超过~1%。您因 IPC 而产生的任何开销都是除此之外的。

关于performance - Python 3 多处理 : optimal chunk size,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34988692/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com