【问题标题】:What is the purpose of using multiple "arch" flags in Nvidia's NVCC compiler?在 Nvidia 的 NVCC 编译器中使用多个“arch”标志的目的是什么?
【发布时间】:2013-07-10 01:37:52
【问题描述】:

我最近开始了解 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”的值都是用的吗?

那和说有什么区别:

-arch compute_20
-code sm_20
-code sm_21

“arch”字段中最早的虚拟架构是自动选择的,还是有其他一些晦涩的行为?

还有其他我应该注意的编译和运行时行为吗?

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

【问题讨论】:

    标签: cuda nvcc ptx


    【解决方案1】:

    大致来说,代码编译流程是这样的:

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

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

    正如您所指出的,GPU 操作的便利功能之一是 JIT 编译。只要有合适的 PTX 代码可用,但没有合适的 SASS 代码,GPU 驱动程序将完成 JIT 编译(不需要安装 CUDA 工具包)。 “合适的 PTX”代码的定义是在数值上等于或低于运行代码的目标 GPU 架构。举个例子,指定arch=compute_30,code=compute_30 会告诉nvcc 在可执行文件中嵌入cc3.0 PTX 代码。此 PTX 代码可用于为 GPU 驱动程序支持的任何未来架构生成 SASS 代码。目前这将包括 Pascal、Volta、Turing 等架构,假设 GPU 驱动程序支持这些架构。

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

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

    如果您指定了一组错误的选项,则可能会创建一个无法在特定 GPU 上(正确)运行的可执行文件。

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

    还可以创建不包含 PTX 的可执行文件,这可能会引起那些试图掩盖其 IP 的人的兴趣。

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

    【讨论】:

    • 对迟到的回复表示歉意,并感谢您的回复。我了解让 PTX 为许多真实架构进行 JIT 编译的目的,但是是否有必要包含所有此类较旧的 PTX 架构,或者仅包含最低规范 PTX?例如,如果我希望代码在尽可能多的 GPU 上运行,我会包括 -arch compute_11、12 13 ... 30、35,还是简单地包括 -arch compute_11?最好的,詹姆斯。
    • 您可以只指定-arch compute_11,然后生成 cc 1.1 PTX 代码。现在和将来的所有 GPU 都应该能够从这个 PTX 版本 JIT 编译为一些有用的机器代码(cc 1.0 设备除外)。但是,通过指定额外的 PTX 版本,您可以通过添加“更新”的 PTX,提供更好地利用更新架构的机会,因此您的代码可能会在 cc3.0 设备上运行得更快,如果您还指定了compute_30。这是代码大小/编译时间和最佳性能之间的权衡。您的里程可能会有所不同。
    • 不幸的是,我上面的评论并不清楚如何生成 PTX。请参考我编辑的答案,以反映如何生成适合 JIT 的 PTX。
    • 有时我看到 arch=compute_xx 后跟 code=compute_xx。这是什么意思?
    • 这意味着您正在请求 nvcc 在可执行对象中嵌入该版本的 PTX(而不是该版本的 SASS)。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2015-04-30
      • 2012-10-15
      • 2011-04-12
      • 2012-01-15
      • 2017-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多