一些相关的问题/答案是here and here.
我仍然不确定在使用 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
and 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 PTX 代码创建的 V5.2 机器代码?与 -code=compute_52 有什么区别?
-code=sm_52
将从中间 PTX 代码生成 cc5.2 SASS 代码。 SASS 代码将被嵌入,PTX 将被丢弃。请注意,以这种形式单独指定该选项,没有-arch
选项,将是非法的。 (1)
-code=compute_52
将(仅)生成 cc5.x PTX 代码并将该 PTX 嵌入到可执行文件/二进制文件中。请注意,以这种形式单独指定该选项,没有-arch
选项,将是非法的。 (1)
The cuobjdump
tool可用于识别给定二进制文件中到底包含哪些组件。
(1) 当没有-gencode
使用开关,并且没有-arch
使用开关,nvcc
假设默认值-arch=sm_20
附加到您的编译命令(这是针对 CUDA 7.5,默认值-arch
设置可能因 CUDA 版本而异)。sm_20
is a real架构,并且指定一个是不合法的real建筑学上的-arch
当一个选项-code
还提供了选项。