'code=sm_X' 是只嵌入二进制(cubin)代码,还是 PTX 代码,或者两者都嵌入?

use*_*869 3 cuda nvcc

我对 '-gencode' 语句中的 'code=sm_X' 选项有点困惑。

示例:NVCC 编译器选项有什么作用

-gencode arch=compute_13,code=sm_13
Run Code Online (Sandbox Code Playgroud)

嵌入库中?

只有与CC 1.3,或GPU的机器代码(代码的cubin)与CC 1.3的GPU的PTX代码?

在“Maxwell 兼容性指南”中,声明“只有由 'code=' 子句指定的后端目标版本将保留在生成的二进制文件中”。

由此,我推断给定的编译器选项仅嵌入了带有 CC 1.3 且没有PTX 代码的GPU 的机器代码。这意味着,这将能够运行这个库例如,AA麦克斯韦代卡上,因为是从机器代码可能是“刚刚在时间”(JIT)编译库中没有内嵌代码PTX。

另一方面,在 NVIDIA 的 GTC 2013 演示文稿“作为应用程序构建工具的 CUDA 工具包简介”中,它表示“-gencode arch=compute_13,code=sm_13”对于所有 CC >= 1.3 的 GPU 来说就足够了,并且对于 CC > 1.3 的 GPU 使用此编译器选项,机器代码是从 PTX 代码进行 JIT 化的。因此,在我看来,Maxwell 兼容性指南和 GTC 演示中给出的信息是相互矛盾的。

Rob*_*lla 5

nvcc有许多格式可以指定代码生成选项。阅读nvcc 手册第 6 节可能会有所启发。

使用此格式时:

nvcc -gencode arch=compute_13,code=sm_13 ...
Run Code Online (Sandbox Code Playgroud)

保留 sm_13 (cc 1.3) 设备的 SASS 代码。可执行对象中不会保留 PTX,因此代码只能在能够运行 cc1.3 SASS 的设备上运行。

使用上述命令格式,为了将源代码的 PTX 版本嵌入到可执行对象中,需要使用虚拟架构规范提供给code=.... 由于这种特定格式(使用-gencode)不允许在单个开关中指定多个目标,因此我们必须-gencode多次将开关传递给 nvcc,每个目标都对应一个我们希望嵌入到可执行对象中的目标。

所以扩展上面的例子,我们可以使用以下内容:

nvcc -gencode arch=compute_13,code=sm_13 -gencode arch=compute_13,code=compute_13 ...
Run Code Online (Sandbox Code Playgroud)

这将在可执行文件中嵌入 cc1.3 SASS(通过第一个gencode开关)和 cc1.3 PTX(通过第二个gencode开关)。能够直接运行 cc1.3 SASS 代码的设备将使用它。其他设备(计算能力大于 cc 1.3)将由驱动程序执行 JIT 编译步骤,以将 cc1.3 PTX 代码转换为具有适合相关设备的架构的 SASS 代码。

我同意GTC 2013 演示文稿(例如幻灯片 37)似乎表明

nvcc -gencode arch=compute_13,code=sm_13 ...
Run Code Online (Sandbox Code Playgroud)

足以满足所有计算能力为 1.3 或更高的设备。事实并非如此,这很容易证明。如果您使用上述格式编译代码,并尝试在 cc 2.0 设备上运行它,它将失败并显示与您的代码中的任何内核相关联的“无效设备功能”错误。

同样,nvcc具有用于指定代码生成的各种命令格式和“快捷方式”。一些比较简单的,比如:

nvcc -arch=sm_13 ...
Run Code Online (Sandbox Code Playgroud)

将在可执行对象中嵌入代码的 PTX 和 SASS 版本,从而产生建议的向前兼容性。