我刚刚研究过该文档部分enter link description here
据我了解此功能
import multiprocessing
pool = multiprocessing.Pool()
print pool.map(f, range(10))
将创建一个任务块,其数量等于核心数量。结果将与从序列中获得输入的顺序相同。
文档也说
--- will block till complete:
让我们想象上面的f是一个复杂的函数。我们有4个CPU,因此块大小为4,它会阻塞直到所有4个块都完成后才得到下一个块吗?
因此,在更坏的情况下,3个空闲内核会空闲很长时间,直到最后一个空闲内核完成?
最佳答案
您似乎给人的印象是chunksize
将与内核数匹配。这是不正确的。如果未指定,chunksize
具有实现定义的值,并且至少在CPython(参考解释器)上,它不等于内核数。在撰写本文时,在Python 2.7和3.7上,使用的计算为:
if chunksize is None:
chunksize, extra = divmod(len(iterable), len(self._pool) * 4)
if extra:
chunksize += 1
len(self._pool)
是工作进程数,len(iterable)
是可迭代输入中的项目数(如果没有定义的长度,则将其list
修改)。因此,对于您的情况,计算公式为:
chunksize, extra = divmod(10, numcores * 4)
if extra:
chunksize += 1
例如,对于四核计算机,将计算
chunksize, extra = 0, 10
,然后if
检查会将chunksize
更改为1
。因此,每个工作人员将采用一个输入值(几乎立即会抓取0、1、2和3),然后在每个工作人员完成操作后,还将再抓取一个项目。假设所有项目花费大致相同的时间,您将进行两轮全占用(使用4/4核),然后进行一轮半占用(使用2/4核)。最坏的情况是最后一个任务开始花费的时间最长。如果这是提前知道的,则应尝试组织输入以防止发生这种情况(首先放置最昂贵的物品,因此在不完全占用的情况下运行的最终任务很短而且很快完成,从而最大程度地提高了并行度);否则,这是不可避免的。对于大量任务,是的,默认
chunksize
将增加,例如对于四个核上的100个输入,您将具有chunksize
的7
,产生15个块,最后一个块的大小不足。因此,是的,对于运行时间千差万别的任务,您将冒尾巴长而占用率低的风险。如果存在风险,请将您的chunksize
显式设置为1
;它降低了整体性能(使其更接近imap
的性能),但是它消除了一个工人在一个块中处理7的第1项而其他所有内核都处于空闲状态的可能性。