nvcc简介

nvcc简介

参考NVDIA官方文档:

https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#gpu-generations

nvcc编译分成device部分编译和host部分编译,host部分直接调用平台编译器进行编译Linux使用gcc,window使用cl.exe,这里主要讲解device部分的编译,此部分编译分两个阶段,第一阶段将源文件.cu文件的device部分编译成ptx文本指令,第二阶段将ptx文本指令编译成在真实架构上运行的二进制指令,第二阶段可能发生在生成可执行程序的过程中,也可能发生在运行可执行程序的过程中(just-in-time compilation)。在生成可执行程序的过程中可以根据nvcc选项选择是否将ptx文本指令(x.ptx中间文件中)、二进制指令(x.cubin中间文件)嵌入到可执行程序中,一般有3种嵌入方式:只嵌入x.ptx(第二阶段被忽略,全部依赖just-in-time compilation);只嵌入x.cubin(无法进行just-in-time compilation);两者都嵌入(运行过程中driver找到合适二进制指令镜像则加载之,否则进行just-in-time compilation再加载之)。

虚拟架构和真实架构

gpu设备的应用兼容性和cpu明显不同,cpu每一代指令集一般都兼容上一代指令集,所以已发布的应用可以运行在新一代的cpu硬件上,但GPU新一代指令集不兼容上一代的指令集。GPU使用virtual architectures来保证应用层兼容性(PTX可以看做虚拟的GPU架构,ptx是文本指令)。GPU虽然在真实架构上不具备二进制指令的兼容性,但是PTX可以跨代兼容,例如使用compute_30虚拟架构生成的PTX指令,可以用来生成sm_50的真实架构的二进制指令。低代PTX文本指令可以跨代生成高代二进制指令,但低代二进制指令却无法跨代运行在高代真实架构GPU,高代二进制指令更不可能运行在低代架构GPU上。

sm_30 and sm_32

Basic features

+ Kepler support

+ Unified memory programming

sm_35+ Dynamic parallelism support
sm_50sm_52, and sm_53+ Maxwell support
sm_60sm_61, and sm_62+ Pascal support
sm_70+ Volta support

上表中第二列Kepler、 Maxwell、 Pascla 、Volta都是NVDIA显卡架构名(不同于系列名,如GeForce、 Quadro是系列名,分别对应游戏和深度学习两个领域),各代架构对应不同的各代指令集。第一列对应显卡的functional capabilities,例如sm_35,3代表第3代架构,5代表第五发版本,同一代的二进制指令是兼容的,sm_30的真实架构的二进制指令可以运行在sm_35架构的GPU上。

Virtual Architecture Feature List

compute_30 and compute_32

Basic features

+ Kepler support

+ Unified memory programming

compute_35+ Dynamic parallelism support
compute_50compute_52, and compute_53+ Maxwell support
compute_60compute_61, and compute_62+ Pascal support
compute_70+ Volta support

上表对应GPU虚拟架构,类比真实架构进行理解。、

NVCC使用

使用指令

nvcc x.cu --gpu-architecture=compute_50 --gpu-code=sm_50
效果如下图

                        

最终只有对应真实架构sm_50的二进制的指令被嵌入到最用的可执行程序或者库文件中,如果运行在非sm_50的GPU上,将会报错如下:

addKernel launch failed: no kernel image is available for execution on the device
addWithCuda failed!

因为没有将PTX文本指令嵌入到可执行程序中,没法进行即时编译(just-in-time compilation)。

将PTX文本指令和二进制指令都嵌入到可执行程序中可以使用指令

nvcc x.cu --gpu-architecture=compute_50 --gpu-code=compute_50,sm_50

或者省略--gpu-code

nvcc x.cu --gpu-architecture=sm_50

将一个版本的PTX指令和多种二进制指令嵌入可执行程序使用如下指令:

nvcc x.cu --gpu-architecture=compute_50 --gpu-code=compute_50,sm_50,sm_52

只将ptx文本指令嵌入到可执行文件可以使用如下指令:

nvcc x.cu --gpu-architecture=compute_50 --gpu-code=compute_50

或者省略--gpu-code

nvcc x.cu --gpu-architecture=compute_50

just-in-time compilation如下:


总结:

compute_50这参数项用来指定生成ptx指令的版本,跟在--gpu-architecture选项和--gpu-code选项之后皆可;

sm_50这类参数用来指定生成二进制代码的版本,不考虑shorthand的情况(详见官网,就是以上省略--gpu-code的情况),跟在--gpu-code选项之后;

--gpu-architecture选项只能跟一个参数,不考虑shorthand的情况,只能用来指定生成的ptx版本;

--gpu-code选项可以跟多个参数,不考虑shorthand的情况,用来指定生成的二进制文件的版本和最终嵌入到可执行文件中的内容,是只有ptx文本指令还是只有二进制指令,或者两者皆有。

为何不混淆记忆,我们可以不使用shorthand的情况,即不省略--gpu-code选项。

官网上有一句话:

From this it follows that the virtual architecture should always be chosen as low as possible, thereby maximizing the actual GPUs to run on. The real architecture should be chosen as high as possible (assuming that this always generates better code).

选择虚拟架构要尽量选择低版本的架构,因为低版本的虚拟架构也可以生成高版本的真实架构二进制指令,这样可以保证兼容性好,选择真实架构版本要尽量选择高版本的架构,可以生成更好的二进制代码。但这只是理想情况,详见官网5.4. Virtual Architectures


  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值