CHUNKSIZE无关的多处理在Python / pool.map?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CHUNKSIZE无关的多处理在Python / pool.map?相关的知识,希望对你有一定的参考价值。

我试图利用蟒蛇池多重功能。

独立如何我设置的块大小(Windows 7和Ubuntu的下 - 后者见下面有4个内核),并行线程的数量似乎保持不变。

from multiprocessing import Pool
from multiprocessing import cpu_count
import multiprocessing
import time


def f(x):
    print("ready to sleep", x, multiprocessing.current_process())
    time.sleep(20)
    print("slept with:", x, multiprocessing.current_process())


if __name__ == '__main__':
    processes = cpu_count()
    print('-' * 20)
    print('Utilizing %d cores' % processes)
    print('-' * 20)
    pool = Pool(processes)
    myList = []
    runner = 0
    while runner < 40:
        myList.append(runner)
        runner += 1
    print("len(myList):", len(myList))

    # chunksize = int(len(myList) / processes)
    # chunksize = processes
    chunksize = 1
    print("chunksize:", chunksize)
    pool.map(f, myList, 1)

该行为是相同的I是否使用chunksize = int(len(myList) / processes)chunksize = processes1(如在上面的例子)。

难道说的CHUNKSIZE自动设置为内核的数量?

例如用于chunksize = 1

--------------------
Utilizing 4 cores
--------------------
len(myList): 40
chunksize: 10
ready to sleep 0 <ForkProcess(ForkPoolWorker-1, started daemon)>
ready to sleep 1 <ForkProcess(ForkPoolWorker-2, started daemon)>
ready to sleep 2 <ForkProcess(ForkPoolWorker-3, started daemon)>
ready to sleep 3 <ForkProcess(ForkPoolWorker-4, started daemon)>
slept with: 0 <ForkProcess(ForkPoolWorker-1, started daemon)>
ready to sleep 4 <ForkProcess(ForkPoolWorker-1, started daemon)>
slept with: 1 <ForkProcess(ForkPoolWorker-2, started daemon)>
ready to sleep 5 <ForkProcess(ForkPoolWorker-2, started daemon)>
slept with: 2 <ForkProcess(ForkPoolWorker-3, started daemon)>
ready to sleep 6 <ForkProcess(ForkPoolWorker-3, started daemon)>
slept with: 3 <ForkProcess(ForkPoolWorker-4, started daemon)>
ready to sleep 7 <ForkProcess(ForkPoolWorker-4, started daemon)>
slept with: 4 <ForkProcess(ForkPoolWorker-1, started daemon)>
ready to sleep 8 <ForkProcess(ForkPoolWorker-1, started daemon)>
slept with: 5 <ForkProcess(ForkPoolWorker-2, started daemon)>
ready to sleep 9 <ForkProcess(ForkPoolWorker-2, started daemon)>
slept with: 6 <ForkProcess(ForkPoolWorker-3, started daemon)>
ready to sleep 10 <ForkProcess(ForkPoolWorker-3, started daemon)>
slept with: 7 <ForkProcess(ForkPoolWorker-4, started daemon)>
ready to sleep 11 <ForkProcess(ForkPoolWorker-4, started daemon)>
slept with: 8 <ForkProcess(ForkPoolWorker-1, started daemon)>
答案

CHUNKSIZE不会影响多少个核心的习惯,这是由processesPool参数设置。 CHUNKSIZE将如何传递给Pool.map可迭代的许多项目,都按单个工作进程一次在什么Pool所谓的“任务”分布(下图显示的Python 3.7.1)。

task_python_3.7.1

如果你设置chunksize=1,一名工人进程被一个新的项目反馈,在一个新的任务,只有完成前收到一前一后。对于chunksize > 1工人得到一整批的项目,在一次任务中,当它完成,它如果有任何左侧获得下一批。

分配项一个接一个与chunksize=1增加调度的灵活性,同时降低了它的总体吞吐量,因为滴供给需要更多的进程间通信(IPC)。

在我的游泳池的CHUNKSIZE算法here的深入分析,我定义工作单元,用于处理迭代为taskel的一个项目,以避免命名冲突字的“任务”的游泳池的使用。任务(如工作单位)由chunksize taskels的。

你会设置chunksize=1如果你不能预测taskel将需要多长时间才能完成,例如优化问题,在处理时间跨越taskels良莠不齐。滴灌喂养这里阻止了工人进程坐在一堆不变的项目,而在一个重taskel chrunching,防止他的任务的其他物品分发到怠速工流程。

否则,如果所有的taskels将需要同样的时间来完成,你可以设置chunksize=len(iterable) // processes,让任务只在所有工作人员分发一次。请注意,这将产生一个任务以外还有情况下len(iterable) / processes过程(流程+ 1)有一个余数。这有可能会严重影响你的整体计算时间的潜力。了解更多关于这在以前链接的答案。


仅供参考,这就是Pool内部计算CHUNKSIZE如果没有设置源代码的一部分:

    # Python 3.6, line 378 in `multiprocessing.pool.py`
    if chunksize is None:
        chunksize, extra = divmod(len(iterable), len(self._pool) * 4)
        if extra:
            chunksize += 1
    if len(iterable) == 0:
        chunksize = 0

以上是关于CHUNKSIZE无关的多处理在Python / pool.map?的主要内容,如果未能解决你的问题,请参考以下文章

使用pandas的Python多处理并非所有进程都一次运行

multiprocessing:maxtasksperchild和chunksize冲突?

如何在不连接的情况下读取 Python 数据框中的数据?

Python 中的多线程还是串行处理?

Python中的多处理与线程

Docker内的多处理python程序