为什么在池中使用超过 2 个进程后没有影响?



通过使用multiprocessing库中的map函数,我认为使用2个以上的进程时执行时间没有差异。我正在使用 4 个内核运行该程序。

实际代码非常简单,可以计算前 4000 个斐波那契数 4 次(= 内核数量(。它在 N 个内核之间平均分配工作(例如,当使用具有 2 个进程的池时,每个进程将计算前 4000 个斐波那契数两次(。整个过程是在 N = 1 的情况下完成的,直到内核数量。

输出(每行中包括内核数量和相应的执行时间(以秒为单位((为:

  1. 3,147
  2. 1,72
  3. 1,896
  4. 1.899

有谁知道为什么超过 2 个内核的执行时间不会减少? 实际代码为:

import multiprocessing
from time import time

def F(_):
for n in range(4 * 10 ** 3):
a, b = 0, 1
for i in range(0, n):
a, b = b, a + b
return

def pool_fib():
n_cores = multiprocessing.cpu_count()
args = list(range(multiprocessing.cpu_count()))
for i in range(1, n_cores + 1):
with multiprocessing.Pool(i) as p:
start = time()
p.map(F, args)
print(i, time() - start)

if __name__ == '__main__':
pool_fib()

如果你使用的是相当现代的CPU,multiprocessing.cpu_count()不会给你机器拥有的物理内核数量,而是给你超线程的数量。简而言之,超线程允许单个物理内核具有n(最常见的是两个(管道,这会欺骗您的操作系统,让您认为您拥有的内核数量是实际拥有的内核数量的n倍。当您正在执行一些可能会使内核缺乏数据的事情(最值得注意的是,由缓存未命中引起的 IO 或 RAM 查找(时,这很有帮助,但您的工作负载纯粹是算术的,不太可能使您的 CPU 匮乏,从而导致超线程几乎没有收益。您可能获得的微小收益将被多处理开销所掩盖,这是非常显着的。

附言

我通常将这类内容作为评论发布,但我已经超出了评论大小限制。顺便说一下,如果你选择斐波那契级数不仅仅是一个例子,你可能想考虑一个更快的算法:快速斐波那契计算

最新更新