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

时间:2016-02-26 15:59:24

标签: cuda nvcc ptx fat-binaries

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

现在,根据this除了两个编译器标志之外,还有两种指定体系结构的方法: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会有什么不同?

1 个答案:

答案 0 :(得分:25)

一些相关的问题/答案是herehere

  

在使用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。

  

现在,除了两个编译器标志之外,还有两种指定体系结构的方法: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

或您确定的同等情况:

-arch=compute_30 -code=sm_52

然后是的,这意味着:

  1. 将从您的源代码生成临时PTX代码,它将使用cc3.0 PTX。
  2. 从该PTX,ptxas工具将生成符合cc5.2标准的SASS代码。
  3. SASS代码将嵌入您的可执行文件中。
  4. 将丢弃PTX代码。
  5. (我不确定为什么你会真正指定这样的组合,但它是合法的。)

      

    如果我只是指定-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 tool可用于识别给定二进制文件中的确切组件。

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