Как я могу заставить multiprocessing.pool.map распределять процессы в числовом порядке?
Дополнительная информация:
У меня есть программа, которая обрабатывает несколько тысяч файлов данных, составляя график каждого из них. Я использую multiprocessing.pool.map
для передачи каждого файла процессору, и он отлично работает. Иногда это занимает много времени, и было бы неплохо смотреть на выходные изображения во время работы программы. Это было бы намного проще, если бы процесс карты распределял снимки по порядку; вместо этого для конкретного прогона, который я только что выполнил, первые 8 проанализированных снимков были: 0, 78, 156, 234, 312, 390, 468, 546
. Есть ли способ заставить их распределять их более близко по порядку номеров?
Пример:
Вот пример кода, который содержит те же ключевые элементы и показывает тот же базовый результат:
import sys
from multiprocessing import Pool
import time
num_proc = 4; num_calls = 20; sleeper = 0.1
def SomeFunc(arg):
time.sleep(sleeper)
print "%5d" % (arg),
sys.stdout.flush() # otherwise doesn't print properly on single line
proc_pool = Pool(num_proc)
proc_pool.map( SomeFunc, range(num_calls) )
Урожайность:
0 4 2 6 1 5 3 7 8 10 12 14 13 11 9 15 16 18 17 19
Отвечать:
От @Hayden: используйте параметр chunksize, def map(self, func, iterable, chunksize=None)
.
Дополнительная информация: chunksize
определяет, сколько итераций выделяется каждому процессору за раз. В моем примере выше, например, используется размер фрагмента 2 --- что означает, что каждый процессор отключается и выполняет свою задачу в течение 2 итераций функции, а затем возвращается для большего количества («проверка»). Компромисс размера chunksize заключается в том, что существуют накладные расходы на «регистрацию», когда процессор должен синхронизироваться с остальными, что говорит о том, что вам нужен большой размер chunksize. С другой стороны, если у вас есть большие фрагменты, то один процессор может завершить свой фрагмент, в то время как другому остается много времени, поэтому вам следует использовать небольшой размер фрагмента. Я предполагаю, что дополнительная полезная информация - это то, какой диапазон есть, сколько времени может занять каждый вызов функции. Если они действительно должны занимать одинаковое количество времени - гораздо эффективнее использовать большой размер блока. С другой стороны, если вызовы некоторых функций могут занимать в два раза больше времени, чем другие, вам нужен небольшой размер фрагментов, чтобы процессоры не застали в ожидании.
Для моей проблемы каждый вызов функции должен занимать примерно одинаковое количество времени (я думаю), поэтому, если я хочу, чтобы процессы вызывались по порядку, я собираюсь пожертвовать эффективностью из-за накладных расходов на регистрацию.
SomeFunc
я бы вызвал другую функцию, напримерPlotFunc()
, который создает изображение сmatplotlib
иpyplot
и сохраняет его на диск. - person DilithiumMatrix   schedule 28.07.2013