ProcessPoolExecutor увеличивает производительность не интуитивно понятным способом - PullRequest
0 голосов

У меня есть приложение, которое в основном многопоточное: поток 1 - это вычисление, а поток 2 - это GUI (Tkinter). Одна из частей вычисления включает функцию с l oop. Поэтому я решил использовать здесь многопроцессорность таким образом:

def mpw1(idw_tree, mapsdata, inlines, xlines, x, y, dfattrs, calcplan, attrsdim, mdim):

    n_cores = os.cpu_count()
    flatcubec2 = np.zeros((attrsdim,mdim))

    with ProcessPoolExecutor(n_cores) as ex:
            args = ((i, calcplan, idw_tree, mapsdata, dfattrs, flatcubec2, inlines, xlines, n_cores) for i in range(n_cores))
            flatcubec2 = ex.map(circle, args)

    return flatcubec2

где circle - это просто вычислительная функция (скажем, она что-то считает).

Но что странно, так это что установка n_cores в максимально возможной степени не позволяет мне добиться максимальной производительности. Вот некоторая информация:

8 ядер (макс.) - 17 se c
6 ядер - 14 se c
4 ядра - 12 se c
3 ядра - 14 se c
2 ядра - 17 se c

Что на самом деле происходит? Почему использование максимального количества оборудования не позволяет добиться максимальной производительности? Проблема в моем способе использования многопоточности ?

Ответы [ 2 ]

0 голосов

Такое поведение объясняется тем, что я использовал неправильную команду (multiprocessing.cpu_count ()) для задания количества используемых процессов, эта команда вернула мне вдвое больше, чем должно быть, в mp необходимо использовать только физический cpu, без логического Итак, такое поведение, когда после 4-го «рабочего» (максимум физических процессоров в моем случае) производительность начинает снижаться, можно объяснить тем фактом, что многопроцессорность работает явным образом и предсказуемо только с физическими процессорами. Чтобы получить количество физических процессоров, я использовал:

psutil.cpu_count(logical = False)
0 голосов
/ 10 июля 2020

Прежде всего, поскольку вы используете ProcessPoolExecutor, это многопроцессорность , а не многопоточность . Многопоточность практически не дает прироста производительности в Python из-за глобальной блокировки интерпретатора.

Во-вторых, трудно объяснить производительность вашего приложения, не видя фактического кода. Многопроцессорность связана с некоторыми накладными расходами, поэтому она полезна только в том случае, если вам нужно выполнить некоторую обработку (и, конечно, достаточно доступных ядер для выполнения процессов).

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

...