为什么multiprocessing.Pool不能线性地提高计算速度?

时间:2019-12-02 12:27:56

标签: python python-multiprocessing

我试图更好地理解Python中的并行编程,并且无法理解为什么进程数量的增加并不能减少程序线性执行的时间

例如使用4个进程的程序需要10.8秒才能完成,而使用8个进程的7.280761957168579秒则需要预期的5.4-6秒。我了解启动一个过程大约需要0.1秒,但是这个数字仍然没有加起来,它应该最多8个过程最多6.5秒,而不是 7.280761957168579 ...

有人可以解释一下,为什么时间减少不是线性的?

我的简单程序:

def sum_square_with_mp(numbers):

    start_time = time.time()
    p = Pool(8)
    result = p.map(sum_square, numbers)
    p.close()
    p.join()
    end_time = time.time() - start_time

    print(f"Processing {len(numbers)} numbers took {end_time} time using multiprocessing.")

def sum_square(number):
    s = 0
    for i in range(number):
        s += i * i
    return s

if __name__ == '__main__':
    numbers = range(20000)
    sum_square_with_mp(numbers)

2 个答案:

答案 0 :(得分:2)

首先,比启动子流程要多得多的开销,即创建池,映射函数调用,序列化参数,监视执行,检索和反序列化结果等。

然后,您最多可以在一个给定的时间让一个给定的内核执行一个进程-因此,如果您有4个内核,那么最多4个进程实际上是在同时执行。

最后,进程执行由操作系统处理,操作系统将根据一些相当复杂的规则和启发式方法决定哪个进程当前在哪个内核上处于活动状态。在大多数情况下,流程执行将被中断并恢复几次(最终)才能完成(最终),因此“实际”执行时间(流程启动与完成之间的时间)实际上并不相同作为有效执行此过程所花费的时间。哦,是的,此上下文切换也确实有一些开销...

请注意,这与Python无关,实际上只是普通的OS process scheduling-CS101。

答案 1 :(得分:0)

父/驱动程序需要先将范围中的值序列化,然后再将其发送给子/工作进程。这需要一些时间,反序列化返回的结果也需要一些时间。这增加了代码的“不可并行化”部分。有关更多信息,请参见Amdahl's law

您还没有说系统有多少个CPU /内核,也没有说明它们如何被占用,这也会对此产生影响