Количество параллельных процессов определяется количеством физических процессоров или количеством логических процессоров? - PullRequest
0 голосов
/ 19 января 2020

Вот моя информация о процессоре:

enter image description here

Я использую ray для обучения алгоритмов обучения подкреплению, где я определяю Learner класс украшен @ray.remote(num_cpus=2) и Worker класс украшен ray.remote(num_cpus=1). Чтобы получить максимальную производительность, сколько рабочих я могу иметь?

Раньше я устанавливал количество рабочих на 8-10, но сегодня я сталкиваюсь с этим постом , в котором написано

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

Это говорит о том, что количество физических процессоров ограничивает Количество процессов, работающих параллельно. Означает ли это, что я не должен использовать более 4 рабочих для достижения максимальной производительности, предполагая, что рабочие сильно нагружают процессор? Я надеюсь, что кто-то может дать мне подробное объяснение (или ссылку). Заранее спасибо.

Обновление

Спасибо за комментарии @ AM C и @KlausD .. Я обновляю свой вопрос здесь, надеясь, что он прояснит мой вопрос.

Я провел несколько тестов. Например, я проводил эксперименты с 1, 3, 8 работниками, отдельно. Вот результат:

  • Для случая с одним работником требуется 400 м для выполнения 400 шагов
  • Для случая с 3 работниками для выполнения 400 шагов требуется в среднем 4 м 29 с
  • В случае с 6 работниками для выполнения 400 шагов в среднем требуется 5 мсек.

Я пришел к выводу, что в случае с 6 работниками произошел конфликт процессора. Тем не менее, я открыл top (где я мог видеть 12 процессоров), чтобы проверить использование процессора, все работники использовали около 100% процессора. Поэтому я понятия не имел, был ли мой вывод верным.

Я также написал небольшую программу для дальнейшего тестирования. Код приведен ниже

from time import time
import numpy as np
import ray


@ray.remote(num_cpus=1)
def f(x, y):
    start = time()
    while True:
        x += y
        if np.mean(x) > 100:
            break
    return time() - start

if __name__ == '__main__':
    # I intend to make x and y large to increase the cpu usage.
    x = np.random.rand(1000, 10000)
    y = np.random.uniform(0, 3, (1000, 10000))
    print('x mean:', np.mean(x))
    print('y mean:', np.mean(y))
    for n in range(1, 30, 3):
        ray.init()

        start = time()
        result = ray.get([f.remote(x, y) for _ in range(n)])

        print('Num of workers:', n)
        # print('Run time:', result)
        print('Average run time:', np.mean(result))
        print('Ray run time:', time() - start)
        ray.shutdown()

Вот результат

x mean: 0.4998949941471149
y mean: 1.4997634832632463

Num of workers: 1
Average run time: 1.3638701438903809
Ray run time: 2.1305620670318604

Num of workers: 4
Average run time: 3.1797224283218384
Ray run time: 4.065998554229736

Num of workers: 7
Average run time: 5.139907530375889
Ray run time: 6.446819543838501

Num of workers: 10
Average run time: 7.569052147865295
Ray run time: 8.996447086334229

Num of workers: 13
Average run time: 8.455958109635572
Ray run time: 11.761570692062378

Num of workers: 16
Average run time: 7.848772034049034
Ray run time: 13.739320278167725

Num of workers: 19
Average run time: 8.033894174977354
Ray run time: 16.16210103034973

Num of workers: 22
Average run time: 8.699185609817505
Ray run time: 18.566803693771362

Num of workers: 25
Average run time: 8.966830835342407
Ray run time: 21.45942711830139

Num of workers: 28
Average run time: 8.584995950971331
Ray run time: 23.2943696975708

Я ожидал, что, по крайней мере, дело с 4 работниками должно занять почти то же время, что и дело с 1 работником, как я имеют 6 физических ядер. Но результат, кажется, предлагает другую историю. Кроме того, я не понимаю, почему Average run time перестает расти, когда число работников превышает 10?

1 Ответ

0 голосов
/ 20 января 2020

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

cat /proc/cpuinfo

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

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

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

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

...