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

时间:2013-07-11 16:54:31

标签: cuda nvcc ptx

我最近了解了NVCC如何为不同的计算架构编译CUDA设备代码。

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

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

在检查了各种CUDA项目Makefile之后,我注意到以下情况经常发生:

-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 / code对?上面是否使用了“arch”的所有值?

它之间的区别是什么:

-arch compute_20
-code sm_20
-code sm_21

“arch”字段中最早的虚拟架构是自动选择还是存在其他一些模糊的行为?

我应该注意其他任何编译和运行时行为吗?

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

2 个答案:

答案 0 :(得分:39)

粗略地说,代码编译流程如下:

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

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

正如您所指出的,GPU操作的一个便利功能是JIT编译。 JIT-compile将由GPU驱动程序完成(不需要安装CUDA工具包),只要有合适的PTX代码,但不适合的SASS代码。

包含多个虚拟体系结构(即多个版本的PTX)的一个优点是,您可以与更多种类的目标GPU设备兼容(尽管某些设备可能会触发JIT编译以创建必要的SASS)

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

如果指定了一组错误的选项,则可以创建一个无法在特定GPU上正常运行的可执行文件。

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

也可以创建不包含PTX的excutable,这可能是那些试图掩盖其IP的人感兴趣的。

创建适合JIT的PTX应由specifying a virtual architecture code开关。

答案 1 :(得分:2)

多个-arch标志的目的是使用__CUDA_ARCH__宏进行条件编译(即使用#ifdef)不同优化的代码路径。

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