Как во время выполнения определить, когда MPI с поддержкой CUDA будет передавать через ОЗУ?C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Как во время выполнения определить, когда MPI с поддержкой CUDA будет передавать через ОЗУ?

Сообщение Anonymous »

Я хочу во время выполнения определить, собирается ли MPI с поддержкой CUDA отправлять данные непосредственно между VRAM моих графических процессоров или он собирается автоматически вернуться к первому клонированию данных в ОЗУ. Я хочу избежать последнего сценария, потому что я могу сделать это клонирование быстрее. Мне нужно выполнить эту проверку надежным способом для интеграции в библиотеку.
Контекст
Мое распределенное приложение C++ включает в себя значительную замену объемы данных (например, 64 ГиБ) между VRAM (очень мощных) графических процессоров CUDA. Пользователь может скомпилировать с помощью «обычного» MPI, или MPI с поддержкой CUDA, и логика взаимодействующего кода будет выглядеть следующим образом:

Код: Выделить всё

function swapGPUArrays():

if MPI is CUDA-aware:
exchange VRAM pointers directly

else:
cudaMemcpy VRAM to RAM
exchange RAM pointers
cudaMemcpy RAM to VRAM

Код: Выделить всё

function exchangeArrays():

partition arrays into maximum-sized MPI messages (about `16 GiB`)

asynchronously send/recv each message

wait for all asynchs to finish
Код использует эту проверку, чтобы определить, поддерживает ли MPI-компилятор CUDA (и, следовательно, может напрямую отправлять данные в память устройства CUDA), а в противном случае возвращается к копированию памяти устройства в постоянные массивы ОЗУ. , которые затем обмениваются. Обратите внимание: поскольку обмениваемая память слишком велика для одного сообщения MPI, она делится на несколько сообщений; они обмениваются асинхронно (поэтому их передача может происходить одновременно), как указано в этой работе.
Этот код отлично работает в следующих сценариях:
  • используется MPI-компилятор, не поддерживающий CUDA; обмен памятью осуществляется через RAM
  • используется MPI-компилятор с поддержкой UCX и CUDA; обмен указателями VRAM осуществляется напрямую, причем «за кулисами» это делается с использованием оптимизированных методов (например, одноранговая прямая связь между графическими процессорами, если это разрешено такими вещами, как NVLink).

    Проблема
    Рассмотрим сценарий, в котором пользователь компилирует этот код с помощью MPI с поддержкой CUDA, но его графические процессоры нет напрямую подключен к сети/межсоединению. Это означает, что во время выполнения вызовы sendrecv MPI, поддерживающего CUDA, будут тайно маршрутизировать сообщения через ОЗУ, аналогично моему коду выше. Это работает правильно, но, увы, у них недостаточная производительность!
  • В моей ручной копии я cudaMemcpy полностью данных из VRAM в RAM за один вызов. Затем я разделяю данные на отдельные сообщения между RAM.
  • MPI с поддержкой CUDA создает копии из VRAM в RAM для каждого сообщения. Выполнение уже достигло функции ExchangeArrays() и разделило полезную нагрузку на сообщения, прежде чем MPI решит скопировать их в ОЗУ.
Это означает, что разрешение MPI с поддержкой CUDA приводит к более медленному копированию из RAM в VRAM из-за разделения на множество меньших копий. Для моего тестирования это примерно в 2 раза медленнее.
Ищу решение
Если бы я заранее знал, что MPI с поддержкой CUDA в любом случае собирался маршрутизироваться через ОЗУ, я мог бы сделать это самостоятельно с помощью единственного вызова cudaMemcpy. Поэтому я ищу такую ​​функцию, как

Код: Выделить всё

isMpiGoingToRouteThroughRAM()
который я затем мог бы запросить, чтобы изменить исходный оператор if на:

Код: Выделить всё

if (MPI is CUDA-aware) and (not isMpiGoingToRouteThroughRAM()):
...
В идеале мне нужно выполнить эту проверку во время выполнения, а не во время компиляции, поскольку пользователь может компилировать и развертывать на разных машинах. Я ценю, что такая проверка может оказаться специфичной для MPI-компилятора. Я намерен поддерживать все основные компиляторы MPI (конечно, по крайней мере OpenMPI и MPICH) с использованием средств защиты препроцессора.
Все предложения приветствуются!
Вопрос по теме
Когда MPI с поддержкой CUDA возвращается к маршрутизации через ОЗУ, ему обязательно нужны буферы ОЗУ для отправки/получения сообщений в/из. Я не передаю указатель оперативной памяти при вызове sendrecv — это расточительное выделение и уничтожение временной оперативной памяти? Это была бы еще одна катастрофа, которой я хотел бы избежать!

Подробнее здесь: https://stackoverflow.com/questions/782 ... hrough-ram
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»