Скажем, я хочу парализовать некоторые интенсивные вычисления (не связанные с I/O).
Естественно, я не хочу запускать больше процессов, чем доступные процессоры, или я бы начал платить за переключение контекста (и промахи кэша).
Ментально, я ожидал бы, что при увеличении n
в multiprocessing.Pool(n)
общее время будет вести себя следующим образом:
- отрицательный наклон, поскольку задачи используют преимущества распараллеливания
- положительный наклон, так как переключение контекста начинает меня стоить
- плато
Но на самом деле я получаю это:
#!/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
Операционная система: Ubuntu 14.04
После n > 4 я вижу, что диспетчер задач вращается через различные процессы, как и ожидалось, поскольку процессов больше, чем процессоров. Тем не менее, нет никакого штрафа относительно n = 4 (мое число процессоров).
Фактически, даже когда n < 4, я вижу, что планировщик фанетически поворачивает процессы через мои процессоры, вместо того, чтобы назначать каждый процесс его собственному процессору и избегать переключения контекста.
Я наблюдаю это поведение с помощью gnome-system-monitor: (Пожалуйста, дайте мне знать, если у кого-то есть другой опыт.)
Любое объяснение, почему, похоже, не важно, сколько процессов я запускаю? Или что-то не так с моим кодом?
Мое предположение: похоже, что процессы не связаны с процессором (даже когда активны только два процесса, они продолжают переключать CPU), и поэтому я плачу за переключение контекста.
Литература:
EDIT: обновленная графика и код с более высокими константами.