python 多处理:没有递减 returns?

python multiprocessing: no diminishing returns?

假设我想并行化一些密集计算(不受 I/O 约束)。

当然,我不想 运行 比可用处理器更多的进程,否则我会开始为上下文切换(和缓存未命中)付费。

在心理上,我希望随着我在 multiprocessing.Pool(n) 中增加 n,总时间会像这样:

  1. 负斜率,因为任务利用了并行化
  2. 正斜率,因为上下文切换开始让我付出代价
  3. 高原

但实际上,我得到的是:

#!/usr/bin/env python

from math import factorial


def pi(n):
    t = 0
    pi = 0
    deno = 0
    k = 0
    for k in range(n):
        t = ((-1)**k)*(factorial(6*k))*(13591409+545140134*k)
        deno = factorial(3*k)*(factorial(k)**3)*(640320**(3*k))
        pi += t/deno
    pi = pi * 12/(640320**(1.5))
    pi = 1/pi
    return pi

import multiprocessing
import time
maxx = 20
tasks = 60
task_complexity = 500
x = range(1, maxx+1)
y = [0]*maxx

for i in x:
    p = multiprocessing.Pool(i)
    tic = time.time()
    p.map(pi, [task_complexity]*tasks)
    toc = time.time()
    y[i-1] = toc-tic
    print '%2d %ds' % (i, y[i-1])

import matplotlib.pyplot as plot
plot.plot(x, y)
plot.xlabel('Number of threads')
plot.xlim(1, maxx)
plot.xticks(x)
plot.ylabel('Time in seconds')
plot.show()

我的机器:i3-3217U CPU @ 1.80GHz × 4

操作系统:Ubuntu14.04

在 n>4 之后,我看到任务管理器在各个进程之间轮换,正如预期的那样,因为进程比处理器多。然而,相对于 n=4(我的处理器数量)没有惩罚。

事实上,即使当 n<4 时,我也看到调度程序在我的处理器中疯狂地轮换进程,而不是将每个进程分配给它自己的处理器并避免上下文切换。

我在使用 gnome-system-monitor 时看到了这种行为:(如果有人有不同的经历,请告诉我。)

任何解释为什么我启动多少个进程似乎无关紧要?还是我的代码有问题?

我的猜测:似乎进程不受处理器限制(即使只有两个进程处于活动状态,它们也会不断切换 CPU),所以我无论如何都要为上下文切换付费。

参考文献:

编辑:更新了具有更高常量的图形和代码。

In fact, even when n<4, I see the scheduler frenetically rotating the processes through my processors, instead of assigning each process to its own processor and avoid context switching.

默认情况下,进程不是 processor-bounded,主要原因之一是避免处理器受热不均匀,这会导致机械应力并缩短其使用寿命。

有一些方法可以在单核上强制执行 运行 进程(参见 psutil 模块),这具有更好地使用高速缓存和避免上下文切换等优点,但在大多数情况下情况下(如果不是全部的话),你在性能方面不会有太大的不同。

所以现在如果生成的进程多于您的核心数量,它们将仅充当线程并在它们之间切换以优化执行。处理器性能只会(非常)轻微降低,因为您已经用少于 4 个进程切换上下文。

回答我自己的问题:

首先,我的post似乎有误。正在使用的 CPU 被疯狂地改变似乎不是真的。如果我启动两个 CPU 密集型进程,它们会不断更换核心,但仅限于两个核心之间。我的计算机有 4 个内核,每个内核有 2 "soft" 个内核(用于超线程)。我想发生的事情是它在这 2 "soft" 个核心之间发生变化。不是 Linux 这样做,而是 CPU-板。

话虽这么说,但我仍然很惊讶上下文切换并没有比现在更痛苦。

编辑: this blog.

有一个很好的讨论,经验工作比我好