Поведение и производительность унифицированной памяти по сравнению с закрепленной памятью хоста

Я студент, который в настоящее время работает над проектом, который состоит из написания определенной программы в CUDA. Я считаю, что предмет этой программы не имеет отношения к вопросу; но я должен отметить, что мой профессор предложил мне использовать объединенную память в моей программе после того, как он увидел мои попытки создать класс интеллектуальных указателей CUDA. Лучше всего описать этот класс как "уникальный указатель на массив", который соответствует идиоме RAII.

После проверки замечаний к выпуску CUDA 6.0 об объединенной памяти (и обновлениях, представленных в CUDA 8.0), я не сомневался, стоит ли переходить на объединенную память или нет.

Q1: я знаю, что объединенная память CUDA отображает память GPU и CPU. Но о какой памяти процессора мы говорим? Это закрепленная память позволяет быстрее передавать данные? Или это стандартная страничная системная память?

Q2: я знаю, что обновления введены в CUDA 8.0 в основном про паскальскую архитектуру. Но можно ли ожидать ускорения в архитектуре Максвелла (по отношению к закрепленной памяти хоста)?

Q3: Несмотря на то, что я всего лишь студент, я вижу, что NVIDIA много работает над созданием унифицированной памяти. Поэтому можно подумать, что использование единой памяти - лучшая идея в долгосрочной перспективе. Я прав?

Q4: правда ли, что каждый раз, когда я хочу получить доступ к одному элементу массива на хосте (в то время как данные находятся на устройстве), весь массив будет скопирован на хост?

1 ответ

Решение

Умные указатели для памяти GPU

(Часть) вашей первоначальной мотивацией была возможность использования умных указателей для (глобальной) памяти GPU; и ваш профессор предложил использовать для этого единую память (хотя мне не совсем понятно, как это могло бы помочь). Ну, дело в том, что вам не нужно изобретать велосипед для этого - вы уже можете unique_ptr Предназначена для (разных видов) памяти CUDA GPU, как часть библиотеки cuda-api-wrappers.

Эти уникальные указатели на самом деле std::unique_ptr(), но с пользовательскими удалителями (и вы создаете их с помощью соответствующих методов. Вы можете найти список методов для их создания на этой странице Doxygen (хотя документация очень частичная на данный момент).

В качестве примера использования рассмотрим пример вектора CUDA vectorAdd, который выполняет поэлементное сложение двух векторов для получения третьего. Вот тот же пример, использующий интеллектуальные указатели как для хоста, так и для памяти устройства (и, в общем, обертки API).

Предостережение: я являюсь автором библиотеки API-оболочек, поэтому я склонен в пользу ее использования:-)

(Частично) ответы на ваши конкретные вопросы

Q1: О каком виде памяти процессора мы говорим [для унифицированных распределений памяти]? Это закрепленная память... или... стандартная страничная системная память?

Я не знаю, но вы можете легко узнать, написав небольшую программу, которая:

  1. Выделяет некоторую управляемую память.
  2. Пишет в него на стороне хоста.
  3. Предварительно загружает его в графический процессор, затем завершает работу.

... и профилировать его для определения пропускной способности PCIe. С PCIe 3.0 и отсутствующим промежуточным трафиком я обычно получаю ~12 ГБ / с из закрепленной памяти и примерно половину от незафиксированной памяти.

Q2:... в CUDA 8.0 ... можно ли ожидать ускорения в архитектуре Maxwell (по отношению к закрепленной памяти хоста)?

По моему весьма ограниченному опыту, производительность унифицированных карт доступа к памяти не улучшается в CUDA 8.0 по сравнению с CUDA 6.0. (но могут быть скрытые изменения в логике предварительной выборки или общей оптимизации кода, которые в некоторых случаях действительно показывают улучшения.) Несмотря на это, помните, что CUDA 6.0 не поддерживает цели sm_52, поэтому ваш вопрос немного спорный.

Q3:... Я вижу, что NVIDIA много работает над созданием унифицированной памяти. Поэтому можно подумать, что использование единой памяти - лучшая идея в долгосрочной перспективе. Я прав?

Я считаю, что ты не прав. Как предполагает руководство по программированию CUDA, унифицированная память - это механизм, предназначенный для простого доступа к памяти и программирования; он жертвует некоторой скоростью для более равномерного и простого кода. Хотя усилия nVIDIA могут несколько снизить накладные расходы на его использование, нет никаких безумных черт оптимизации, которые бы это убрали. На Kepler Tesla использование унифицированной памяти обычно в 1,8–2 раза медленнее в различных тестах; и хотя у меня нет данных по Максвеллу или Паскалю, я сомневаюсь, что это упадет настолько, что вы предпочтете использовать объединенную память по всем направлениям.

Q4: правда ли, что каждый раз, когда я хочу получить доступ к одному элементу массива на хосте (в то время как данные находятся на устройстве), весь массив будет скопирован на хост?

Нет, управляемая память выгружается; поэтому только одна страница будет скопирована по шине PCIe. Но если массив маленький, это может быть весь массив.

Другие вопросы по тегам