cuda c programming guide - 编程接口

cuda c++是对c++的扩充,具体参考C++ Language Extensions

cuda c++编写的kernel需要使用nvcc进行编译。

运行时库需要使用cuda runtime,其提供了在host上执行的c/c++函数,可用于allocate/deallcote device memory,transfer data between host and device memory等。

cuda runtime是构建在cuda driver api的基础上的,两者的区别是,driver api可在runtime api的基础上提供更加细粒度的控制(如context/modules)。用户可以直接调用driver api,但是大部分情况下,只使用cuda runtime api已经足够了。

3.1 nvcc编译

虽然一般使用cuda c++编写kernel,但也可以直接使用cuda指令集(PTX)编写kernel。两种情况编写的kernel都需要使用nvcc编译为可在device上执行的二进制程序。

nvcc是一个编译器driver,用于简化c++/PTX代码的编译过程。其提供了简洁/熟悉的指令,可用于完成多个阶段的编译任务。本节给出nvcc的workflow和常用options。

3.1.1 编译workflow

3.1.1.1 离线编译

nvcc编译的源文件可以是主机代码和device 代码的混合体。

nvcc的基本workflow是:

  • 从host代码中分离出device代码;
  • 将device代码编译成汇编格式(PTX代码)或二进制形式(cubin对象);
  • 将host代码中的<<<...>>>替换为必要的cuda runtime函数,然后去调用和加载对应的编译过的kernel(即上一步生成的PTX代码/cubin对象);

修改后的host代码:

  • 可以作为c++代码输出,然后使用其他的编译器进行编译;
  • 也可以让nvcc调用host编译器在最后一个编译阶段当做目标代码使用;

接下来应用程序:

  • 可以link到编译过的host代码(最常见的情况);
  • 忽略修改过的host代码,使用cuda driver api加载和执行PTX代码/cubin对象;
3.1.1.2 即时编译

应用程序运行时加载的PTX代码会被设备驱动进一步编译成二进制码,称之为即时编译。即时编译会增加应用程序的加载耗时,但也会从device driver的更新中获益。这也是唯一的一种可以让应用程序运行在编译时尚不存在的device上的方法。

当即时编译器为应用程序编译PTX代码时,它会自动缓存生成的二进制码以避免重复编译。但当device driver升级后,缓存会变得不可用,所以应用程序会随着device driver中内置的即时编译器的更新而重新编译,从而获得新的编译器带来的提升。

即时编译需要通过环境变量控制,具体见 CUDA Environment Variables

另一种编译方式是NVRTC(nvidia runtime compiler),它可以在运行时将cuda c++代码编译成PTX。

3.1.2 二进制的兼容性

二进制代码是特定于架构的。编译时的 -code 选项用于设定生成的cubin对象的目标架构。例如,设定-code=sm_80表示产生特定于计算能力为8.0的架构的cubin。

生成的cubin是向后兼容的,但不能够跨主版本。也就是说,为计算能力X.y gpu生成的cubin,只能在 X.z (z >= y)的GPU上运行。

3.1.3 PTX兼容性

将c++代码编译为PTX代码时使用 -arch 选项设定target的计算能力。之所以需要这样的设置,是因为只有超过某个特定的计算能力后才能支持某些PTX指令,例如warp shuffle函数所需要的最小计算能力为5.0,因此对包含warp shuffle的代码,必须设置-arch=compute_50或更高。

为特定计算能力的GPU产生的PTX代码可以编译为适配于同样的或更高计算能力GPU的binary code。但是从老版本PTX代码中编译成的二进制码不能使用硬件的新特性。比如,为pascal(计算能力6.0)编译的PTX代码进一步编译为volta(计算能力7.0)上的二进制码无法使用tensor core指令。因为tensor core在pascal上不存在。所以最终产生的binary会比直接使用在volta上编译的PTX码的性能要差。

3.1.4 应用程序兼容性

3.2 cuda runtime

应用程序会link cuda runtime(libcudart.a/cudart.lib/libcudart.so/cudart.dll)。

所有的cuda runtime api都以cuda开头。

3.2.1 初始化

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值