我在python中使用多处理程序包。 如您所见,我分别执行了两个不同的代码片段。第一个使用Pool.map的代码比第二个连续执行的代码要花费更多的时间。 谁能向我解释为什么? 我认为p.map()会更快。 不并行执行吗? ...
提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供 中文繁体 英文版本 中英对照 版本,有任何建议请联系yoyou2525@163.com。
我尝试利用python的池多处理功能。
独立于我如何设置块大小(在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)
无论我使用chunksize = int(len(myList) / processes)
, chunksize = processes
还是1
(如上例所示),行为都是一样的。
是否可以将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不影响使用的核心数量,这由Pool
的processes
参数设置。 Chunksize设置传递给Pool.map
的可迭代项的Pool.map
,在Pool
调用“任务”时,每个工作进程一次分配(下图显示了Python 3.7.1)。
如果您设置chunksize=1
,则只有在完成之前收到的工作后,才能在新任务中为工作进程提供新项目。 对于chunksize > 1
一个工作人员在一个任务中一次获得一整批项目,当它完成时,如果有任何剩余,它将获得下一批。
使用chunksize=1
逐个分发项目会增加调度的灵活性,同时降低整体吞吐量,因为滴灌需要更多的进程间通信(IPC)。
在我的游泳池的CHUNKSIZE算法的深入分析在这里 ,我定义工作单元,用于处理迭代为taskel的一个项目,以避免命名冲突字的“任务”的游泳池的使用。 任务(作为工作单元)由chunksize
taskel组成。
如果无法预测taskel需要完成多长时间,则可以设置chunksize=1
,例如优化问题,其中处理时间在任务栏之间变化很大。 在这里滴水可防止工人进程坐在一堆未触动的物品上,同时在一个重型任务上运行,防止他的任务中的其他物品被分配到空转的工人过程。
否则,如果所有任务都需要相同的时间来完成,则可以设置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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.