Больше параллельных процессов, чем доступных процессоров в пафосе - PullRequest
0 голосов
/ 27 декабря 2018

Раньше я мог запускать 100 параллельных процессов следующим образом:

from multiprocessing import Process

def run_in_parallel(some_list):
    proc = []
    for list_element in some_list:
        time.sleep(20)
        p = Process(target=main, args=(list_element,))
        p.start()
        proc.append(p)
    for p in proc:
        p.join()

run_in_parallel(some_list)

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

Следующий минимальный пример моего кода работает хорошо, но, похоже, он ограничен количеством потоков.Как заставить пафос масштабироваться до 100 параллельных процессов?У моего процессора всего 4 ядра.Мои процессы простаивают большую часть времени, но они должны работать в течение нескольких дней.Я не возражаю против того, чтобы этот time.sleep (20) был там для инициализации.

from pathos.multiprocessing import ProcessingPool as Pool

input = zip(itertools.repeat((variable1, variable2, class1), len(some_list)), some_list)

p = Pool()
p.map(main, input)

edit: В идеале я хотел бы сделать p = Pool (node ​​= len (some_list)),который не работает, конечно.

1 Ответ

0 голосов
/ 27 декабря 2018

Я pathos автор.Я не уверен, что правильно интерпретирую ваш вопрос - немного легче интерпретировать вопрос, когда вы предоставили минимальный пример рабочего кода.Однако ...

Это то, что вы имеете в виду?

>>> def name(x):
...   import multiprocess as mp
...   return mp.process.current_process().name
... 
>>> from pathos.multiprocessing import ProcessingPool as Pool
>>> p = Pool(ncpus=10)
>>> p.map(name, range(10))
['PoolWorker-1', 'PoolWorker-2', 'PoolWorker-3', 'PoolWorker-4', 'PoolWorker-6', 'PoolWorker-5', 'PoolWorker-7', 'PoolWorker-8', 'PoolWorker-9', 'PoolWorker-10']
>>> p.map(name, range(20))
['PoolWorker-1', 'PoolWorker-2', 'PoolWorker-3', 'PoolWorker-4', 'PoolWorker-6', 'PoolWorker-5', 'PoolWorker-7', 'PoolWorker-8', 'PoolWorker-9', 'PoolWorker-10', 'PoolWorker-1', 'PoolWorker-2', 'PoolWorker-3', 'PoolWorker-4', 'PoolWorker-6', 'PoolWorker-5', 'PoolWorker-7', 'PoolWorker-8', 'PoolWorker-9', 'PoolWorker-10']
>>>

Тогда, например, если вы хотите перенастроить использовать только 4 процессора, вы можете сделать это:

>>> p.ncpus = 4      
>>> p.map(name, range(20))
['PoolWorker-11', 'PoolWorker-11', 'PoolWorker-12', 'PoolWorker-12', 'PoolWorker-13', 'PoolWorker-13', 'PoolWorker-14', 'PoolWorker-14', 'PoolWorker-11', 'PoolWorker-11', 'PoolWorker-12', 'PoolWorker-12', 'PoolWorker-13', 'PoolWorker-13', 'PoolWorker-14', 'PoolWorker-14', 'PoolWorker-11', 'PoolWorker-11', 'PoolWorker-12', 'PoolWorker-12']

Я бы беспокоился, что если у вас всего 4 ядра, но вы хотите 100-параллельный параллелизм, вы можете не получить масштабирование, которое вы думаете.В зависимости от того, сколько времени занимает функция, которую вы хотите распараллелить, вы можете использовать один из pools, например: pathos.threading.ThreadPool или MPI-ориентированный пул из pyina.

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

...