#python #multiprocessing #pathos
#python #многопроцессорная обработка #пафос
Вопрос:
Я сталкиваюсь с неэффективным распараллеливанием с ProcessingPool.map()
функцией Pathos: к концу обработки один медленно работающий рабочий последовательно обрабатывает последние задачи в списке, в то время как другие рабочие простаивают. Я думаю, это связано с «фрагментированием» списка задач.
При использовании собственного Python multiprocessing.Pool
я могу решить это принудительно chunksize=1
при вызове map
. Однако этот аргумент не поддерживается Pathos, и исходный код предполагает, что это может быть упущением или задачей со стороны разработчиков:
return _pool.map(star(f), zip(*args)) # chunksize
(из Pathos multiprocessing.py
, строка 137)
Я бы хотел сохранить Pathos из-за его способности работать с lambda.
Есть ли какой-нибудь способ получить размер блока, работающий в Pathos? Есть ли обходной путь с использованием одной из других плохо документированных реализаций пула Patho?
Ответ №1:
Я pathos
разработчик. Это не оплошность… вы не можете использовать chunksize
при использовании pathos.pools.ProcessingPool
. Причина, по которой это было сделано, заключалась в том, что я хотел, чтобы map
функции имели тот же интерфейс, что и у python map
… и для этого, в зависимости от multiprocessing
реализации, мне нужно было либо выбрать chunksize
ключевое слово, либо разрешить *args
и **kwds
. Поэтому я выбираю последнее.
Если вы хотите использовать chunksize
, есть _ProcessPool
, который сохраняет исходный multiprocessing.Pool
интерфейс, но имеет расширенную сериализацию.
>>> import pathos
>>> p = pathos.pools._ProcessPool()
>>> p.map(lambda x:x*x, range(4), chunksize=10)
[0, 1, 4, 9]
>>>
Мне жаль, что вы считаете, что документации не хватает. Код в основном состоит из разветвления multiprocessing
стандартной библиотеки python… и я не менял документацию, в которой была воспроизведена функциональность. Например, здесь я перерабатываю документы STL, поскольку функциональность та же:
>>> p = pathos.pools._ProcessPool()
>>> print(p.map.__doc__)
Equivalent of `map()` builtin
>>> p = multiprocessing.Pool()
>>> print(p.map.__doc__)
Equivalent of `map()` builtin
>>>
… и в тех случаях, когда я изменял функциональность, я писал новые документы:
>>> p = pathos.pools.ProcessPool()
>>> print(p.map.__doc__)
run a batch of jobs with a blocking and ordered map
Returns a list of results of applying the function f to the items of
the argument sequence(s). If more than one sequence is given, the
function is called with an argument list consisting of the corresponding
item of each sequence.
>>>
По общему признанию, документы могли бы быть лучше. Особенно можно улучшить документы, поступающие из STL. Пожалуйста, не стесняйтесь добавлять тикет на GitHub или, что еще лучше, PR для расширения документации.
Комментарии:
1. Спасибо за этот подробный и невероятно быстрый ответ, он работает! Я думаю, что подсказка
chunksize
значительно улучшит документы. На нем нет ссылки pathos.readthedocs.io (по крайней мере, ни один из них не был перенастроен поиском). Или дажеmap_with_chunksize
метод вPool
, илиchunk_size
параметр в конструкторе? Я понимаю, что здесь вы выбираете дизайн, но для моего варианта использования параметр оказывается весьма важным.2. Точка зрения о документах. На самом деле, мое решение относительно документации состояло в том, чтобы повторно использовать то, что было в STL, если я не напишу новую функциональность (что, честно говоря, было не слишком много). Я написал эти документы, вероятно, десять лет назад, но их можно было бы пересмотреть. Я добавлю тикет на GitHub, чтобы улучшить документы.