Неожиданная производительность многопроцессорной обработки.Pool () - PullRequest
0 голосов
/ 26 марта 2020

Я считаю, что multiprocessing.Pool () работает не так, как ожидалось, в моем случае ниже. Может ли кто-нибудь объяснить, почему он так себя вел и как улучшить производительность, если это возможно. Ниже приведен упрощенный c код:

import numpy as np
import multiprocessing  
from itertools import repeat

def group_data_by_runID(args):
    data, runID = args
    return data[data[:,0].astype(int)==runID,:]

%%time
DATA = np.array([[0,1],[0,2],[0,3],[0,4],[1,5],[1,6],[1,7],[1,8],[2,9],[2,10],[2,11],[2,12]])
runIDs = [0,1,2]*10000000
pool = multiprocessing.Pool(40)
list(pool.map(group_data_by_runID, zip(repeat(DATA), runIDs)))

. Как видно из приведенного выше кода, я намеревался использовать 40 ядер (56 ядер и более чем достаточно памяти, доступной в этой системе) для запуска код, это заняло 1мин 31с. Тогда я использовал:

list(map(group_data_by_runID, zip(repeat(DATA), runIDs)))

Это заняло 2 минуты 33 с. Так что производительность использования 40 ядер только в два раза ниже, чем в два раза, что для меня очень странно. Я также заметил, что даже у меня 40 ядер, иногда он не запускается в 40 ядрах, как это видно на htop.

Где я ошибся? И как я могу улучшить скорость. Обратите внимание, что фактические данные намного больше.

1 Ответ

0 голосов
/ 01 апреля 2020

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

Использование многопроцессорной обработки может привести к дополнительным расходам, если ваши входные данные велики, потому что эти данные будут скопированы и отправлены по проводам в различные процессы, как описано выше в juanpa. Эти накладные расходы могут быть очень значительными. Тем не менее, мы все еще можем получить огромный выигрыш в производительности, разбивая входные данные на маленькие порции и позволяя каждому процессу обрабатывать каждый порцию.

Другой сценарий, в котором можно добиться значительного прироста производительности, - это отсутствие входных данных. Например, чтение данных из десятков или сотен файлов.

Несмотря на то, что многопроцессорность может повысить скорость, большая часть энергии все равно будет расходоваться на сам алгоритм, который может фундаментально определять эффективность кода.

...