Странная проблема в использовании гибридного программирования MPI / OpenMP. Количество потоков OpenMP всегда равно 1 в параллельной области - PullRequest
0 голосов
/ 22 июня 2019

Конфигурация системы:

Workstation with two Xeon E5-2620 V4 CPUs. Cent OS 7.3.

Openmpi-3.0.1, ifort 2015, gcc 4.8.6, intel MKL.

Я запускаю гибридную программу MPI / OpenMP на рабочей станции. Я хочу использовать 1 процесс MPI с 8 потоками OpenMP. Однако количество потоков OpenMP, используемых в параллельной области, всегда равно 1. На другой машине с процессором Intel 9900K количество потоков OpenMP всегда равно 2. Для обеих машин я напечатал OMP_NUM_THREADS, вызвав omp_get_max_threads. OMP_NUM_THREADS равно 8, так как я уже установил "export OMP_NUM_THREADS=8". Это действительно беспокоит.

Покопавшись около суток, я понял, что это связано с параметром Openmpi "-bind-to". Если используется «-bind-to none» или «-bind-to numa», программа работает нормально, поскольку загрузка ЦП для каждого процесса MPI составляет 800%, и в параллельной области достигается ускорение в 8 раз. Если я использую значение по умолчанию, которое «-bind-to core». Количество потоков OpenMP не всегда то, что я ожидал. Поэтому на рабочей станции с Xeon 2640 мы отключили гиперпоточность, поэтому реальные используемые потоки openmp всегда равны 1. Для ПК с Intel i7-9900K гиперпоточность включена, поэтому число используемых потоков OMP равно 2.

Более того, если я не использую параметры "-bind-to none/numa", omp_get_num_procs возвращает 1. Если используется "-bind-to none", omp_get_num_procs возвращает число процессоров (ядер ЦП) при использовании "-bind-to numa", omp_get_num_procs возвращает номер процессорных ядер в одном процессоре.

Я публикую здесь свой опыт, который может помочь другим людям с подобной проблемой.

1 Ответ

0 голосов
/ 22 июня 2019

Как указано Жилем в комментарии , в гибридных запусках MPI + OpenMP есть два места для работы с наборами процессоров. Первым из них является библиотека MPI и программа mpirun (mpiexec), которая осуществляет распределение процессов MPI на доступных узлах и их доступных процессорах (с помощью hwloc ). Тогда каждый запущенный процесс MPI будет иметь некоторый разрешенный набор логических ядер ЦП, и библиотека OpenMP (многопоточность) будет пытаться работать с этими доступными ресурсами. Библиотека OpenMP (gcc's libgomp или intel & llvm's openmprtl.org) может проверять набор разрешенных ядер, чтобы решить, какое количество потоков использовать.

Когда вы хотите " N MPI-процесс с K OpenMP-потоками ", вы должны проверить, что ваш mpirun даст K разрешенных ядер для каждого MPI-процесса. И mpirun не будет уважать вашу переменную OMP_NUM_THREADS env.

mpirun в OpenMPI имеет полезную опцию --report-bindings, чтобы увидеть, что является допустимым набором в реальном запуске. Он также имеет множество (не очень простых в использовании) опций для изменения привязок, описанных на странице руководства https://www.open -mpi.org / DOC / v4.0 / man1 / mpirun.1.php

Вы можете попробовать mpirun -n 1 --report-bindings true, чтобы увидеть фактические привязки без запуска вашей программы. Для 1 MPI-процесса и 8 ядер на процесс попробуйте параметр "--cpus-per-proc <#perproc> - привязать каждый процесс к указанному количеству процессоров. "

 mpirun -n 1 --cpus-per-proc 8 --report-bindings true

Эта опция устарела, но все еще может работать, и это намного проще, чем "--map-by <obj>:PE=n". (Я не совсем понимаю этот вариант сейчас. Возможно, --map-by socket или --bind-by socket может помочь вам связать процесс MPI со всеми доступными ядрами чипа процессора)

Чтобы выяснить, как соотносятся логические ядра процессора с гиперпоточностью и настоящими ядрами процессора, вы можете использовать библиотеку hwloc и ее инструмент lstopo https://www.open -mpi.org / projects / hwloc / doc / v2.0.4 / a00312 .php # cli_examples

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...