CUDA: как использовать -arch и -code и SM vs COMPUTE

Я все еще не уверен, как правильно указать архитектуры для генерации кода при создании с помощью nvcc. Я знаю, что есть машинный код, а также код PTX, встроенный в мой двоичный файл, и что это можно контролировать с помощью переключателей контроллера -code и -arch (или комбинации обоих с использованием -gencode).

Теперь, согласно this, кроме двух флагов компилятора, существуют также два способа указания архитектур: sm_XX и compute_XX, где compute_XX относится к виртуальной и sm_XX к реальной архитектуре. Флаг -arch принимает только идентификаторы для виртуальных архитектур (например, compute_XX), тогда как флаг -code принимает как идентификаторы для реальных, так и для виртуальных архитектур.

В документации указано, что -arch указывает виртуальные архитектуры, для которых скомпилированы входные файлы. Однако этот код PTX не компилируется автоматически в машинный код, но это скорее "шаг предварительной обработки".

Теперь -code должен указать, какие архитектуры собираются и оптимизируются для кода PTX.

Однако неясно, какой PTX или двоичный код будет встроен в двоичный файл. Если я укажу, например, -arch=compute_30 -code=sm_52, означает ли это, что мой код сначала будет скомпилирован для PTX уровня 3.0, из которого впоследствии будет создан машинный код для уровня элемента 5.2? И что будет внедрено?

Если я просто укажу -code=sm_52, что произойдет? Будет введен только машинный код для V5.2, который был создан из кода V5.2 PTX? И какова будет разница с -code=compute_52?

Ответ 1

Некоторые связанные вопросы/ответы здесь и здесь.

Я все еще не уверен, как правильно указать архитектуры для генерации кода при создании с помощью nvcc.

Полное описание несколько сложное, но предполагается, что это относительно простое, легко запоминающееся каноническое использование. Компиляция для архитектуры (как виртуальной, так и реальной), которая представляет собой графические процессоры, на которые вы хотите настроить таргетинг. Достаточно простая форма:

-gencode arch=compute_XX,code=sm_XX

где XX - это двухзначная вычислительная способность для графического процессора, на который вы хотите настроить таргетинг. Если вы хотите настроить таргетинг на несколько графических процессоров, просто повторите всю последовательность для каждой цели XX. Это примерно подход, применяемый к проектам кода кода CUDA. (Если вы хотите включить PTX в свой исполняемый файл, включите дополнительный -gencode с опцией code, указав ту же виртуальную архитектуру PTX, что и опция arch).

Другая довольно простая форма, предназначенная только для одного графического процессора, заключается в следующем:

-arch=sm_XX 

с тем же описанием для XX. Эта форма будет включать как SASS, так и PTX для указанной архитектуры.

Теперь, в соответствии с этим, кроме двух флагов компилятора, есть два способа указания архитектур: sm_XX и compute_XX, где compute_XX ссылается на виртуальную и sm_XX на реальную архитектуру. Флаг -arch принимает только идентификаторы для виртуальных архитектур (например, compute_XX), тогда как флаг -кода принимает как идентификаторы для реальных, так и для виртуальных архитектур.

Это в основном правильное, если arch и code используются как подпереключатели в коммутаторе -gencode, или если оба используются вместе, автономно, как вы описываете. Но, например, когда -arch используется сам по себе (без -code), он представляет собой другой вид "сокращенного" обозначения, и в этом случае вы можете передать реальную архитектуру, например -arch=sm_52

Однако неясно, какой PTX или двоичный код будет встроен в двоичный файл. Если я укажу, например, -arch = compute_30 -code = sm_52, значит ли это, что мой код сначала будет скомпилирован для PTX уровня 3.0, из которого впоследствии будет создан машинный код для уровня 5.2? И что будет внедрено?

Точное определение того, что внедряется, зависит от формы использования. Но для этого примера:

-gencode arch=compute_30,code=sm_52

или для эквивалентного случая, который вы идентифицируете:

-arch=compute_30 -code=sm_52

то да, это означает, что:

  • Временный код PTX будет создан из вашего исходного кода, и он будет использовать cc3.0 PTX.
  • Из этого PTX инструмент ptxas будет генерировать css5.2-совместимый код SASS.
  • Код SASS будет встроен в ваш исполняемый файл.
  • Код PTX будет отброшен.

(Я не уверен, почему вы на самом деле указываете такую ​​комбо, но это законно.)

Если я просто укажу -code = sm_52, что тогда произойдет? Будет введен только машинный код для V5.2, который был создан из кода V5.2 PTX? И какова будет разница с -code = compute_52?

-code=sm_52 будет генерировать код cc5.2 SASS из промежуточного кода PTX. Код SASS будет встроен, PTX будет отброшен. Обратите внимание, что указание этого параметра самостоятельно в этой форме без опции -arch было бы незаконным. (1)

-code=compute_52 будет генерировать код cc5.x PTX (только) и вставлять этот PTX в исполняемый/двоичный файл. Обратите внимание, что указание этого параметра самостоятельно в этой форме без опции -arch было бы незаконным. (1)

Инструмент cuobjdump