Передача нескольких итераций в многопроцессорную систему pool.map [duplicate]

Перейдите к своему config.php. У меня такая же проблема. Проверьте имя пользователя и пароль, а также sql select - это то же имя, что и config.

9
задан usual me 28 January 2016 в 13:54
поделиться

1 ответ

Использование multiprocessing требует отправки рабочим процессам информации о выполняемой функции, а не только аргументы для передачи. Эта информация передается травлением , что информация в основном процессе, отправка его в рабочий процесс и ее рассыпание.

Это приводит к основной проблеме:

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

Но травление функции partial включает в себя травление основной функции (дешево) и всех аргументы по умолчанию ( дорогие , когда аргумент по умолчанию - 10M list). Поэтому каждый раз, когда задача отправляется в случае partial, она травит связанный аргумент, отправляет его в рабочий процесс, рабочий процесс распаковывается, а затем выполняет «настоящую» работу. На моей машине этот рассол имеет размер примерно 50 МБ, что является огромным объемом накладных расходов; в быстрых тестах времени на моей машине, травление и рассыпание 10 миллионов длинной list из 0 занимает около 620 мс (и это игнорирует накладные расходы на фактическую передачу 50 МБ данных).

partial должны рассосаться таким образом, потому что они не знают своих имен; при расчете функции, подобной f, f (будучи def -ed) знает свое квалифицированное имя (в интерактивном интерпретаторе или из основного модуля программы это __main__.f), поэтому удаленная сторона может просто воссоздайте его локально, выполнив эквивалент from __main__ import f. Но partial не знает его имени; конечно, вы назначили его g, но ни pickle, ни partial сами не знают, что это доступно с квалифицированным именем __main__.g; его можно было бы назвать foo.fred или миллион других вещей. Поэтому он должен pickle получить информацию, необходимую для воссоздания целиком с нуля. Это также pickle для каждого вызова (не один раз на одного рабочего), потому что он не знает, что вызываемый не меняет родителя между рабочими элементами, и он всегда пытается обеспечить его отправку в актуальное состояние.

У вас есть другие проблемы (создание временного времени для list только в случае partial и незначительные накладные расходы при вызове функции partial, завершенной или вызывающей функцию напрямую), но это chump изменение относительно накладного травления для каждого вызова и разблокировка partial добавляется (первоначальное создание list добавляет одноразовые служебные данные чуть ниже половины того, что каждый цикл pickle / unpickle расходы, накладные расходы для вызова через partial меньше, чем микросекунда).

9
ответ дан ShadowRanger 4 September 2018 в 07:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: