在Nvidia的NVCC编译器中使用多个“拱”标志的目的是什么?

我最近开始讨论NVCC如何为不同的计算架构编译CUDA设备代码。

根据我的理解,当使用NVCC的-gencode选项时,“arch”是程序员应用程序所需的最小计算体系结构,也是NVCC的JIT编译器编译PTX代码的最小设备计算体系结构。

我也明白,-gencode的“code”参数是NVCC完全编译应用程序的计算体系结构,因此不需要JIT编译。

经过对各种CUDA项目Makefiles的检查,我发现定期发生以下情况:

-gencode arch=compute_20,code=sm_20 -gencode arch=compute_20,code=sm_21 -gencode arch=compute_21,code=sm_21 

经过一番阅读后,我发现可以在一个二进制文件中编译多个设备体系结构 – 在本例中为sm_20,sm_21。

我的问题是为什么有这么多的拱/码对是必要的? 以上是否使用了“拱”的所有值?

有什么区别和说:

 -arch compute_20 -code sm_20 -code sm_21 

自动select“拱”字段中最早的虚拟体系结构还是存在一些其他模糊的行为?

有没有其他编译和运行时行为,我应该知道的?

我已阅读手册, http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#gpu-compilation ,我仍然不清楚在编译或运行时会发生什么。

干杯,

詹姆士。

粗略地说,代码编译stream程如下所示:

CUDA C / C ++设备代码源 – > PTX – > SASS

虚拟体系结构(例如, compute_20 ,无论由compute_20 -arch compute...指定什么)确定将生成什么types​​的PTX代码。 额外的开关(例如, -code sm_21 )确定将生成什么types​​的SASS代码。 SASS实际上是GPU(机器语言)的可执行目标代码。 一个可执行文件可以包含SASS和/或PTX的多个版本,并且有一个运行时加载器机制,可以根据实际使用的GPUselect合适的版本。

正如你指出的那样,GPU操作的便捷特性之一就是JIT编译。 JIT编译将由GPU驱动程序完成(不需要安装CUDA工具包),只要合适的PTX代码可用,但合适的SASS代码不可用。

包括多个虚拟体系结构(即PTX的多个版本)的一个优点是,您可以与更广泛的目标GPU设备执行兼容性(尽pipe某些设备可能会触发JIT编译来创build必要的SASS)。

包含多个“真实GPU目标”(即多个SASS版本)的一个优点是,当存在其中一个目标设备时,可以避免JIT编译步骤。

如果您指定了一组错误的选项,则可以创build一个不会在特定GPU上正确运行的可执行文件。

指定很多这些选项的一个可能的缺点是代码大小膨胀。 另一个可能的缺点是编译时间,通常会更长,因为您指定了更多的选项。

也可以创build不包含PTX的可改变的字符,这可能是那些试图掩盖其IP的人感兴趣的。

创build适合于JIT的PTX应该通过指定 code开关的虚拟体系结构来完成。

多元标志的用途是将__CUDA_ARCH__macros用于条件编译(即使用#ifdef )不同优化的代码path。

看到这里: http : //docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#virtual-architecture-identification-macro