"Code=sm_X" включает в себя только двоичный (кубинский) код, или также код PTX, или оба?
Я немного запутался по поводу опции 'code=sm_X' в операторе '-gencode'.
Пример: что делает опция компилятора NVCC
-gencode arch=compute_13,code=sm_13
вставлять в библиотеку?
Только машинный код (код кубина) для графических процессоров с CC 1.3 или также код PTX для графических процессоров с CC 1.3?
В "Руководстве по совместимости Maxwell" указано "Только конечные целевые версии, указанные в предложении" code = ", будут сохранены в результирующем двоичном файле".
Исходя из этого, я хотел бы заключить, что данная опция компилятора встраивает машинный код только для графических процессоров с CC 1.3 и без кода PTX. Это будет означать, что не удастся запустить эту библиотеку, например, на плате генерации Максвелла, так как в библиотеке нет встроенного PTX-кода, из которого машинный код может быть скомпилирован "точно в срок" (JIT).
С другой стороны, в презентации GTC 2013 "Введение в CUDA Toolkit как инструмент для сборки приложений" от NVIDIA указано, что "-gencode arch=compute_13,code=sm_13" достаточно для всех графических процессоров с CC >= 1,3 и что с этой опцией компилятора для графических процессоров с CC > 1,3 машинный код JIT-редактируется из кода PTX. Таким образом, информация, представленная в руководстве по совместимости Maxwell и этой презентации GTC, на мой взгляд, противоречива.
1 ответ
nvcc
имеет много форматов, с помощью которых можно указать параметры генерации кода. Прочтение раздела 6 руководства nvcc может быть поучительным.
при использовании этого формата:
nvcc -gencode arch=compute_13,code=sm_13 ...
будет сохранентолько код SASS для устройства sm_13 (cc 1.3). PTX не будет сохранен в исполняемом объекте, и поэтому код может выполняться только на устройстве, способном выполнять cc1.3 SASS.
Используя приведенный выше формат команды, чтобы встроить версию исходного кода PTX в исполняемый объект, необходимо использовать спецификацию виртуальной архитектуры для опции, предоставленной для code=...
, Поскольку этот конкретный формат (используя -gencode
) не позволяет указывать несколько целей в одном коммутаторе, мы должны передать -gencode
несколько раз переключайтесь на nvcc, по одному для каждой цели, которую мы хотим встроить в исполняемый объект.
Таким образом, расширяя приведенный выше пример, мы могли бы использовать следующее:
nvcc -gencode arch=compute_13,code=sm_13 -gencode arch=compute_13,code=compute_13 ...
Это будет включать в себя как cc1.3 SASS (по первым gencode
коммутатор) и cc1.3 PTX (по второму gencode
переключатель) в исполняемом файле. Устройства, способные запускать код SASS cc1.3 напрямую, будут использовать это. Другие устройства (с вычислительной способностью больше, чем cc 1.3) будут выполнять драйвером этап JIT-компиляции, чтобы преобразовать код PTC cc1.3 в код SASS с архитектурой, подходящей для рассматриваемого устройства.
Я согласен, что презентация GTC 2013 (например, слайд 37), кажется, предполагает, что
nvcc -gencode arch=compute_13,code=sm_13 ...
достаточно для всех устройств с вычислительной способностью 1,3 или выше. Это не так, и это легко продемонстрировать. Если вы скомпилируете код с использованием вышеуказанного формата и попытаетесь запустить его на устройстве cc 2.0, произойдет сбой с ошибкой "недопустимая функция устройства", связанной с любым ядром или ядрами, имеющимися в вашем коде.
Снова, nvcc
имеет множество форматов команд и "горячих клавиш" для указания генерации кода. Некоторые относительно простые, такие как:
nvcc -arch=sm_13 ...
встроит версию кода PTX и SASS в исполняемый объект, в результате чего будет предложен вид прямой совместимости.