我正在尝试以下代码:
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?和multiprocessing.Pool() slower than just using ordinary functions
他们似乎把它归结为IPC开销或磁盘饱和度,但我觉得在我的例子中,这些问题显然不是问题;我没有在磁盘上写入/读取任何内容,并且计算时间足够长,以至于与多处理所节省的总时间相比,IPC开销似乎应该很小(我估计,因为我和#39;我在4个核心而不是1个核心上工作,我应该将计算时间从14秒减少到大约3.5秒。我不会让我的cpu饱和,我不会想到;检查cat /proc/cpuinfo
表明我有4个核心,但即使我只处理2个进程,它仍然比正常的映射函数慢(甚至比4个进程慢)。还有什么可能会减慢多处理版本的速度?我误解了IPC开销如何扩展?
如果相关,则此代码用Python 2.7编写,我的操作系统是Linux Mint 17.2
答案 0 :(得分:2)
pool.map
将列表拆分为N个作业(其中N是列表的大小)并将其分配给流程。
单个流程正在进行的工作显示在您的代码中:
def square(x):
return x**2
此操作在现代CPU上花费的时间非常短,无论数量有多大。
在您的示例中,您创建了一个庞大的列表,并对每个元素执行不相关的操作。当然,与针对快速循环优化的常规map
函数相比,IPC开销会更大。
为了让您的示例按预期工作,只需向square函数添加time.sleep(0.1)
调用即可。这模拟了一个长期运行的任务。当然,您可能希望减小列表的大小,或者需要永远完成。