Производительность многопроцессорной обработки Python улучшается только с квадратным корнем из числа используемых ядер - PullRequest
0 голосов
/ 07 мая 2018

Я пытаюсь реализовать многопроцессорность в Python (Windows Server 2012) и испытываю трудности с достижением ожидаемого уровня повышения производительности.В частности, для набора задач, которые почти полностью независимы, я бы ожидал линейного улучшения с дополнительными ядрами .


Я понимаю, что - особенно в Windows - тамЭто накладные расходы, связанные с открытием новых процессов [1] , а также то, что многие причуды базового кода могут помешать чистой тенденции.Но в теории тенденция в конечном итоге должна быть близкой к линейной для полностью распараллеленной задачи [2] ;или, возможно, материально-техническое обеспечение, если я имел дело с частично последовательным заданиемпочти идеальное отношение квадратный корень до N_cores=36 (количество физических ядер на моем сервере) до ожидаемого снижения производительности, когда я получаю дополнительные логические ядра.


Здесь - график результатов моего теста производительности: enter image description here
(" Нормализованная производительность " равна [ время работы с 1 ядро ​​процессора ] , деленное на [ время работы с N ядра процессора ] ).

Нормально ли это резкое уменьшение отдачи при многопроцессорной обработке? Или я что-то упустил в своей реализации?


import numpy as np
from multiprocessing import Pool, cpu_count, Manager
import math as m
from functools import partial
from time import time

def check_prime(num):

    #Assert positive integer value
    if num!=m.floor(num) or num<1:
        print("Input must be a positive integer")
        return None

    #Check divisibility for all possible factors
    prime = True
    for i in range(2,num):
        if num%i==0: prime=False
    return prime

def cp_worker(num, L):
    prime = check_prime(num)
    L.append((num, prime))


def mp_primes(omag, mp=cpu_count()):
    with Manager() as manager:
        np.random.seed(0)
        numlist = np.random.randint(10**omag, 10**(omag+1), 100)

        L = manager.list()
        cp_worker_ptl = partial(cp_worker, L=L)

        try:
            pool = Pool(processes=mp)   
            list(pool.imap(cp_worker_ptl, numlist))
        except Exception as e:
            print(e)
        finally:
            pool.close() # no more tasks
            pool.join()

        return L


if __name__ == '__main__':
    rt = []
    for i in range(cpu_count()):
        t0 = time()
        mp_result = mp_primes(6, mp=i+1)
        t1 = time()
        rt.append(t1-t0)
        print("Using %i core(s), run time is %.2fs" % (i+1, rt[-1]))

Примечание: Я знаю, что для этой задачи было бы более эффективно реализовать многопоточность 1055 *, но фактический скрипт, для которого этот является упрощенным аналогом, несовместим с многопоточностью Python из-за GIL.

1 Ответ

0 голосов
/ 07 мая 2018

@ KellanM заслуженно [+ 1] для количественного мониторинга производительности

Я что-то упустил в своей реализации?

Да, вы абстрагируетесь от всех дополнительных расходов от управления процессами.

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

Джин AMDAHL сформулировал начальный закон убывающей отдачи . enter image description here
Более поздняя, ​​ переформулированная версия , также учитывала влияние управления процессами {setup | terminate} - дополнительные расходы и пробовала справиться с атомарностью обработки (учитывая, что большие полезные нагрузки рабочих пакетов не могут быть легко перераспределены / перераспределены по доступному пулу свободных ядер ЦП в большинстве распространенных систем программирования (за исключением некоторых действительно специфических микро-расписаний) искусство, подобное тому, что продемонстрировано в PARLANSE или SISAL компании LLNL, было продемонстрировано в прошлом).


Лучший следующий шаг?

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

Низкая производительность (для первого случая ниже)
если не катастрофические последствия (из последнего случая ниже),
любой из плохо спроектированных политик сопоставления ресурсов, будь то
an " under-booking"- ресурсы из пула CPU -core
или
и" over-booking"- ресурсы из пула RAM -space
обсуждается также здесь

Ссылка на переформулированный Закон Амдала выше поможет вам оценить точку убывающей прибыли, а не платить больше, чем когда-либо получит.

Эксперименты Hoefinger et Haunschmid могут послужить хорошим практическим доказательством того, как будет расти число обрабатывающих узлов (будь то локальное ядро ​​CPU с управляемым O / S или узел распределенной архитектуры NUMA) начать уменьшать результирующую производительность,
где Точка убывающей отдачи (продемонстрировано в законе верховного агностика Амдала)
фактически станет Очком, после которого вы платите больше, чем получаете. :

enter image description here Удачи на этом интересном поприще! enter image description here


И последнее, но не менее важное:

Проблемы NUMA / не-локальности услышат свое мнение при обсуждении масштабирования для настройки на уровне HPC (вычислительные стратегии in-Cache / in-RAM) и могут - как побочный эффект - помочь обнаружить недостатки (как сообщается @ eryksun выше). Вы можете свободно просматривать текущую NUMA-топологию своей платформы с помощью инструмента lstopo, чтобы увидеть абстракцию, с которой пытается работать операционная система, запланировав «просто» - [CONCURRENT] выполнение задачи по такой топологии NUMA-ресурсов:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...