Типы передачи cudaMemcpy: по умолчанию против HostToDevice / DeviceToHost

#memory #cuda #nvidia

#память #cuda #nvidia

Вопрос:

cudaMemcpy позволяет программистам явно указывать направление передачи памяти.

Есть ли какое-либо преимущество в ручном указании направления передачи памяти ( cudaMemcpyDeviceToHost / cudaMemcpyHostToDevice / cudaMemcpyDeviceToDevice ) вместо того, чтобы позволять cuda автоматически выводить ( cudaMemcpyDefault ) значения указателя?

Комментарии:

1. указание направления вручную позволяет выполнить дополнительную проверку ошибок во время выполнения cuda. Например, если вы укажете HostToDevice, среда выполнения cuda может проверить, что переданный вами указатель назначения допустим для использования на устройстве. Если вы передали значение по умолчанию и ошибочно использовали два указателя на хост, вы просто получите копию данных host-> host без указания на то, что что-то не так.

2. Хороший момент. Я думаю, что еще лучше, если есть статическая проверка типов, чтобы предотвратить смешивание указателей хоста и устройства. У меня есть оболочки для указателей устройств и memory API. Это гарантирует, что во время компиляции не произойдет такого недопустимого смешивания. Документация рекомендует использовать cudaMemcpyDefault с указанием вручную, но не объясняет почему.

3. Это поражает меня как вопрос, отличный от того, который вы задали в своем вопросе. В вашем вопросе вы спросили, есть ли преимущество ручной спецификации, на что я ответил. Я не могу раскрыть недокументированную информацию. Если вы хотите увидеть улучшения в CUDA, вы можете отправить отчет об ошибке (в данном случае по документации) по адресу developer.nvidia.com

Ответ №1:

tl; dr: Почти наверняка нет преимущества.

cudaMemcpyDefault был добавлен IIRC, когда графические процессоры стали способны легко идентифицировать пространство памяти путем проверки адреса («Унифицированная виртуальная адресация»). Перед этим вам нужно было указать направление. Смотрите, например, документацию CUDA 3, доступную здесь. Найдите cudaMemcpyKind в ссылке на API — по умолчанию нет, только H2H, H2D, D2H и H2H.

Когда это изменилось, я думаю, для nVIDIA имело смысл не перегружать функцию или называть ее по-другому, а просто добавить другое постоянное значение для новой возможности.

Я не уверен на 100%, что разницы нет, это просто очень разумно; и, исходя из личного опыта, я не видел никаких преимуществ / различий. Конечно, копирование происходит не быстрее.

Ответ №2:

Из документов cudaMemcpy() :

[…] Рекомендуется передавать cudaMemcpyDefault , и в этом случае тип передачи определяется по значениям указателя. Однако cudaMemcpyDefault это разрешено только в системах, поддерживающих унифицированную виртуальную адресацию. […]

Поэтому, если у вас есть графический процессор, который допускает унифицированную виртуальную адресацию, используйте cudaMemcpyDefault , в противном случае у вас нет другого выбора, кроме как быть явным.

Вы можете запросить, поддерживает ли ваша система это с помощью

cudaGetDeviceProperties() со свойством устройства cudaDeviceProp::unifiedAddressing .

Комментарии:

1. Да, но есть ли какое-либо преимущество в одном или другом?

2. @talonmies ну, как вы знаете, это не задокументировано там, как и множество других вещей CUDA, которые, похоже, не задокументированы. Если документы рекомендуют это, я предполагаю, что есть какая-то причина, почему это лучше (в противном случае я бы сказал, что они плохо написаны). Я этого не знаю. Если вы это сделаете, пожалуйста, ответьте на вопрос, чтобы больше из нас могли узнать 😉