一些相关的问题/答案在这里和这里。
我仍然不确定在使用 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
那么是的,这意味着:
- 将从您的源代码生成一个临时 PTX 代码,它将使用 cc3.0 PTX。
- 从该 PTX,该
ptxas
工具将生成符合 cc5.2 的 SASS 代码。
- SASS 代码将嵌入到您的可执行文件中。
- 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