CUDA:如何使用-arch 和-code 以及 SM 与 COMPUTE

CUDA: How to use -arch and -code and SM vs COMPUTE

我仍然不确定在使用 nvcc 构建时如何正确指定代码生成的体系结构。我知道我的二进制文件中嵌入了机器代码和 PTX 代码,这可以通过控制器开关 -code-arch(或两者的组合使用 -gencode 来控制).

现在,根据 this 除了两个编译器标志外,还有两种指定体系结构的方法:sm_XXcompute_XX,其中 compute_XX 指的是一个虚拟和 sm_XX 到真实的体系结构。标志 -arch 仅采用虚拟架构的标识符(例如 compute_XX),而 -code 标志采用真实架构和虚拟架构的标识符。

文档指出 -arch 指定了编译输入文件的虚拟体系结构。但是,此 PTX 代码不会自动编译为机器代码,而是 "preprocessing step".

现在,-code 应该指定 PTX 代码针对哪些架构进行组装和优化。

但是,尚不清楚二进制文件中将嵌入哪种 PTX 或二进制代码。例如,如果我指定 -arch=compute_30 -code=sm_52,这是否意味着我的代码将首先编译为功能级别 3.0 PTX,之后将创建功能级别 5.2 的机器代码?将嵌入什么?

如果我只指定-code=sm_52会发生什么?仅嵌入由 V5.2 PTX 代码创建的 V5.2 机器代码? -code=compute_52 有什么区别?

一些相关的 questions/answers 是 here and here

I am still not sure how to properly specify the architectures for code generation when building with nvcc.

完整的描述有些复杂,但旨在提供相对简单、易于记忆的规范用法。针对代表您希望定位的 GPU 的架构(虚拟和真实)进行编译。一个相当简单的形式是:

-gencode arch=compute_XX,code=sm_XX

其中 XX 是您希望定位的 GPU 的两位数计算能力。如果您希望以多个 GPU 为目标,只需为每个 XX 目标重复整个序列。这大约是 CUDA 示例代码项目采用的方法。 (如果您想在可执行文件中包含 PTX,请包含一个额外的 -gencodecode 选项,指定与 arch 选项相同的 PTX 虚拟架构。

另一种相当简单的形式,当只针对单个 GPU 时,只需使用:

-arch=sm_XX 

与 XX 的描述相同。此表单将包括指定架构的 SASS 和 PTX。

Now, according to this apart from the two compiler flags there are also two ways of specifying architectures: sm_XX and compute_XX, where compute_XX refers to a virtual and sm_XX to a real architecture. The flag -arch only takes identifiers for virtual architectures (such as compute_XX) whereas the -code flag takes both, identifiers for real and for virtual architectures.

archcode作为-gencode开关中的子开关,或者两者一起使用时,基本正确,正如您所描述的那样独立。但是,例如,当 -arch 被单独使用时(没有 -code),它代表另一种 "shorthand" 符号,在这种情况下,你可以通过一个真实的架构,例如-arch=sm_52

However, it is not clear which PTX or binary code will be embedded in the binary. If I specify for example -arch=compute_30 -code=sm_52, does that mean my code will first be compiled to feature level 3.0 PTX from which afterwards machine code for feature level 5.2 will be created from? And what will be embedded?

嵌入内容的确切定义因使用形式而异。但是对于这个例子:

-gencode arch=compute_30,code=sm_52

或您确定的等效案例:

-arch=compute_30 -code=sm_52

那么是的,意思是:

  1. 将从您的源代码生成临时 PTX 代码,它将使用 cc3.0 PTX。
  2. 从那个 PTX,ptxas 工具将生成符合 cc5.2 的 SASS 代码。
  3. SASS 代码将嵌入到您的可执行文件中。
  4. PTX 代码将被丢弃。

(我不确定你为什么要指定这样的组合,但这是合法的。)

If I just specify -code=sm_52 what will happen then? Only machine code for V5.2 will be embedded that has been created out of V5.2 PTX code? And what would be the difference to -code=compute_52?

-code=sm_52 将从中间 PTX 代码生成 cc5.2 SASS 代码。 SASS 代码将被嵌入,PTX 将被丢弃。请注意,在没有 -arch 选项的情况下,以这种形式单独指定此选项是非法的。 (1)

-code=compute_52 将生成 cc5.x PTX 代码(仅)并将该 PTX 嵌入 executable/binary。请注意,在没有 -arch 选项的情况下,以这种形式单独指定此选项是非法的。 (1)

cuobjdump tool 可用于识别给定二进制文件中的确切组件。

(1) 当未使用 -gencode 开关且未使用 -arch 开关时,nvcc 假定默认值 -arch=sm_20 附加到您的编译命令(这是针对 CUDA 7.5 的,默认 -arch 设置可能因 CUDA 版本而异)。 sm_20real 架构,在 -arch 选项上指定 real 架构是不合法的-code 还提供了选项。