Что означает настройку MPI для общей памяти?

У меня есть немного вопросов, связанных с исследованиями.

В настоящее время я закончил реализацию структуры каркасного каркаса на основе MPI (в частности, используя openmpi 6.3). рамочная работа должна использоваться на одной машине. теперь, я сравниваю его с другими предыдущими реализациями скелета (такими как scandium, быстрый поток,..)

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

Есть несколько больших разниц в времени завершения двух категорий.

Сегодня я также ознакомлен с конфигурацией open-mpi для общей памяти здесь = > openmpi-sm

и наступает мой вопрос.

1st, что значит настроить MPI для общей памяти? Я имею в виду, что процессы MPI живут в собственной виртуальной памяти; что же такое флаг, как в следующей команде? (Я думал, что в MPI каждое сообщение связано с явным передачей сообщения, никакой памяти не разделяется между процессами).

    shell$ mpirun --mca btl self,sm,tcp -np 16 ./a.out

2nd почему производительность MPI намного хуже по сравнению с другой реализацией скелета, разработанной для общей памяти? По крайней мере, я также запускаю его на одной многоядерной машине. (Я полагаю, это потому, что в другой реализации использовалось параллельное программирование потоков, но у меня нет убедительных объяснений).

любое предложение или дальнейшее обсуждение приветствуются.

Пожалуйста, дайте мне знать, если мне нужно уточнить мой вопрос.

Благодарю вас за ваше время!

Ответ 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 к отдельному ядру процессора.