2016-01-23 2 views
10

Предположим, я хочу парализовать некоторые интенсивные вычисления (не связанные с I/O).python многопроцессорность: нет уменьшающейся отдачи?

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

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

mockup

  1. отрицательный наклон как задача воспользоваться распараллеливаниями
  2. положительного наклона, как контекст переключение начинается с меня
  3. Плато

Но в действительности, я получаю это:

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

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

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

Ссылки:

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

+0

Из интереса: сколько процессорных потоков у вас есть? – poke

+0

@poke, я забыл упомянуть. :) Я добавил эту и другую информацию тем временем. –

+0

Просто для ясности: [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

ответ

0

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

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

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

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

+0

Мне нравится ваше объяснение по нагреву, и я думаю, что это часть истории, но я не совсем ее покупаю. Они могут избегать нагрева, меняя сердечники каждые 30 минут или около того, не каждую секунду или меньше. И мне говорят, что в Windows этого постоянного переключения процессора не происходит. Во всяком случае, я буду отмечать как правильные, если у кого-то нет других объяснений. ps: Я добавил скриншот инструмента, который я использую, чтобы увидеть это поведение, в случае, если кто-то может его подтвердить ... –

+0

Спасибо, что упомянул 'psutil'; когда я нахожу некоторое время, я изменю код, чтобы узнать, могу ли я повысить производительность. Для справок в будущем команда 'taskset (1)' также выглядит интересной. –

+1

существует несколько алгоритмов (зависит от ОС) для планирования задач на процессоре. Я ищу лучший ответ, чем проблема с нагревом, но я не нахожу многого, потому что есть потребность в переключении процессов для программ с одним потоком. Я нашел статью, описывающую возможное улучшение производительности с использованием алгоритма контекстной коммутации, но я понятия не имею, используется ли это или только материал для исследования. – CoMartel

1

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

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

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

EDIT: Существует хорошая дискуссия с лучшей эмпирической работой, чем я, над this blog.

Смежные вопросы