我刚刚研究过该文档部分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个输入,您将具有chunksize7,产生15个块,最后一个块的大小不足。因此,是的,对于运行时间千差万别的任务,您将冒尾巴长而占用率低的风险。如果存在风险,请将您的chunksize显式设置为1;它降低了整体性能(使其更接近imap的性能),但是它消除了一个工人在一个块中处理7的第1项而其他所有内核都处于空闲状态的可能性。

10-08 18:05