Ответ 1
Открытый MPI очень модульный. Он имеет свою собственную компонентную модель под названием Modular Component Architecture (MCA). Здесь указывается имя параметра --mca
- оно используется для предоставления значений времени выполнения параметрам MCA, экспортируемых различными компонентами в MCA.
Когда два процесса в данном коммуникаторе хотят поговорить друг с другом, MCA находит подходящие компоненты, которые могут передавать сообщения от одного процесса к другому. Если оба процесса находятся на одном и том же node, Open MPI обычно выбирает компонент BTL с общей памятью, известный как sm
. Если оба процесса находятся на разных узлах, Open MPI просматривает доступные сетевые интерфейсы и выбирает самый быстрый, который может подключаться к другому node. Он ставит некоторые предпочтения в таких быстрых сетях, как InfiniBand (через компонент openib
BTL), но если ваш кластер не имеет InfiniBand, TCP/IP используется как резерв, если компонент tcp
BTL находится в списке разрешенных BTLS.
По умолчанию вам не нужно делать ничего особенного, чтобы обеспечить обмен данными с общей памятью. Просто запустите свою программу с помощью mpiexec -np 16 ./a.out
. То, с чем вы связались, - это часть разделяемой памяти в часто задаваемых FAQ по Open MPI, в которой даются подсказки о том, какие параметры sm
BTL можно было бы настроить, чтобы повысить производительность. Мой опыт работы с Open MPI показывает, что параметры по умолчанию почти оптимальны и работают очень хорошо, даже на экзотических аппаратных средствах, таких как многоуровневые системы NUMA. Обратите внимание, что реализация обмена данными по умолчанию для общей памяти копирует данные дважды - один раз из буфера отправки в общую память и один раз из общей памяти в буфер приема. Ярлык существует в виде устройства KNEM, но его необходимо загрузить и скомпилировать отдельно, поскольку он не является частью стандартного ядра Linux. С поддержкой KNEM Open MPI способен выполнять "нулевые копии" между процессами на одном и том же node - копия выполняется с помощью устройства ядра и является прямой копией из памяти первого процесса в память второй процесс. Это значительно улучшает передачу больших сообщений между процессами, которые находятся на одном и том же node.
Другой вариант - полностью забыть о MPI и напрямую использовать разделяемую память. Вы можете использовать интерфейс управления памятью POSIX (см. здесь), чтобы создать блок разделяемой памяти, чтобы все процессы работали на нем напрямую. Если данные хранятся в общей памяти, это может быть полезно, поскольку никакие копии не будут сделаны. Но следите за проблемами NUMA в современных многопроцессорных системах, где каждый сокет имеет свой собственный контроллер памяти, а доступ к памяти из удаленных сокетов на одной плате медленнее. Важное значение имеет процесс пиннинга/привязки процесса - от --bind-to-socket
до mpiexec
, чтобы он привязывал каждый процесс MPI к отдельному ядру процессора.