apr*_*ero 6 python multiprocessing
我试图用 Python 中的多处理来加速一些代码,但我无法理解一点。假设我有以下愚蠢的功能:
import time
from multiprocessing.pool import Pool
def foo(_):
for _ in range(100000000):
a = 3
Run Code Online (Sandbox Code Playgroud)
当我在笔记本电脑(英特尔 - 8 核 cpu)上运行此代码而不使用多处理(请参阅下面的代码)时,所用时间约为 2.31 秒。
t1 = time.time()
foo(1)
print(f"Without multiprocessing {time.time() - t1}")
Run Code Online (Sandbox Code Playgroud)
相反,当我使用 Python 多处理库(请参阅下面的代码)运行此代码时,所用时间约为 6.0 秒。
pool = Pool(8)
t1 = time.time()
pool.map(foo, range(8))
print(f"Sample multiprocessing {time.time() - t1}")
Run Code Online (Sandbox Code Playgroud)
据我所知,我知道在使用多处理时有一些时间开销,主要是由于需要产生新进程和复制内存状态。然而,这个操作应该只在处理最初产生时执行一次,并且不应该那么大。
那么我在这里缺少什么?我的推理有问题吗?
编辑:我认为最好更明确地说明我的问题。我在这里期望的是多处理代码比顺序代码稍慢。确实,我没有将整个工作拆分到 8 个内核,但我并行使用 8 个内核来完成相同的工作(因此在理想的世界中,处理时间应该或多或少保持不变)。考虑到产生新进程的开销,我预计时间会增加一些(不是太大)百分比,但不会增加约 2.60 倍。
好吧,多处理不可能使这更快:您不是将工作划分为 8 个进程,而是要求 8 个进程中的每一个都完成整个事情。每个进程将花费至少与您的代码在不使用多处理的情况下只执行一次一样长的时间。
因此,如果多处理根本没有帮助,您会期望它花费大约 8 倍的时间(它的工作量是单处理器运行的 8 倍!)。但是你说它不需要 2.31 * 8 ~= 18.5 秒,而是“仅”大约 6 秒。所以你的速度比 3 倍要好。
为什么不多呢?从这里猜不出来。这将取决于您的机器有多少物理内核,以及您同时运行多少其他东西。对于此特定功能,每个进程都将 100% 受 CPU 限制,因此“逻辑”内核的数量几乎无关紧要 - 处理器超线程几乎没有机会提供帮助。所以我猜你有 4 个物理内核。
我的盒子上的示例计时,它有 8 个逻辑核心,但只有 4 个物理核心,否则让盒子非常安静:
Without multiprocessing 2.468580484390259
Sample multiprocessing 4.78624415397644
Run Code Online (Sandbox Code Playgroud)
如上所述,这些都不让我感到惊讶。事实上,我很惊讶(但愉快)的程序如何有效地利用了机器的真容了一点。