用于生成最佳代码的 NVCC 编译选项(使用 JIT)

Posted

技术标签:

【中文标题】用于生成最佳代码的 NVCC 编译选项(使用 JIT)【英文标题】:NVCC compilation options for generating the best code (using JIT) 【发布时间】:2014-05-30 08:11:54 【问题描述】:

我试图了解 nvcc 编译阶段,但我有点困惑。因为我不知道将运行我的软件的机器的确切硬件配置,所以我想使用 JIT 编译功能为它生成最好的代码。在 NVCC 文档中我发现了这个:

“例如,当应用程序在 sm_10、sm_13 甚至更高的架构上启动时,以下命令允许生成完全匹配的 GPU 二进制代码:”

nvcc x.cu -arch=compute_10 -code=compute_10

所以我的理解是,上述选项将为当前 GPU 生成最佳/最快/最佳代码。那是对的吗?我还读到默认的 nvcc 选项是:

nvcc x.cu –arch=compute_10 -code=sm_10,compute_10

如果以上确实正确,为什么我不能在我的应用程序中使用任何 compute_20 功能?

【问题讨论】:

【参考方案1】:

当您指定目标架构时,您将自己限制在该架构中可用的功能上。这是因为 PTX 代码是虚拟汇编代码,因此您需要了解 PTX 生成期间可用的功能。 PTX 将被 JIT 编译为您正在运行的任何 GPU 的 GPU 二进制代码 (SASS),但它不能针对较新的架构功能。

我建议您选择一个最低架构(例如,如果您想要双精度,则为 1.3,如果您想要 Fermi 或更高版本的功能,则为 2.0),然后为该架构和更新的基础架构创建 PTX。您可以在一个命令中执行此操作(尽管需要更长时间,因为它需要多次通过代码)并将所有内容捆绑到一个胖二进制文件中。

一个示例命令行可能是:

nvcc <general options> <filename.cu> \
    -gencode arch=compute_13,code=compute_13 \
    -gencode arch=compute_20,code=compute_20 \
    -gencode arch=compute_30,code=compute_30 \
    -gencode arch=compute_35,code=compute_35

这将在二进制文件中创建四个 PTX 版本。您还可以同时编译到选定的 GPU,这样可以避免用户的 JIT 编译时间,但也会增加二进制文件的大小。

查看NVCC manual了解更多信息。

【讨论】:

运行胖二进制可执行文件时使用哪个 PTX 版本? 这取决于您运行的 GPU 架构。它将选择兼容的最新 PTX。这个答案已经有 5 年历史了,如果您要在 Volta 或 Turing 一代 GPU 上使用该命令,那么它将采用 compute_35 PTX 和 JIT 将其编译到当前 GPU。 谢谢。它会在每次内核启动时做出这个决定吗? 不,不需要。一旦它为当前的 GPU 进行了 JIT 编译,它就会将其保存在缓存中,并在您再次启动内核时重用已编译的版本。有关缓存存储位置的信息(CUDA_​CACHE_​PATH 变量),请参阅docs.nvidia.com/cuda/cuda-c-programming-guide/…。

以上是关于用于生成最佳代码的 NVCC 编译选项(使用 JIT)的主要内容,如果未能解决你的问题,请参考以下文章

CUDA nvcc慢主机代码

CUDA compiler driver nvcc 散点

如何在没有 nvcc 的情况下在编译时获取 CUDA 工具包版本?

为 CPU 编译 cuda 代码

如何配置 mex 以将编译器标志传递给 nvcc

Visual Studio 是不是使用 nvcc 编译 cuda 代码?