您的位置:首页 > 游戏 > 手游 > [CUDA编程] --- nvcc编译过程和GPU计算能力

[CUDA编程] --- nvcc编译过程和GPU计算能力

2024/11/17 22:41:28 来源:https://blog.csdn.net/weixin_42445727/article/details/140893132  浏览:    关键词:[CUDA编程] --- nvcc编译过程和GPU计算能力

1 nvcc编译流程

nvcc编译流程

1 nvcc分离全部源代码为主机代码和设备代码
2 主机(host)代码是C/C++代码,设备(device)代码是C/C++拓展语言编写
3 nvcc先将设备代码编译为PTX(Parallel Thread Execution)伪汇编代码,再将PTX代码编译为二进制的cubin目标代码
4 在将源代码编译为PTX代码时,需要使用选项-arch=compute_XY指定一个虚拟架构的计算能力,用以确定代码中能够使用的CUDA功能
5 在将PTX代码编译为cubin代码时,需要使用选项-code-sm ZW指定一个真实架构的计算能力,用以确定可执行文件能否使用的CPU 

具体可参看官方文档:
nvcc编译过程:https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html

下面结合这张图进行具体讲解
在这里插入图片描述
NVCC的编译过程分为离线编译和即时编译两部分组成:

离线编译(绿色虚线框内):

CUDA源程序(即xxx.cu文件)在编译前的预处理会被分为主机端代码和设备段代码(即图中的左右分支):

1.如图右分支:在设备端代码会被编译成ptx文件(可以看作是用于设备端的汇编文件)或是直接可运行的二进制文件xxx.cubin,然后将起.ptx/.cubin文件放在fatbinary文件中。

2.如图左分支:在主机端代码进行预处理,并将其嵌入到fatbinary文件中,并将CUDA特定的C++扩展转换成标准C++结构(通过cudafe++和cudafe1.stub.c合成为。cudafe1.cpp),然后C++主机编译器将所合成的主机代码与嵌入的fatbinary编译成主机.o/.obj文件。

即时编译(图片绿色虚线框下方):

在主机设备启动代码时,CUDA run-time系统会对fatbinary文件进行检测,以获得一个对于GPU设备合适的映像(之后还会提及):

1.如果之前的cubin文件与当前GPU相匹配,run-time系统通过nvlink对多个设备端文件进行链接,最后通过host linker链接主机端文件成可执行文件。

2.如果cubin文件所表示的虚拟设备与当前GPU不符或者fatbinary文件中只包含ptx文件,将会对fatbinary文件中的ptx文件进行即时编译,并对其进行链接(nvlink)最后通过host linker链接主机端文件成可执行文件。

补充说明:
NVCC极大的考虑到了应用的向后兼容性,(如最上面图的绿色实线宽内)将输入设备端代码根据虚拟gpu结构(virtual architecture)编译成ptx,以及通过当前的真实gpu结构将其编译成cubin文件,到时进行直接执行即可。
在这里插入图片描述
由于ptx的存在,可以提高其兼容性,通过在运行时对ptx进行即时编译成cubin文件并执行。
在这里插入图片描述

1 PTX是CUDA平台为基于CPU通用计算而定义的虚拟机和指令集
2 nvcc编译命令总是使用两个体系结构,一个是虚拟的中间体系结构,另一个是实际的GPU体系结构
3 虚拟架构更像是对应所需的GPU的功能声明
4 虚拟架构尽可能选择低 --- 适配更多实际GPU真实架构尽可能选择高 --- 充分发挥GPU性能

2 GPU架构与计算能力

3 CUDA程序兼容性问题

3.1 指定虚拟架构计算能力

  • C/C++源码编译为PTX时,可以指定虚拟架构的计算能力,用来确定代码中能够使用的CUDA功能
  • C/C+=源码转化为PTX这一步与GPU硬件无关
  • 编译指令(指定虚拟架构计算能力)
// XY: 第一个数组X代表计算能力的主版本号,第二个数字Y代表计算能力的次版本号
-arch=compute_XY
  • PTX的指令在能在更高的计算能力的GPU使用
nvcc helloworld -o hello -arch=compute_61
编译出来的可执行文件hello可以在计算能力>=6.1的GPU上面运行,在计算能力小于6.1的GPU无法运行

3.2 指定真实架构计算能力

  • PTX指令转化为二进制cubin代码与具体的GPU有关
  • 编译指令(指定真实架构的计算能力)
// XY:第一个数字X代表能力的主版本号,第二个数字Y代表计算能力的次版本号
-code=sm_XY
  • 注意
1 二进制cubin代码,大版本之前不兼容
2 指定真实架构计算能力的时候必须指定虚拟架构计算能力
3 指定真实架能力必须大于等于虚拟架构计算能力
  • 真实架构可以实现低小版本到高小版本的兼容

3.3 指定多个GPU版本编译

  • 使得编译出来的二进制文件可以在多个GPU中运行
  • 同时指定多组计算能力
编译选项: -gencode arch=compute_XY -code=sm_XY
如:
-gencode arch=compute_35 -code=sm_35 //开普勒架构
-gencode arch=compute_50 -code=sm_50 // 麦克斯韦架构
-gencode arch=compute_60 -code=sm_60 // 帕斯卡架构
-gencode arch=compute_70 -code=sm_70 // 福特架构
  • 编译出的可执行文件包含四个二进制版本,生成的可执行文件称为胖二进制文件(fatbinary)

3.4 nvcc即时编译

  • 在运行可执行文件时,从保留的PTX代码临时编译出cubin文件
  • 在可执行文件中保留PTX代码,nvcc编译指令指定所保留的PTX代码虚拟架构
指令 -gencode arch=compute_Xy, code=sm_XY
两个计算能力都是虚拟架构计算能力
两个虚拟架构计算能力必须一致
如:
-gencode arch=compute_35, code=sm_35
-gencode arch=compute_60, code=sm_60
-gencode arch=compute_61, code=sm_61

3.5 nvcc编译默认计算能力

不同版本CUDA 编译器在编译CUDA代码时,都有一个默认计算能力,
CUDA6.0及更改版本, 默认计算能力1.0
CUDA6.5-CUDA8.0,默认计算能力2.0
CUDA9.0-CUDA10.2,默认计算能力3.0
CUDA11.6,默认计算能力5.2

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com