Размер куска не влияет на то, сколько ядер используется, это задается параметром processes
Pool
.Chunksize устанавливает, сколько элементов итерируемого элемента, который вы передаете Pool.map
, распределяется по одному рабочему процессу за один раз , что Pool
называет "задачей" (на рисунке ниже показан Python 3.7.1).
Если вы установите chunksize=1
, рабочий процесс получает новый элемент в новом задании только после выполнения одногополучил раньше.Для chunksize > 1
рабочий получает сразу целую партию предметов в рамках задачи, а когда она завершается, он получает следующую партию, если они еще остались.
Распределение предметов по одному с помощью chunksize=1
увеличивает гибкость планирования при одновременном снижении общей пропускной способности, поскольку для капельной подачи требуется больше межпроцессного взаимодействия (IPC).
В моем углубленном анализе алгоритма chunksize-пула здесь я определяю единица работы для обработки одного элемента итерируемого как taskel , чтобы избежать конфликтов имен с использованием пула слова "задача".Задача (как единица работы) состоит из chunksize
Taskels.
Вы бы установили chunksize=1
, если не можете предсказать, как долго нужно будет выполнить Taskel, например, задача оптимизации, где время обработкисильно варьируется в зависимости от задач.Здесь капельное кормление не позволяет рабочему процессу сидеть на куче нетронутых предметов, в то же время хрустеть на одном тяжелом задании, не позволяя другим элементам в его задаче распределяться между рабочими процессами в режиме ожидания.
В противном случае, если всем вашим задачам потребуется одинаковое время для завершения, вы можете установить chunksize=len(iterable) // processes
, чтобы задачи распределялись по всем работникам только один раз.Обратите внимание, что это создаст еще одну задачу, чем процессы (процессы + 1), если у len(iterable) / processes
есть остаток.Это может серьезно повлиять на общее время вычислений.Подробнее об этом читайте в ранее связанном ответе.
К вашему сведению, это часть исходного кода, где Pool
внутренне вычисляет размер фрагмента, если не установлен:
# Python 3.6, line 378 in `multiprocessing.pool.py`
if chunksize is None:
chunksize, extra = divmod(len(iterable), len(self._pool) * 4)
if extra:
chunksize += 1
if len(iterable) == 0:
chunksize = 0