Многопроцессорность python: нет уменьшающихся результатов?

Скажем, я хочу парализовать некоторые интенсивные вычисления (не связанные с I/O).

Естественно, я не хочу запускать больше процессов, чем доступные процессоры, или я бы начал платить за переключение контекста (и промахи кэша).

Ментально, я ожидал бы, что при увеличении n в multiprocessing.Pool(n) общее время будет вести себя следующим образом:

mockup

  • отрицательный наклон, поскольку задачи используют преимущества распараллеливания
  • положительный наклон, так как переключение контекста начинает меня стоить
  • плато

Но на самом деле я получаю это:

real

#!/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: (Пожалуйста, дайте мне знать, если у кого-то есть другой опыт.)

gnome-system-monitor

Любое объяснение, почему, похоже, не важно, сколько процессов я запускаю? Или что-то не так с моим кодом?

Мое предположение: похоже, что процессы не связаны с процессором (даже когда активны только два процесса, они продолжают переключать CPU), и поэтому я плачу за переключение контекста.

Литература:

EDIT: обновленная графика и код с более высокими константами.

Ответ 1

Фактически, даже когда n < 4, я вижу, что планировщик frenetically вращает процессов через мои процессоры, вместо того, чтобы присваивать каждому процессу его собственный процессор и избежать переключения контекста.

Процессы по умолчанию не ограничены процессором, одна из основных причин заключается в том, чтобы избежать неодинакового нагрева процессора, что может вызвать механическое напряжение и сократить срок его службы.

Существуют способы принудительного запуска процесса на одном ядре (смотрите модуль psutil), который имеет такие преимущества, как лучшее использование кеш-памяти и исключение переключения контекста, но в большинстве случаев (если не все) вы не имеют большого значения с точки зрения выступлений.

Итак, если вы создаете больше процессов, чем количество ядер, они будут действовать как потоки и переключаться между ними для оптимизации выполнения. Производительность процессора будет немного (очень) немного понижена, так как вы уже переключали контекст с менее чем 4 процессами.

Ответ 2

Отвечая на мой собственный вопрос:

Во-первых, я, кажется, допустил ошибку в своем сообщении. Не похоже, чтобы используемый CPU менялся отчаянно. Если я запускаю два процессора с интенсивным процессом, они меняют ядра, но только между двумя ядрами. Мой компьютер имеет 4 ядра, каждый из которых имеет 2 "мягких" ядра (для гиперпотока). Я предполагаю, что происходит, что он меняется между этими двумя "мягкими" ядрами. Это не Linux, это процессорная плата.

Это, как говорится, я все еще удивляюсь, что переключение контекста не больнее, чем оно есть.

РЕДАКТИРОВАТЬ: Хорошая дискуссия с лучшей эмпирической работой, чем я, над этот блог. p >