多处理 - 数量对处理过程的影响

时间:2018-06-19 03:27:18

标签: python multiprocessing

这可能是一个非常愚蠢的问题,但我找不到任何完全回答这个问题的文件。我正在尝试熟悉python上的multiprocessing库尝试使用multiprocessing.Pool进行滑翔伞任务。 我通过以下方式启动池中的进程数: Pool(processes=nmbr_of_processes)。 问题是我不明白这个过程如何减少工作持续时间。我写了一个脚本来评估它。

def test_operation(y):
sum = 0
for x in range(1000):
    sum += y*x


def main():
    time1 = time.time()
    p = mp.Pool(processes=2)
    result = p.map(test_operation, range(100000))
    p.close()
    p.join()

print('Parallel tooks {} seconds'.format(time.time() - time1))

final = list()
time2 = time.time()
for y in range(100000):
    final.append(test_operation(y))
print('Serial tooks {} seconds'.format(time.time() - time2))

问题是,当我使用mp.Pool(processes=2)的2个进程时,通常会得到:

Parallel took 5.162384271621704 seconds
Serial took 9.853888034820557 seconds

如果我使用更多流程,例如p = mp.Pool(processes=4) 我明白了:

Parallel took 6.404058218002319 seconds
Serial took 9.667300701141357 seconds

我正在开发MacMini DualCore i7 3Ghz。我知道我不能将工作持续时间缩短到连续工作所用时间的一半。但我无法理解为什么与使用2个流程的工作相比,添加更多流程会增加工作持续时间。如果有一个最佳数量的进程可以根据cpu启动,它会是什么?

1 个答案:

答案 0 :(得分:3)

这里需要注意的是,这适用于CPU绑定的任务;你的代码在CPU使用率上很重。首先要做的是检查你有多少理论核心:

import multiprocessing as mp
print(mp.cpu_count())

对于像这样的CPU绑定任务,通过创建一个工作人员多于理论核心的池来获得没有任何好处。如果您没有指定Pool的大小,则会默认返回此数字。然而,这忽略了别的东西;您的代码不是您的操作系统必须运行的唯一内容。

如果您启动与理论核心一样多的进程,系统别无选择,只能定期中断您的进程,以便继续运行,因此您可能会受到性能影响。您无法垄断所有核心。这里的一般经验法则是使池大小为cpu_count() - 1,这使得OS可以在其他进程中自由使用。

我很惊讶地发现我发现的其他答案都没有提到这个一般规则;它似乎仅限于注释等。但是,您自己的测试表明它适用于您的情况下的性能,因此确定池大小是一种合理的启发式方法。