在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