Замедление при параллельном запуске подпроцессов при использовании mpi4py - PullRequest
0 голосов
/ 29 августа 2018

Используя mpi4py, я запускаю программу на python, которая запускает несколько процессов fortran параллельно, начиная со скрипта SLURM, используя (например):

mpirun -n 4 python myprog.py

но заметили, что myprog.py выполняется дольше, чем больше число запрошенных задач, например. работает myprog.py (следующий код показывает только часть программы mpi):

comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()

data = None

if rank == 0:
    data = params

recvbuf = np.empty(4, dtype=np.float64) 
comm.Scatter(data, recvbuf, root=0)

py_task(int(recvbuf[0]), recvbuf[1], recvbuf[2], int(recvbuf[3]))

с mpirun -n 1 ... для одного массива recvbuf занимает 3 минуты, в то время как работа с четырьмя массивами recvbuf (предположительно параллельно), на четырех процессорах, использующих mpirun -n 4 ..., занимает около 5 минут. Тем не менее, я ожидаю, что время выполнения будет примерно одинаковым как для одного, так и для четырех процессоров.

py_task - это по сути оболочка Python для запуска программы на фортране:

subprocess.check_call(cmd) 

Кажется, существует некоторое взаимодействие между subprocess.check_call (cmd) и пакетом mpi4py, который мешает коду работать должным образом параллельно.

Я искал эту проблему, но не могу найти ничего, что помогло бы ей. Есть ли какие-либо исправления этой проблемы / подробные описания, объясняющие, что здесь происходит / рекомендации о том, как выделить причину узкого места в этом коде?

Дополнительное примечание:

Этот конвейер был адаптирован для mpi4py из "параллельного импорта joblib", где ранее не было проблем с параллельным выполнением subprocess.check_call (), и поэтому я подозреваю, что эта проблема связана с взаимодействием между подпроцессом и mpi4py .

1 Ответ

0 голосов
/ 12 сентября 2018

Замедление было изначально исправлено добавлением:

экспорт SLURM_CPU_BIND = нет

к сценарию slurm, который запускал задания.

Хотя вышеприведенное действительно обеспечило временное исправление, на самом деле проблема была гораздо глубже, и я приведу очень простое описание этого здесь.

1) Я удалил mpi4py, который я установил с помощью conda, а затем переустановил его с загрузкой Intel MPI (рекомендуемая версия MPI для нашего вычислительного кластера). В сценарии SLURM я изменил запуск программы на python:

srun python my_prog.py.

и убрал строку экспорта ... выше, а замедление было убрано.

2) Было обнаружено еще одно замедление для запуска> 40 задач одновременно. Это было связано с:

Каждый раз, когда запускается подпроцесс на основе фортрана, файловая система запрашивает начальные ресурсы (например, предоставление файла в качестве аргумента программе). В моем случае одновременно запускалось большое количество задач, и каждый файл мог иметь размер ~ 500 МБ, что, вероятно, превышало возможности ввода-вывода кластерной файловой системы. Это привело к большим накладным расходам, связанным с замедлением запуска каждого подпроцесса.

В предыдущей реализации распараллеливания для JobLib использовалось не более 24 ядер одновременно, а затем в запросах к файловой системе не было существенного узкого места, поэтому ранее не было обнаружено проблем с производительностью.

Для 2) я обнаружил, что лучшим решением было бы значительно реорганизовать мой код , чтобы минимизировать количество запущенных подпроцессов. Очень простое исправление, но о котором я не знал прежде, чем узнал об узких местах в запросах ресурсов в файловых системах.

(Наконец, я также добавлю, что использование модуля подпроцесса в mpi4py, как правило, не рекомендуется в режиме онлайн, при этом многопроцессорный модуль предпочтителен для использования с одним узлом.)

...