CUDA中的NVCC编译器详解-程序员宅基地

技术标签: c++  python  深度学习  人工智能  硬件架构  

NVCC编译器详解

CUDA C++ 为熟悉 C++ 编程语言的用户提供了一种简单的途径,可以轻松编写由设备执行的程序。

它由c++语言的最小扩展集和运行时库组成。

编程模型中引入了核心语言扩展。它们允许程序员将内核定义为 C++ 函数,并在每次调用函数时使用一些新语法来指定网格和块的维度。所有扩展的完整描述可以在 C++ 语言扩展中找到。任何包含这些扩展名的源文件都必须使用 nvcc 进行编译,如使用NVCC编译中所述。

运行时在 CUDA Runtime 中引入。它提供了在主机上执行的 C 和 C++ 函数,用于分配和释放设备内存、在主机内存和设备内存之间传输数据、管理具有多个设备的系统等。运行时的完整描述可以在 CUDA 参考手册中找到。

运行时构建在较低级别的 C API(即 CUDA 驱动程序 API)之上,应用程序也可以访问该 API。驱动程序 API 通过公开诸如 CUDA 上下文(类似于设备的主机进程)和 CUDA 模块(类似于设备的动态加载库)等较低级别的概念来提供额外的控制级别。大多数应用程序不使用驱动程序 API,因为它们不需要这种额外的控制级别,并且在使用运行时时,上下文和模块管理是隐式的,从而产生更简洁的代码。由于运行时可与驱动程序 API 互操作,因此大多数需要驱动程序 API 功能的应用程序可以默认使用运行时 API,并且仅在需要时使用驱动程序 API。 Driver API 中介绍了驱动API并在参考手册中进行了全面描述。

利用NVCC编译

在这里插入图片描述

内核可以使用称为 PTX 的 CUDA 指令集架构来编写,PTX 参考手册中对此进行了描述。 然而,使用高级编程语言(如 C++)通常更有效。 在这两种情况下,内核都必须通过 nvcc 编译成二进制代码才能在设备上执行。

nvcc 是一种编译器驱动程序,可简化编译 C++PTX 代码:它提供简单且熟悉的命令行选项,并通过调用实现不同编译阶段的工具集合来执行它们。 本节概述了 nvcc 工作流程和命令选项。 完整的描述可以在 nvcc 用户手册中找到。

编译流程

离线编译

使用 nvcc 编译的源文件可以包含主机代码(即在host上执行的代码)和设备代码(即在device上执行的代码。 nvcc 的基本工作流程包括将设备代码与主机代码分离,然后:

  • 将设备代码编译成汇编形式(PTX 代码)或二进制形式(cubin 对象)
  • 并通过CUDA运行时函数的调用来替换 <<<…>>> 语法对主机代码进行修改,以从 PTX 代码或 cubin 对象加载和启动每个编译的内核。

修改后的主机代码要么作为 C++ 代码输出,然后使用另一个工具编译,要么直接作为目标代码输出,方法是让 nvcc 在最后编译阶段调用主机编译器。

然后应用程序可以:

  • 链接到已编译的主机代码(这是最常见的情况),
  • 或者忽略修改后的主机代码(如果有)并使用 CUDA 驱动程序 API(请参阅驱动程序 API)来加载和执行 PTX 代码或 cubin 对象。
即时编译

在这里插入图片描述

应用程序在运行时加载的任何 PTX 代码都由设备驱动程序进一步编译为二进制代码。这称为即时编译。即时编译增加了应用程序加载时间,但允许应用程序受益于每个新设备驱动程序带来的任何新编译器改进。它也是应用程序能够运行在编译时不存在的设备上的唯一方式,如应用程序兼容性中所述。

当设备驱动程序为某些应用程序实时编译一些 PTX 代码时,它会自动缓存生成二进制代码的副本,以避免在应用程序的后续调用中重复编译。缓存(称为计算缓存)在设备驱动程序升级时自动失效,因此应用程序可以从设备驱动程序中内置的新即时编译器的改进中受益。

环境变量可用于控制即时编译,如 CUDA 环境变量中所述

作为使用 nvcc 编译 CUDA C++ 设备代码的替代方法,NVRTC 可用于在运行时将 CUDA C++ 设备代码编译为 PTX。 NVRTC 是 CUDA C++ 的运行时编译库;更多信息可以在 NVRTC 用户指南中找到。

Binary 兼容性

二进制代码是特定于体系结构的。 使用指定目标体系结构的编译器选项 -code 生成 cubin 对象:例如,使用 -code=sm_35 编译会为计算能力为 3.5 的设备生成二进制代码。 从一个次要修订版到下一个修订版都保证了二进制兼容性,但不能保证从一个次要修订版到前一个修订版或跨主要修订版。 换句话说,为计算能力 X.y 生成的 cubin 对象只会在计算能力 X.z 且 z≥y 的设备上执行。

注意:仅桌面支持二进制兼容性。 Tegra 不支持它。 此外,不支持桌面和 Tegra 之间的二进制兼容性。

PTX 兼容性

某些 PTX 指令仅在具有更高计算能力的设备上受支持。 例如,Warp Shuffle Functions 仅在计算能力 3.0 及以上的设备上支持。 -arch 编译器选项指定将 C++ 编译为 PTX 代码时假定的计算能力。 因此,例如,包含 warp shuffle 的代码必须使用 -arch=compute_30(或更高版本)进行编译。

为某些特定计算能力生成的 PTX 代码始终可以编译为具有更大或相等计算能力的二进制代码。 请注意,从早期 PTX 版本编译的二进制文件可能无法使用某些硬件功能。 例如,从为计算能力 6.0 (Pascal) 生成的 PTX 编译的计算能力 7.0 (Volta) 的二进制目标设备将不会使用 Tensor Core 指令,因为这些指令在 Pascal 上不可用。 因此,最终二进制文件的性能可能会比使用最新版本的 PTX 生成的二进制文件更差。

应用程序兼容性

要在具有特定计算能力的设备上执行代码,应用程序必须加载与此计算能力兼容的二进制或 PTX 代码,如二进制兼容性PTX 兼容性中所述。 特别是,为了能够在具有更高计算能力的未来架构上执行代码(尚无法生成二进制代码),应用程序必须加载将为这些设备实时编译的 PTX 代码(参见即时编译)。

哪些 PTX 和二进制代码嵌入到 CUDA C++ 应用程序中由 -arch-code 编译器选项或 -gencode 编译器选项控制,详见 nvcc 用户手册。 例如:

nvcc x.cu
        -gencode arch=compute_50,code=sm_50
        -gencode arch=compute_60,code=sm_60
        -gencode arch=compute_70,code=\"compute_70,sm_70\"

嵌入与计算能力 5.0 和 6.0(第一和第二-gencode 选项)兼容的二进制代码以及与计算能力 7.0(第三-gencode 选项)兼容的 PTX 和二进制代码。

生成主机代码以在运行时自动选择最合适的代码来加载和执行,在上面的示例中,这些代码将是:

  • 具有计算能力 5.0 和 5.2 的设备的 5.0 二进制代码,
  • 具有计算能力 6.0 和 6.1 的设备的 6.0 二进制代码,
  • 具有计算能力 7.0 和 7.5 的设备的 7.0 二进制代码,
  • PTX 代码在运行时编译为具有计算能力 8.0 和 8.6 的设备的二进制代码。

例如,x.cu 可以有一个优化代码的方法,使用 warp shuffle 操作,这些操作仅在计算能力 3.0 及更高版本的设备中受支持。 __CUDA_ARCH__ 宏可用于根据计算能力区分各种代码方案。 它仅为设备代码定义。 例如,当使用 -arch=compute_35 编译时,__CUDA_ARCH__ 等于 350。

使用驱动 API 的应用程序必须编译代码以分离文件并在运行时显式加载和执行最合适的文件。

Volta 架构引入了独立线程调度,它改变了在 GPU 上调度线程的方式。 对于依赖于以前架构中 SIMT 调度的特定行为的代码,独立线程调度可能会改变参与线程的集合,从而导致不正确的结果。 为了在实现独立线程调度中详述的纠正措施的同时帮助迁移,Volta 开发人员可以使用编译器选项组合 -arch=compute_60 -code=sm_70 选择加入 Pascal 的线程调度。

nvcc 用户手册列出了 -arch、-code-gencode 编译器选项的各种简写。 例如,-arch=sm_70-arch=compute_70 -code=compute_70,sm_70 的简写(与 -gencode arch=compute_70,code=\"compute_70,sm_70\" 相同)。

C++兼容性

编译器前端根据 C++ 语法规则处理 CUDA 源文件。 主机代码支持完整的 C++。 但是,设备代码仅完全支持 C++ 的一个子集,如 C++ 语言支持中所述。

64位支持

64 位版本的 nvcc 以 64 位模式编译设备代码(即指针是 64 位的)。 以 64 位模式编译的设备代码仅支持以 64 位模式编译的主机代码。

同样,32 位版本的 nvcc 以 32 位模式编译设备代码,而以 32 位模式编译的设备代码仅支持以 32 位模式编译的主机代码。

32 位版本的 nvcc 也可以使用 -m64 编译器选项以 64 位模式编译设备代码。

64 位版本的 nvcc 也可以使用 -m32 编译器选项以 32 位模式编译设备代码。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/kunhe0512/article/details/125026801

智能推荐

25.hadoop系列之Yarn Tool接口实现动态传参_yarn脚本后缀传值-程序员宅基地

文章浏览阅读139次。当我们通过yarn向集群提交自定义任务时,若传入队列参数会报错此时我们需要Tool工具,进行动态传参控制。_yarn脚本后缀传值

Android Studio查看Android源码_win查看安卓源码-程序员宅基地

文章浏览阅读4.3k次。最近在折腾面试,然后就有些组件的原理需要看源码,之前也弄过,都是用的Source Insight在win10里面搞的,今天试了一下Mac,源码60G,我这个版本是Android 11,目前是最新版的代码。用AS看源码首先要构建项目配置文件,就是ipr和iml工具,用到Android源码里面的idegen工具,但是你用官方的mmm命令方法会报错,说文件格式不对,本来是可以用mmm命令直接生成的,但是Mac的文件系统跟官方要求的有问题,所以就放弃了,有想试试的同学可以执行下面的命令。cd ~/aosp_win查看安卓源码

使用正则表达式判断URL地址是否合法_判断是否是正常链接正则表达式-程序员宅基地

文章浏览阅读1k次。在编程中,我们常常需要对给定的URL地址进行合法性检测。函数来判断URL地址是否合法。该函数接受一个URL地址作为参数,并返回一个布尔值,表示该URL地址是否合法。总之,在Python中使用正则表达式判断URL地址是否合法非常简单,只需要编写一个正则表达式,然后使用。在函数内部,我们使用正则表达式来匹配URL地址的各个部分,并将它们拼接在一起。函数来判断该URL地址是否符合我们定义的正则表达式规则。匹配URL地址的路径部分。在示例代码中,我们将一个合法的URL地址。使用正则表达式判断URL地址是否合法。_判断是否是正常链接正则表达式

写一个基于知识图谱的古诗词问答系统的背景意义,500字-程序员宅基地

文章浏览阅读260次。古诗词是中国文化的重要组成部分,具有悠久的历史和独特的艺术价值。但是,由于其语言难度较高、时代背景和文化背景的复杂性等原因,使得普通读者很难深入理解古诗词的内涵和价值。此时,基于知识图谱的古诗词问答系统应运而生,其背景意义包括以下几个方面:一、促进文化传承古诗词是中华文化的瑰宝,它们承载了丰富的历史文化信息。而传统的古诗词学习方式主要依靠课堂教学和自学,但这种学习方式往往难以满足大众的需求。基..._古诗问答系统

MySQL自动备份脚本_mysqldump 脚本-程序员宅基地

文章浏览阅读660次,点赞10次,收藏10次。mysqldump命令将数据库中的数据备份成一个文本文件,表的结构和数据将存储在生成的文本文件中。将备份出来的数据还原到某个数据库中。备份一个数据库下的多个表。MySQL自动备份脚本。也可以登入数据之后进行。_mysqldump 脚本

程序员刚写完代码,就被开除了_程序员需求写不出来被开除-程序员宅基地

文章浏览阅读1.1k次。学小编逛贴吧发现一个热帖,就凑了凑热闹~~~看到这样一个帖。一程序员说自己刚写完代码,就别公司老板给开除了。为什么会这样的呢?原来是这位程序员写了一段这样的代码:public static Date getNextDay() {try {Thread.sleep(246060*1000);} catch (InterruptrdException e) {e.printStackTr..._程序员需求写不出来被开除

随便推点

rpm常用命令记录_rpm命令-程序员宅基地

文章浏览阅读1.7k次。linux - rpm _rpm命令

ssm小学生课外知识学习网站+vue-程序员宅基地

文章浏览阅读26次。用户可以在首页访问小学生课外知识学习网站方面信息,首页上面有导航栏,导航栏上面有课外知识,试卷列表,学习资讯,个人中心,后台管理等,点击导航栏课外知识可以看到很多信息,点击某个信息可以查看对应详情信息,用户登录后可以对小学生课外知识学习网站文章信息进行评论操作。管理员可以对课外知识进行添加,查询,修改,删除操作。下图就是课外知识管理页面。管理员可以对知识分类信息进行删除,查询和修改操作。前端技术:JavaScript、VUE.js(2.X)、css3。数据库管理工具:Navicat或sqlyog。

goland 常用快捷键_goland进入ctrl+b函数后,什么快捷键返回上一个函数-程序员宅基地

文章浏览阅读1.7w次,点赞3次,收藏9次。转自:https://www.cnblogs.com/zhishuai/p/7942273.htmljetbrains goland 跳到上一个光标处查了下是 :Ctrl + Alt + 左右 mac下面是:Command+ Alt + 左右键但是我用下来是切上面打开文档页摸索了下是:Ctrl +Win+ Alt + 左右 我的键的映射是Default 。另外jb确实也..._goland进入ctrl+b函数后,什么快捷键返回上一个函数

Python3-word文档操作(六):word文档中表格的操作-单元格文字居中,字体颜色等的设置_doc.tables[0].cell(a, b).vertical_alignment = wd_a-程序员宅基地

文章浏览阅读4.6k次,点赞3次,收藏14次。用python3操作word文档,实现:word文档中表格的操作-单元格文字居中,字体颜色等的设置。python设置文档字体,python设置文档字体颜色,python设置单元格文字居中。_doc.tables[0].cell(a, b).vertical_alignment = wd_align_vertical.center # 垂

Ubuntu系统使用技巧 Vim基本技巧介绍_ubuntu系统vim操作-程序员宅基地

文章浏览阅读231次。Ubuntu系统使用技巧: Ctrl+alt+t: 打开终端​ Ctrl+L:清理屏幕​ Tab: 自动补全​ up/down: 调出命令执行记录​ Ctrl+Alt+方向键:切换工作区​ Alt+Tab: 切换任务重定向、管道、通配符:重定向:就是把命令的执行结果写入到文件中​ cmd > filename 把命令的执行结果以清空的方式写入到文件中(先清空再写入)​ cmd >> filename 把命令的执行结果以追加的方式写入到文件中管道:_ubuntu系统vim操作

Nacos 使用指南-程序员宅基地

文章浏览阅读420次,点赞3次,收藏8次。123。

推荐文章

热门文章

相关标签