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

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

Теперь, в соответствии с этим, помимо двух флагов компилятора, есть также два способа задания архитектур: 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, созданный из кода PTX V5.2? И какая разница -code=compute_52?

1 ответ

Решение

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

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

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

-gencode arch=compute_XX,code=sm_XX

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

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

-arch=sm_XX 

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

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

Это в основном правильно, когда 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

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

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

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

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

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

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

cuobjdump Инструмент может быть использован, чтобы определить, какие именно компоненты находятся в данном двоичном файле.

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

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