为什么 pool.map 比法线贴图慢?

Why is pool.map slower than normal map?

我正在尝试以下代码:

import multiprocessing
import time
import random

def square(x):
    return x**2

pool = multiprocessing.Pool(4)

l = [random.random() for i in xrange(10**8)]

now = time.time()
pool.map(square, l)
print time.time() - now

now = time.time()
map(square, l)
print time.time() - now

并且 pool.map 版本始终比正常 map 版本慢几秒(19 秒对 14 秒)。

我看过问题:Why is multiprocessing.Pool.map slower than builtin map? and multiprocessing.Pool() slower than just using ordinary functions 他们似乎将其归因于 IPC 开销或磁盘饱和,但我觉得在我的示例中这些显然不是问题;我没有 writing/reading 任何 to/from 磁盘,而且计算时间足够长,与多处理节省的总时间相比,IPC 开销似乎应该很小(我估计,因为我'在 4 个内核而不是 1 个内核上工作,我应该将计算时间从 14 秒减少到大约 3.5 秒)。我没有饱和我的 cpu 我不认为;检查 cat /proc/cpuinfo 显示我有 4 个内核,但即使我只处理 2 个进程,它仍然比普通映射函数慢(甚至比 4 个进程慢)。还有什么可能会减慢多处理版本的速度?我是否误解了 IPC 开销的扩展方式?

如果相关的话,这段代码是用Python2.7写的,我的OS是LinuxMint 17.2

pool.map 将列表拆分为 N 个作业(其中 N 是列表的大小)并将它们分派给进程。

单个进程所做的工作显示在您的代码中:

def square(x):
    return x**2

无论数字有多大,此操作在现代 CPU 上只需要很少的时间。

在您的示例中,您正在创建一个巨大的列表并对每个元素执行不相关的操作。当然,与针对快速循环优化的常规 map 函数相比,IPC 开销会更大。

为了让您的示例按预期运行,只需添加对 square 函数的 time.sleep(0.1) 调用。这模拟了一个很长的 运行 任务。当然,您可能希望减小列表的大小,否则将需要很长时间才能完成。