Какова цель использования нескольких "арочных" флагов в компиляторе Nvidia NVCC?

Недавно я понял, как NVCC компилирует код устройства CUDA для различных вычислительных архитектур.

Насколько я понимаю, при использовании опции -gencode NVCC "arch" - это минимальная вычислительная архитектура, требуемая приложением программиста, а также минимальная вычислительная архитектура устройства, для которой JIT-компилятор NVCC будет компилировать PTX-код.

Я также понимаю, что параметр "code" -gencode - это вычислительная архитектура, для которой NVCC полностью компилирует приложение, так что компиляция JIT не требуется.

После проверки различных Makefiles проекта CUDA я заметил, что регулярно происходят следующие события:

-gencode arch=compute_20,code=sm_20
-gencode arch=compute_20,code=sm_21
-gencode arch=compute_21,code=sm_21

и после некоторого чтения я обнаружил, что несколько архитектур устройств могут быть скомпилированы для одного двоичного файла - в данном случае sm_20, sm_21.

Мои вопросы: почему так много пар "арка / код" необходимо? Все ли значения "арки" используются в приведенном выше?

какая разница между этим и сказать:

-arch compute_20
-code sm_20
-code sm_21

Самая ранняя виртуальная архитектура в полях "арка" выбирается автоматически или есть какое-то другое неясное поведение?

Есть ли какие-либо другие особенности компиляции и времени выполнения, о которых мне следует знать?

Я прочитал руководство, http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html, и мне все еще неясно, что происходит во время компиляции или выполнения.

2 ответа

Решение

Грубо говоря, процесс компиляции кода выглядит так:

Исходный код устройства CUDA C/C++ -> PTX -> SASS

Виртуальная архитектура (например, compute_20независимо от того, что указано -arch compute...) определяет, какой тип кода PTX будет создан. Дополнительные переключатели (например, -code sm_21) определить, какой тип кода SASS будет сгенерирован. SASS - это фактически исполняемый объектный код для графического процессора (машинный язык). Исполняемый файл может содержать несколько версий SASS и / или PTX, и существует механизм загрузчика времени выполнения, который выбирает соответствующие версии на основе фактически используемого графического процессора.

Как вы указали, одной из удобных функций работы с графическим процессором является JIT-компиляция. JIT-компиляция будет выполняться драйвером графического процессора (не требует установки инструментария CUDA) каждый раз, когда доступен подходящий код PTX, а подходящего кода SASS нет.

Одно из преимуществ включения нескольких виртуальных архитектур (то есть нескольких версий PTX) заключается в том, что у вас есть совместимость исполняемых файлов с большим количеством целевых устройств GPU (хотя некоторые устройства могут запускать JIT-компиляцию для создания необходимого SASS).

Одним из преимуществ включения нескольких "реальных целей GPU" (то есть нескольких версий SASS) является то, что вы можете избежать этапа JIT-компиляции, когда присутствует одно из этих целевых устройств.

Если вы укажете неверный набор параметров, можно создать исполняемый файл, который не будет работать (правильно) на конкретном графическом процессоре.

Одним из возможных недостатков при указании большого количества этих параметров является увеличение размера кода. Другим возможным недостатком является время компиляции, которое обычно будет больше, если вы укажете больше опций.

Также возможно создание исполняемых файлов, не содержащих PTX, которые могут быть интересны тем, кто пытается скрыть свой IP.

Создание PTX, подходящего для JIT, должно быть сделано путем указания виртуальной архитектуры для code переключатель.

Цель нескольких -arch флаги, чтобы использовать __CUDA_ARCH__ макрос для условной компиляции (т. е. используя #ifdef) по-разному оптимизированных путей кода.

Смотрите здесь: http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html

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