43

我仍然不确定在使用 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

4

1 回答 1

38

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

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

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

-gencode arch=compute_XX,code=sm_XX

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

当仅针对单个 GPU 时,另一种相当简单的形式就是使用:

-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,这是否意味着我的代码将首先编译为功能级别 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 代码将被丢弃。

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

如果我只指定 -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

于 2016-02-26T16:54:54.670 回答