地图上的Python多处理

地图上的Python多处理,python,python-3.x,Python,Python 3.x,我刚刚学习了这个文档部分 据我所知,这个函数 import multiprocessing pool = multiprocessing.Pool() print pool.map(f, range(10)) 将创建一个任务块,其数量等于核心数量。结果的顺序将与它从sequenze获取输入的顺序相同 docu还说,---将阻止,直到完成: 让我们想象上面的f是一个复杂的函数。我们有4个CPU和一个块大小为4的块,它是否阻塞直到所有4将完成,然后才获得下一个块 所以,在更糟糕的情况下,3个空闲内

我刚刚学习了这个文档部分

据我所知,这个函数

import multiprocessing
pool = multiprocessing.Pool()
print pool.map(f, range(10))
将创建一个任务块,其数量等于核心数量。结果的顺序将与它从sequenze获取输入的顺序相同

docu还说,
---将阻止,直到完成:

让我们想象上面的f是一个复杂的函数。我们有4个CPU和一个块大小为4的块,它是否阻塞直到所有4将完成,然后才获得下一个块


所以,在更糟糕的情况下,3个空闲内核会闲置很长时间,直到最后一个内核完成为止?

你说得有一部分是对的


您还可以阅读
map
接受
chunksize
参数,该参数可用于调整提交给池进程的任务块的大小。如果数据块足够小,每个进程的数据量应该相当相等,所有的内核大部分时间都在工作。

您似乎觉得
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.\u pool)
是工作进程的数量,
len(iterable)
是输入iterable中的项目数量(如果没有定义长度,则为
列表
ified)

因此,对于您的情况,计算如下:

        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的性能),但消除了一个工人在一个块中处理第1项(共7项),而所有其他内核处于空闲状态的可能性。

块大小越小,工作人员之间的任务间隔越均匀,一个工作人员处理最后一批任务,而其他人什么也不做的情况就越不可能结束,但工作人员需要暂停工作以返回池中获取更多任务的频率越高,这会增加开销。