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

bwe*_*ber 32 cuda nvcc fat-binaries ptx

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

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

该文档指出了-arch指定为其编译输入文件的虚拟体系结构.但是,此PTX代码不会自动编译为机器代码,但这是一个"预处理步骤".

现在,-code应该指定汇编和优化PTX代码的架构.

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

如果我只是说明-code=sm_52会发生什么呢?只嵌入V5.2的机器代码是用V5.2 PTX代码创建的?那有什么区别-code=compute_52

Rob*_*lla 30

一些相关的问题/答案在这里这里.

在使用nvcc构建时,我仍然不确定如何正确指定代码生成的体系结构.

完整的描述有点复杂,但有一些相对简单,易于记忆的规范用法.编译体系结构(虚拟和真实),代表您希望定位的GPU.一个相当简单的形式是:

-gencode arch=compute_XX,code=sm_XX
Run Code Online (Sandbox Code Playgroud)

其中XX是您希望定位的GPU的两位数计算能力.如果您希望定位多个GPU,只需重复每个XX目标的整个序列.这大致是CUDA示例代码项目采用的方法.(如果您想在可执行文件中包含PTX,请添加一个附加选项,指定-gencode与该code选项相同的PTX虚拟体系结构arch).

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

-arch=sm_XX 
Run Code Online (Sandbox Code Playgroud)

与XX相同的描述.此表单将包括指定体系结构的SASS和PTX.

现在,除了两个编译器标志之外,还有两种指定体系结构的方法:sm_XX和compute_XX,其中compute_XX表示虚拟,sm_XX表示真实体系结构.flag -arch只接受虚拟体系结构的标识符(例如compute_XX),而-code标记接受真实体系结构和虚拟体系结构的标识符.

这基本上是正确的,当archcode被用作交换机内的子-gencode交换机时,或者两者一起使用时,如您所描述的那样独立使用.但是,例如,当-arch它自己使用(没有-code)时,它代表另一种"速记"符号,在这种情况下,你可以传递一个真实的架构,例如-arch=sm_52

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

嵌入内容的确切定义取决于使用形式.但是对于这个例子:

-gencode arch=compute_30,code=sm_52
Run Code Online (Sandbox Code Playgroud)

或者您确定的同等情况:

-arch=compute_30 -code=sm_52
Run Code Online (Sandbox Code Playgroud)

然后是的,这意味着:

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

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

如果我只是指定-code = sm_52会发生什么呢?只嵌入V5.2的机器代码是用V5.2 PTX代码创建的?那么-code = compute_52会有什么不同?

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

-code=compute_52将生成cc5.x PTX代码(仅)并将该PTX嵌入可执行文件/二进制文件中.请注意,在此表单中-arch单独指定此选项(没有选项)将是非法的.(1)

cuobjdump 工具可用于识别给定二进制文件中的确切组件.

(1)如果没有使用-gencode开关,并且没有使用-arch开关,则nvcc假定-arch=sm_20编译命令附加了一个默认值(这适用于CUDA 7.5,默认-arch设置可能因CUDA版本而异). sm_20是一个真正的体系结构,当提供选项时,在选项上指定真实体系结构是不合法的.-arch-code

  • 当我第一次想清楚如何最好地使用这些标志时,我使用了`cuobjdump --dump-ptx`和`cuobjdump --dump-sass`来检查SASS(二进制机器码)和PTX的版本(中级架构不可知代码)被发送到目标文件中。我建议向其他人动手实践。实际上,要生成支持多种体系结构的可执行文件,您可能希望为每种体系结构都包括SASS,并且仅对*最新体系结构*(对于潜在的将来GPU上的JIT编译)包括PTX。 (2认同)