为什么在Pool中使用2个以上的进程后没有影响?

时间:2018-06-07 19:27:25

标签: python multiprocessing

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

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

输出,每行中核心数量和相应的执行时间(以秒为单位)为:

  1. 3147
  2. 1.72
  3. 1896
  4. 1.899
  5. 有谁知道为什么在超过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()
    

1 个答案:

答案 0 :(得分:4)

如果您使用的是相当现代的CPU(例如任何英特尔酷睿处理器),multiprocessing.cpu_count()将不会为您提供机器所具有的物理内核数量,而是超线程数量。简而言之,超线程允许单个物理内核拥有n(最常见的是两个)管道,这会让您的操作系统误以为您拥有的内核数量是{1}}倍。当你正在做一些可能使核心数据匮乏的东西(最值得注意的是由缓存未命中引起的IO或RAM查找)时,这很有用,但是你的工作量纯粹算术,不太可能使你的CPU匮乏,导致超线程几乎没有收获。而且你可能获得的微小收益将被多处理开销所掩盖,这是非常重要的。

P.S。

我通常将此类内容发布为评论,但我已超出评论大小限制。顺便说一句,如果您选择Fibonacci系列只是一个例子,您可能需要考虑更快的算法:Fast Fibonacci computation