CUDA应用程序的Pascal兼容性指南
基于NVIDIA Pascal架构的GPU构建CUDA应用程序指南。
1. 帕斯卡兼容性
1.1. 关于本文档
本应用说明《CUDA应用的Pascal兼容性指南》旨在帮助开发者确保其NVIDIA® CUDA®应用能够在基于NVIDIA® Pascal架构的GPU上运行。本文档为已熟悉CUDA C++编程并希望确保其软件应用与Pascal兼容的开发者提供指导。
1.2. Pascal架构上的应用兼容性
NVIDIA CUDA C++编译器nvcc可用于生成特定架构的cubin文件以及每个内核的前向兼容PTX版本。每个cubin文件针对特定的计算能力版本,并且仅与相同主版本号的GPU架构前向兼容。例如,针对计算能力3.0的cubin文件在所有计算能力3.x(Kepler)设备上受支持,但不支持计算能力5.x(Maxwell)或6.x(Pascal)设备。因此,为确保应用程序发布后与新GPU架构的前向兼容性,建议所有应用程序都包含其内核的PTX版本。
注意
包含针对特定架构的cubin和PTX代码的CUDA Runtime应用程序默认会自动使用cubin,而PTX路径仅保留用于向前兼容目的。
已经包含内核PTX版本的应用程序应该可以直接在基于Pascal架构的GPU上运行。然而,仅通过cubin文件支持特定GPU架构的应用程序需要更新以提供兼容Pascal的PTX或cubin文件。
1.3. 验证现有应用程序的Pascal兼容性
第一步是检查应用程序中是否编译了与Pascal兼容的设备代码(至少包含PTX)。以下部分展示了如何为使用不同CUDA Toolkit版本构建的应用程序实现这一目标。
1.3.1. 使用CUDA Toolkit 7.5或更早版本的应用
使用CUDA Toolkit 2.1至7.5版本构建的CUDA应用程序只要包含内核的PTX版本,就能与Pascal架构兼容。要测试PTX即时编译(JIT)是否适用于您的应用程序,您可以执行以下操作:
从https://www.nvidia.com/drivers下载并安装最新驱动程序。
设置环境变量
CUDA_FORCE_PTX_JIT=1。启动您的应用程序。
当首次使用上述环境标志启动CUDA应用程序时,CUDA驱动程序会将每个使用的CUDA内核的PTX即时编译(JIT-compile)为原生cubin代码。
如果您设置了上述环境变量后启动程序且运行正常,则已成功验证Pascal兼容性。
注意
测试完成后,请确保取消设置CUDA_FORCE_PTX_JIT环境变量。
1.3.2. 使用CUDA Toolkit 8.0的应用程序
使用CUDA Toolkit 8.0构建的CUDA应用程序只要包含Pascal原生cubin格式的内核(参见构建支持Pascal的应用程序)或PTX格式的内核(参见使用CUDA Toolkit 7.5或更早版本的应用程序),或同时包含这两种格式,就能与Pascal架构兼容。
1.4. 使用Pascal支持构建应用程序
当CUDA应用程序启动内核时,CUDA运行时会检测系统中每个GPU的计算能力,并利用该信息自动寻找可用的最佳匹配cubin或PTX版本内核。如果存在支持目标GPU架构的cubin文件,则直接使用;否则,CUDA运行时会加载PTX,并在启动前将其即时编译(JIT)为GPU原生的cubin格式。若两者均不可用,则内核启动将失败。
用于构建应用程序的方法,无论是原生cubin还是至少对Pascal架构的PTX支持,取决于所使用的CUDA Toolkit版本。
提供原生cubin的主要优势如下:
它节省了终端用户即时编译仅以PTX形式提供的内核所需的时间。编译到应用程序中的所有内核在加载时都必须具有原生二进制文件,否则它们将从PTX即时编译生成,包括链接到应用程序的所有库中的内核,即使这些内核从未被应用程序调用过。特别是在使用大型库时,这种即时编译可能会耗费大量时间。CUDA驱动程序会缓存由PTX即时编译生成的cubin文件,因此对特定用户来说这主要是一次性开销,但最好尽可能避免这种时间消耗。
PTX即时编译的内核通常无法利用新型GPU的架构特性,这意味着原生编译的代码可能更快或具有更高精度。
1.4.1. 使用CUDA Toolkit 7.5或更早版本的应用
CUDA Toolkit 7.5或更早版本中包含的编译器会生成适用于早期NVIDIA架构(如Kepler和Maxwell)的原生cubin文件,但它们无法生成适用于Pascal架构的原生cubin文件。为了在使用7.5或更早版本的CUDA Toolkit时支持Pascal及未来架构,编译器必须为每个内核生成PTX版本。
以下是可用于构建mykernel.cu的编译器设置,使其能原生运行在Kepler或Maxwell设备上,并通过PTX JIT在Pascal设备上运行。
注意
compute_XX 表示PTX版本,而sm_XX 表示cubin版本。nvcc 的-gencode= 命令行选项中的arch= 子句指定前端编译目标,必须始终是PTX版本。code= 子句指定后端编译目标,可以是cubin或PTX或两者。只有code= 子句指定的后端目标版本会保留在最终二进制文件中;其中至少一个必须是PTX版本以确保Pascal兼容性。
Windows
nvcc.exe -ccbin "C:\vs2010\VC\bin"
-Xcompiler "/EHsc /W3 /nologo /O2 /Zi /MT"
-gencode=arch=compute_30,code=sm_30
-gencode=arch=compute_35,code=sm_35
-gencode=arch=compute_50,code=sm_50
-gencode=arch=compute_52,code=sm_52
-gencode=arch=compute_52,code=compute_52
--compile -o "Release\mykernel.cu.obj" "mykernel.cu"
Mac/Linux
/usr/local/cuda/bin/nvcc
-gencode=arch=compute_30,code=sm_30
-gencode=arch=compute_35,code=sm_35
-gencode=arch=compute_50,code=sm_50
-gencode=arch=compute_52,code=sm_52
-gencode=arch=compute_52,code=compute_52
-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=。
1.4.2. 使用CUDA Toolkit 8.0的应用程序
随着CUDA Toolkit 8.0版本的发布,nvcc能够生成原生支持Pascal架构(计算能力6.0和6.1)的cubin文件。在使用CUDA Toolkit 8.0时,为确保nvcc能为所有近期GPU架构生成cubin文件,同时生成PTX版本以保持与未来GPU架构的前向兼容性,需按照以下示例在nvcc命令行中指定相应的-gencode=参数。
Windows
nvcc.exe -ccbin "C:\vs2010\VC\bin"
-Xcompiler "/EHsc /W3 /nologo /O2 /Zi /MT"
-gencode=arch=compute_30,code=sm_30
-gencode=arch=compute_35,code=sm_35
-gencode=arch=compute_50,code=sm_50
-gencode=arch=compute_52,code=sm_52
-gencode=arch=compute_60,code=sm_60
-gencode=arch=compute_61,code=sm_61
-gencode=arch=compute_61,code=compute_61
--compile -o "Release\mykernel.cu.obj" "mykernel.cu"
Mac/Linux
/usr/local/cuda/bin/nvcc
-gencode=arch=compute_30,code=sm_30
-gencode=arch=compute_35,code=sm_35
-gencode=arch=compute_50,code=sm_50
-gencode=arch=compute_52,code=sm_52
-gencode=arch=compute_60,code=sm_60
-gencode=arch=compute_61,code=sm_61
-gencode=arch=compute_61,code=compute_61
-O2 -o mykernel.o -c mykernel.cu
注意
compute_XX 指代PTX版本,而 sm_XX 指代cubin版本。nvcc 的 -gencode= 命令行选项中的 arch= 子句指定前端编译目标,必须始终是PTX版本。code= 子句指定后端编译目标,可以是cubin或PTX或两者。只有 code= 子句指定的后端目标版本会被保留在最终二进制文件中;至少应包含一个PTX版本以确保与未来架构的兼容性。
2. 版本历史
版本 1.0
首次公开发布。
版本 1.1
使用CUDA C++而非CUDA C/C++
3. 通知
3.1. 注意事项
本文档仅供信息参考之用,不应视为对产品功能、状态或质量的保证。NVIDIA公司(“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是苹果公司的商标,经Khronos Group Inc.授权使用。
3.3. 商标
NVIDIA和NVIDIA标识是美国及其他国家NVIDIA公司的商标或注册商标。其他公司及产品名称可能是其各自关联公司的商标。