Предположим, я хочу парализовать некоторые интенсивные вычисления (не связанные с I/O).python многопроцессорность: нет уменьшающейся отдачи?
Естественно, я не хочу запускать больше процессов, чем доступные процессоры, или я начну платить за переключение контекста (и пропуски кэша).
Мысленно, я бы ожидать, что, как я увеличил 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, я вижу, что планировщик безумно поворачивает процессы через мои процессоры, вместо того, чтобы назначать каждый процесс его собственному процессору и избегать переключения контекста.
Я вижу это поведение с помощью гнома-системы-монитор: (Пожалуйста, дайте мне знать, если кто-то другой опыт.)
Любое объяснение, почему это, кажется, не имеет значения, как много процессов Я стреляю? Или что-то не так с моим кодом?
Мое предположение: кажется, что процессы не связаны с процессором (даже если активны только два процесса, они продолжают переключать процессор), и поэтому я плачу за переключение контекста.
Ссылки:
EDIT: обновленный графический и код с более высокими константами.
Из интереса: сколько процессорных потоков у вас есть? – poke
@poke, я забыл упомянуть. :) Я добавил эту и другую информацию тем временем. –
Просто для ясности: [i3-3217U] (http://ark.intel.com/products/65697/Intel-Core-i3-3217U-Processor-3M-Cache-1_80-GHz) имеет 2 ядра с 2 ядрами нитей. Вероятно, вы также должны измерить суммарное время вычисления, чтобы лучше видеть, как переключатели контекста влияют на ваш расчет, [здесь] (http://pastebin.com/bdc3snWB). Я опубликовал модифицированную версию вашего скрипта (без материала для печати, как я теперь у меня нет matplotlib). – mata