2016-05-14 4 views
2

Я запускаю скрипт Python в кластере HPC. Функция в сценарии использует starmap из пакета multiprocessing, чтобы распараллелить определенный процесс с интенсивным вычислением.Использование многопроцессорности Python в кластере HPC

Когда я запускаю сценарий на одной некластерной машине, я получаю ожидаемое повышение скорости. Когда я вхожу в узел и запускаю сценарий локально, я получаю ожидаемое повышение скорости. Однако, когда диспетчер заданий запускает скрипт, ускорение скорости от multiprocessing либо полностью смягчается, либо, иногда, даже вдвое медленнее. Мы заметили, что подкачка памяти возникает, когда вызывается функция starmap. Мы считаем, что это имеет какое-то отношение к природе Python's multiprocessing, то есть к тому факту, что отдельный интерпретатор Python запускается для каждого ядра.

Поскольку мы успешно работали с консоли с одного узла, мы попытались запустить сценарий с HPC_CREATECONSOLE=True, но безрезультатно.

Есть ли какие-то настройки в менеджере заданий, которые мы должны использовать при запуске сценариев Python, которые используют multiprocessing? multiprocessing просто не подходит для кластера HPC?

ответ

0

К сожалению, я не смог найти ответ в сообществе. Однако, благодаря экспериментам, я смог лучше изолировать проблему и найти приемлемое решение.

Проблема возникает из-за реализации Python multiprocessing. Когда создается объект Pool (т. Е. Класс менеджера, который управляет ядрами обработки для параллельной работы), для каждого ядра запускается новое время выполнения Python. В моем коде есть несколько мест, где используется пакет multiprocessing, и создается объект Pool ... каждая функция, которая требует его создания, при необходимости создает объект Pool, а затем присоединяется и завершается перед выходом. Поэтому, если я вызываю функцию 3 раза в коде, 8 экземпляров Python разворачиваются и затем закрываются 3 раза. На одной машине накладные расходы на это были незначительными по сравнению с вычислительной нагрузкой функций ... однако на HPC это было абсурдно высоко.

Я повторно сконструировал код так, чтобы объект Pool был создан в самом начале вызова процесса и затем передавался каждой функции по мере необходимости. Он закрыт, соединен и завершен в конце всего процесса.

Мы обнаружили, что основная часть времени была потрачена на создание объекта Pool на каждом узле. Это было улучшение, потому что оно создавалось только однажды! Затем мы поняли, что основная проблема заключалась в том, что несколько узлов пытались одновременно получить доступ к Python в одном и том же месте из-за сети (он был установлен только на головной узел). Мы установили Python и приложение на всех узлах, и проблема была полностью исправлена.

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

Смежные вопросы