CUDA 应用程序的 NVIDIA Ada GPU 架构兼容性指南
构建用于 NVIDIA Ada GPU 的 CUDA 应用程序指南。
1. NVIDIA Ada GPU 架构兼容性
1.1. 关于本文档
本应用说明,CUDA 应用程序的 NVIDIA Ada GPU 架构兼容性指南,旨在帮助开发人员确保他们的 NVIDIA® CUDA® 应用程序可以在基于 NVIDIA® Ada 架构的 GPU 上运行。本文档为熟悉 CUDA C++ 编程并希望确保其软件应用程序与 NVIDIA Ada GPU 架构兼容的开发人员提供指导。
1.2. NVIDIA Ada GPU 架构上的应用程序兼容性
CUDA 应用程序二进制文件(带有一个或多个 GPU 内核)可以包含两种形式的已编译 GPU 代码:二进制 cubin 对象和前向兼容的 PTX 汇编代码,每种内核各一份。cubin 和 PTX 都是为特定的目标计算能力生成的。为特定计算能力生成的 cubin 支持在任何具有相同主修订版和相同或更高次修订版计算能力的 GPU 上运行。例如,为计算能力 8.6 生成的 cubin 支持在计算能力为 8.9 的 GPU 上运行;但是,为计算能力 8.9 生成的 cubin 不 支持在计算能力为 8.6 的 GPU 上运行,并且为计算能力 8.x 生成的 cubin 不 支持在计算能力为 9.0 的 GPU 上运行。
内核也可以编译为 PTX 形式。在应用程序加载时,PTX 被编译为 cubin,然后 cubin 用于内核执行。与 cubin 不同,PTX 是前向兼容的。这意味着 PTX 支持在任何计算能力高于为生成该 PTX 而假设的计算能力的 GPU 上运行。例如,为计算能力 8.x 生成的 PTX 代码支持在计算能力 8.x 或任何更高版本(主版本或次版本)上运行,包括计算能力 9.x。因此,尽管是可选的,但建议所有应用程序都应包含内核的 PTX,以确保前向兼容性。 要了解有关 cubin 和 PTX 兼容性的更多信息,请参阅 CUDA C++ 编程指南 中的 使用 NVCC 进行编译。
当 CUDA 应用程序在 GPU 上启动内核时,CUDA 运行时会确定系统中 GPU 的计算能力,并使用此信息来查找内核的最佳匹配 cubin 或 PTX 版本。如果二进制文件中存在与该 GPU 兼容的 cubin,则直接使用该 cubin 进行执行。否则,CUDA 运行时首先通过 JIT 编译 1 PTX 生成兼容的 cubin,然后使用该 cubin 进行执行。如果既没有兼容的 cubin 也没有 PTX 可用,则内核启动将失败。
包含内核 PTX 版本的应用程序二进制文件应在基于 NVIDIA Ada 架构的 GPU 上按原样工作。在这种情况下,不需要重建应用程序。但是,不包含 PTX(仅包含 cubin)的应用程序二进制文件需要重建才能在基于 NVIDIA Ada 架构的 GPU 上运行。要了解有关构建兼容应用程序的更多信息,请阅读 构建支持 NVIDIA Ada GPU 架构的应用程序。
1.3. Ampere 和 Ada 之间的兼容性
NVIDIA Ada 架构基于 Ampere 的指令集架构 ISA 8.0,并使用新指令对其进行了扩展。因此,任何在 Ampere 上运行的二进制文件都可以在 Ada 上运行(前向兼容性),但 Ada 二进制文件将无法在 Ampere 上运行。
1.4. 验证现有应用程序的 Ada 兼容性
使 CUDA 应用程序与 NVIDIA Ada GPU 架构兼容的第一步是检查应用程序二进制文件是否已包含兼容的 GPU 代码(至少是 PTX)。以下部分说明了如何为已构建的 CUDA 应用程序完成此操作。
1.4.1. 使用 CUDA Toolkit 10.2 或更早版本构建的应用程序
使用 CUDA Toolkit 2.1 到 10.2 版本构建的 CUDA 应用程序与基于 NVIDIA Ada 架构的 GPU 兼容,只要它们构建为包含内核的 PTX 版本。这可以通过强制 PTX 在应用程序加载时使用以下步骤进行 JIT 编译来测试
从 https://www.nvidia.com/drivers 下载并安装最新的驱动程序。
设置环境变量
CUDA_FORCE_PTX_JIT=1
。启动应用程序。
使用 CUDA_FORCE_PTX_JIT=1
,应用程序二进制文件中嵌入的 GPU 二进制代码将被忽略。而是将每个内核的 PTX 代码 JIT 编译以生成 GPU 二进制代码。如果应用程序不包含 PTX,则应用程序执行失败。这意味着该应用程序与 NVIDIA Ada GPU 架构不兼容,需要重建以实现兼容性。另一方面,如果应用程序在此环境变量设置的情况下正常工作,则该应用程序与 NVIDIA Ada GPU 架构兼容。
注意
请务必在测试完成后取消设置 CUDA_FORCE_PTX_JIT
环境变量。
1.4.2. 使用 CUDA Toolkit 11.0 至 11.7 构建的应用程序
使用 CUDA Toolkit 11.0 至 11.7 构建的 CUDA 应用程序与 NVIDIA Ada GPU 架构兼容,只要它们构建为包含 Ampere 原生 cubin(参见 Ampere 和 Ada 之间的兼容性)或 PTX 格式(参见 使用 CUDA Toolkit 10.2 或更早版本构建的应用程序)的内核,或两者都包含。
1.4.3. 使用 CUDA Toolkit 11.8 构建的应用程序
使用 CUDA Toolkit 11.8 构建的 CUDA 应用程序与 NVIDIA Ada GPU 架构兼容,只要它们构建为包含 Ampere 原生或 Ada 原生 cubin(参见 Ampere 和 Ada 之间的兼容性)或 PTX 格式(参见 使用 CUDA Toolkit 10.2 或更早版本构建的应用程序)的内核,或两者都包含。
1.5. 构建支持 NVIDIA Ada GPU 架构的应用程序
根据用于构建应用程序的 CUDA Toolkit 版本,可以构建它以包含 NVIDIA Ada GPU 架构的 PTX 和/或原生 cubin。虽然仅包含 PTX 就足够了,但包含原生 cubin 也具有以下优点
它可以为最终用户节省 JIT 编译仅作为 PTX 提供的内核所需的时间。所有没有原生 cubin 的内核都从 PTX 进行 JIT 编译,包括链接到应用程序的所有库中的内核,即使这些内核永远不会被应用程序启动。特别是当使用大型库时,这种 JIT 编译可能需要大量时间。CUDA 驱动程序会缓存作为 PTX JIT 结果生成的 cubin,因此这主要是用户的一次性成本,但最好尽可能避免这种情况。
PTX JIT 编译的内核通常无法利用较新 GPU 的架构特性,这意味着原生编译的 cubin 可能会更快或更准确。
1.5.1. 使用 CUDA Toolkit 10.x 或更早版本构建应用程序
CUDA Toolkit 10.x 版本(10.0、10.1 和 10.2)中包含的 nvcc
编译器可以生成 Volta 和 Turing 架构(计算能力 7.x)的原生 cubin。当使用 CUDA Toolkit 10.x 时,为了确保 nvcc
将为所有最新的 GPU 架构生成 cubin 文件,并为与未来 GPU 架构的前向兼容性生成 PTX 版本,请在 nvcc
命令行上指定适当的 -gencode=
参数,如下例所示。
Windows
nvcc.exe -ccbin "C:\vs2010\VC\bin"
-Xcompiler "/EHsc /W3 /nologo /O2 /Zi /MT"
-gencode=arch=compute_60,code=sm_60
-gencode=arch=compute_61,code=sm_61
-gencode=arch=compute_70,code=sm_70
-gencode=arch=compute_75,code=sm_75
-gencode=arch=compute_75,code=compute_75
--compile -o "Release\mykernel.cu.obj" "mykernel.cu"
Mac/Linux
/usr/local/cuda/bin/nvcc
-gencode=arch=compute_60,code=sm_60
-gencode=arch=compute_61,code=sm_61
-gencode=arch=compute_70,code=sm_70
-gencode=arch=compute_75,code=sm_75
-gencode=arch=compute_75,code=compute_75
-O2 -o mykernel.o -c mykernel.cu
或者,可以使用简化的 nvcc
命令行选项 -arch=sm_XX
。它是上面使用的更明确的 -gencode=
命令行选项的简写等效项。-arch=sm_XX
扩展为以下内容
-gencode=arch=compute_XX,code=sm_XX
-gencode=arch=compute_XX,code=compute_XX
但是,虽然 -arch=sm_XX
命令行选项确实默认包含 PTX 后端目标二进制文件,但它一次只能指定一个目标 cubin 架构,并且不可能在同一 nvcc
命令行上使用多个 -arch=
选项,这就是为什么上面的示例显式使用 -gencode=
的原因。
对于 10.0 之前的 CUDA 工具包,需要根据特定工具包版本支持的架构删除一个或多个 -gencode
选项(例如,CUDA 工具包 9.x 支持高达 _60 和 _61 的架构)。还需要更新用于生成 PTX 的最终 -gencode
。有关更多信息和示例,请参阅特定 CUDA 工具包版本的文档。
注意
compute_XX
指的是 PTX 版本,sm_XX
指的是 cubin 版本。-gencode=
命令行选项的 arch=
子句到 nvcc
指定前端编译目标,并且必须始终是 PTX 版本。code=
子句指定后端编译目标,可以是 cubin 或 PTX,或两者兼有。只有 code=
子句指定的后端目标版本将保留在生成的二进制文件中;至少应有一个是 PTX,以提供与未来架构的兼容性。
1.5.2. 使用 CUDA Toolkit 11.0 至 11.7 构建应用程序
CUDA Toolkit 11.0 至 11.7 版本中包含的 nvcc
编译器可以生成 Ampere 架构(计算能力 8.0 和 8.6)的原生 cubin。当使用 CUDA Toolkit 11.0 至 11.7 时,为了确保 nvcc
将为所有最新的 GPU 架构生成 cubin 文件,并为与未来 GPU 架构的前向兼容性生成 PTX 版本,请在 nvcc
命令行上指定适当的 -gencode=
参数,如下例所示。
Windows
nvcc.exe -ccbin "C:\vs2010\VC\bin"
-Xcompiler "/EHsc /W3 /nologo /O2 /Zi /MT"
-gencode=arch=compute_60,code=sm_60
-gencode=arch=compute_61,code=sm_61
-gencode=arch=compute_70,code=sm_70
-gencode=arch=compute_75,code=sm_75
-gencode=arch=compute_80,code=sm_80
-gencode=arch=compute_86,code=sm_86
-gencode=arch=compute_86,code=compute_86
--compile -o "Release\mykernel.cu.obj" "mykernel.cu"
Mac/Linux
/usr/local/cuda/bin/nvcc
-gencode=arch=compute_60,code=sm_60
-gencode=arch=compute_61,code=sm_61
-gencode=arch=compute_70,code=sm_70
-gencode=arch=compute_75,code=sm_75
-gencode=arch=compute_80,code=sm_80
-gencode=arch=compute_86,code=sm_86
-gencode=arch=compute_86,code=compute_86
-O2 -o mykernel.o -c mykernel.cu
或者,可以使用简化的 nvcc
命令行选项 -arch=sm_XX
。它是上面使用的更明确的 -gencode=
命令行选项的简写等效项。-arch=sm_XX
扩展为以下内容
-gencode=arch=compute_XX,code=sm_XX
-gencode=arch=compute_XX,code=compute_XX
但是,虽然 -arch=sm_XX
命令行选项确实默认包含 PTX 后端目标二进制文件,但它一次只能指定一个目标 cubin 架构,并且不可能在同一 nvcc
命令行上使用多个 -arch=
选项,这就是为什么上面的示例显式使用 -gencode=
的原因。
对于 11.0 之前的 CUDA 工具包,需要根据特定工具包版本支持的架构删除一个或多个 -gencode
选项(例如,CUDA 工具包 10.x 支持高达 _72 和 _75 的架构)。还需要更新用于生成 PTX 的最终 -gencode
。有关更多信息和示例,请参阅特定 CUDA 工具包版本的文档。
注意
compute_XX
指的是 PTX 版本,sm_XX
指的是 cubin 版本。-gencode=
命令行选项的 arch=
子句到 nvcc
指定前端编译目标,并且必须始终是 PTX 版本。code=
子句指定后端编译目标,可以是 cubin 或 PTX,或两者兼有。只有 code=
子句指定的后端目标版本将保留在生成的二进制文件中;至少应有一个是 PTX,以提供与未来架构的兼容性。
1.5.3. 使用 CUDA Toolkit 11.8 构建应用程序
使用 CUDA Toolkit 11.8 版本,nvcc
可以生成 NVIDIA Ada GPU 架构(计算能力 8.9)的原生 cubin。当使用 CUDA Toolkit 11.8 时,为了确保 nvcc
将为所有最新的 GPU 架构生成 cubin 文件,并为与未来 GPU 架构的前向兼容性生成 PTX 版本,请在 nvcc
命令行上指定适当的 -gencode=
参数,如下例所示。
Windows
nvcc.exe -ccbin "C:\vs2010\VC\bin"
-Xcompiler "/EHsc /W3 /nologo /O2 /Zi /MT"
-gencode=arch=compute_60,code=sm_60
-gencode=arch=compute_61,code=sm_61
-gencode=arch=compute_70,code=sm_70
-gencode=arch=compute_75,code=sm_75
-gencode=arch=compute_80,code=sm_80
-gencode=arch=compute_86,code=sm_86
-gencode=arch=compute_89,code=sm_89
-gencode=arch=compute_89,code=compute_89
--compile -o "Release\mykernel.cu.obj" "mykernel.cu"
Mac/Linux
/usr/local/cuda/bin/nvcc
-gencode=arch=compute_60,code=sm_60
-gencode=arch=compute_61,code=sm_61
-gencode=arch=compute_70,code=sm_70
-gencode=arch=compute_75,code=sm_75
-gencode=arch=compute_80,code=sm_80
-gencode=arch=compute_86,code=sm_86
-gencode=arch=compute_89,code=sm_89
-gencode=arch=compute_89,code=compute_89
-O2 -o mykernel.o -c mykernel.cu
注意
compute_XX
指的是 PTX 版本,sm_XX
指的是 cubin 版本。-gencode=
命令行选项的 arch=
子句到 nvcc
指定前端编译目标,并且必须始终是 PTX 版本。code=
子句指定后端编译目标,可以是 cubin 或 PTX,或两者兼有。只有 code=
子句指定的后端目标版本将保留在生成的二进制文件中;至少应有一个是 PTX,以提供与未来架构的兼容性。
1.5.4. 独立线程调度兼容性
自 Volta 架构以来的 NVIDIA GPU 在 Warp 中的线程之间具有独立线程调度。如果开发人员对 Warp 同步性2 做出假设,则此功能可能会改变与以前架构相比参与执行代码的线程集。有关详细信息和纠正措施,请参阅 CUDA C++ 编程指南 中的 计算能力 7.x。为了帮助迁移到 NVIDIA Ada GPU 架构,开发人员可以选择使用以下编译器选项组合来选择 Pascal 调度模型。
nvcc -gencode=arch=compute_60,code=sm_89 ...
2. 修订历史
版本 1.0
初始公开发布。
3. 通知
3.1. 通知
本文档仅供参考,不应视为对产品的特定功能、条件或质量的保证。NVIDIA Corporation(“NVIDIA”)对本文档中包含的信息的准确性或完整性不作任何明示或暗示的陈述或保证,并且对本文档中包含的任何错误不承担任何责任。NVIDIA 对使用此类信息或因使用此类信息而可能导致的侵犯第三方专利或其他权利的行为不承担任何责任。本文档不构成对开发、发布或交付任何材料(如下定义)、代码或功能的承诺。
NVIDIA 保留随时修改、增强、改进本文档以及进行任何其他更改的权利,恕不另行通知。
客户在下订单前应获取最新的相关信息,并应验证此类信息是否为最新且完整。
NVIDIA 产品根据 NVIDIA 标准销售条款和条件销售,这些条款和条件在订单确认时提供,除非 NVIDIA 和客户的授权代表签署的单独销售协议(“销售条款”)另有约定。NVIDIA 在此明确反对将任何客户通用条款和条件应用于购买本文档中引用的 NVIDIA 产品。本文档不直接或间接地形成任何合同义务。
NVIDIA 产品并非设计、授权或保证适用于医疗、军事、航空、航天或生命支持设备,也不适用于 NVIDIA 产品的故障或故障可能合理预期会导致人身伤害、死亡或财产或环境损害的应用。NVIDIA 对在上述设备或应用中包含和/或使用 NVIDIA 产品不承担任何责任,因此,此类包含和/或使用由客户自行承担风险。
NVIDIA 不保证或声明基于本文档的产品将适用于任何特定用途。NVIDIA 不一定会对每个产品的所有参数进行测试。客户全权负责评估和确定本文档中包含的任何信息的适用性,确保产品适合客户计划的应用和用途,并为该应用执行必要的测试,以避免应用或产品的默认设置。客户产品设计中的缺陷可能会影响 NVIDIA 产品的质量和可靠性,并可能导致超出本文档中包含的其他或不同的条件和/或要求。NVIDIA 对可能基于或归因于以下原因的任何默认设置、损坏、成本或问题不承担任何责任:(i)以任何违反本文档的方式使用 NVIDIA 产品;或(ii)客户产品设计。
本文档未授予任何 NVIDIA 专利权、版权或其他 NVIDIA 知识产权的明示或暗示许可。NVIDIA 发布的有关第三方产品或服务的信息不构成 NVIDIA 授予使用此类产品或服务的许可,也不构成对其的保证或认可。使用此类信息可能需要获得第三方的专利或其他知识产权的许可,或者获得 NVIDIA 的专利或其他知识产权的许可。
只有在事先获得 NVIDIA 书面批准的情况下,才允许复制本文档中的信息,并且复制必须未经修改且完全符合所有适用的出口法律和法规,并附带所有相关的条件、限制和通知。
本文档和所有 NVIDIA 设计规范、参考板、文件、图纸、诊断程序、列表和其他文档(统称为“材料”)均按“原样”提供。NVIDIA 对这些材料不作任何明示、暗示、法定或其他形式的保证,并明确声明不承担所有关于不侵权、适销性和特定用途适用性的暗示保证。在法律未禁止的范围内,在任何情况下,NVIDIA 均不对任何损害(包括但不限于任何直接、间接、特殊、偶然、惩罚性或后果性损害,无论因何种原因引起,也无论责任理论如何)承担责任,即使 NVIDIA 已被告知可能发生此类损害。尽管客户可能因任何原因而遭受任何损害,但 NVIDIA 对本文所述产品的客户承担的总体和累积责任应根据产品的销售条款进行限制。
3.2. OpenCL
OpenCL 是 Apple Inc. 的商标,已获得 Khronos Group Inc. 的许可使用。
3.3. 商标
NVIDIA 和 NVIDIA 徽标是 NVIDIA Corporation 在美国和其他国家/地区的商标或注册商标。其他公司和产品名称可能是与其相关的各自公司的商标。