首页 > 代码库 > CUDA C编程入门-编程接口

CUDA C编程入门-编程接口

  CUDA C给熟悉C编程语言的人提供一个简单的途径去编写在设备(GPU)上执行的代码。

  由一个最小的C语言的扩展集和运行时库组成。

  核心的语言扩展在编程模型这一章节已经介绍过了。允许程序员定义核函数并且使用一些新的语法指定核函数每次运行时的grid和block的维数。可以在C语言扩展这个章节里找到扩展的完整描述。所有的含有这些扩展的源代码都需要使用nvcc编译,nvcc的概述可以查看使用nvcc编译这一小节。

  在CUDA C运行这一小节介绍运行时。运行时提供在主机执行的用于分配和回收设备内存、设备和主机内存之间传输数据、多个设备的管理等的C函数。可以在CUDA 查考手册中查看关于运行时的完整描述。

  运行时由低级的C API-可被应用访问的CUDA驱动API,作为基础。驱动API通过低级的概念比如CUDA上下文-就像主机处理器的上下文一样、CUAD模块-就像设备动态加载库一样而提供额外级别的控制。大多数应用程序因为不需要额外级别的控制,所以不会使用驱动API,而是用运行时时,上下文和模块管理是隐式的,这样的结果是编写的代码就会简单明了。驱动API在驱动API这一章节介绍,完整的描述在参考手册。

3.1 使用NVCC编译

  可以使用一个叫PTX的CUDA指令集架构编写核函数,PTX的描述在PTX参考手册。然而一般使用更加有效的高级语言,比如C。这两种情况,核函数都必须通过nvcc编译成二进制代码,这样才能在设备上执行。

  nvcc是一个编译器,简化编译C和PTX代码的流程:提供简单和熟悉的命令行选项,执行相关命令去调用实现不同编译阶段的工具集。这节给出nvcc工作流程和命令行选项的概述。可以在nvcc用户手册找到完整的描述。

3.1.1 编译的工作流程

3.1.1.1 离线编译

  使用nvcc编译的源代码可以混有主机(在主机执行的)和设备(在设备执行的)的代码。ncvv的工作流程主要在于分离主机和设备的代码:

  1. 编译设备代码成装配形式(PTX代码)或者二进制形式(cubin对象)。
  2. 修改主机代码:把调用核函数的<<<...>>>替换成必要的从PTX代码和cubin对象加载和运行的已经编译的核函数的CUDA C运行时函数。

  修改的主机代码输出不是被另外的工具编译的C代码就是允许直接让nvcc调用主机编译器完成最后编译阶段的对象代码。

  然后应用程序能:

  1. 链接已经编译的主机代码(大多数的情况下)
  2. 或者忽略已经被修改的主机代码(如果有的话),使用CUDA驱动API加载和执行PTX或者cubin对象。

3.1.1.2 即时编译

  任何被应用程序在运行时加载的PTX代码都会被设备驱动编译成二进制代码。这就叫做即时编译。即时编译增加应用加载的时间,但是能使应用从新的设备驱动带的新的性能更好的编译器获得益处。只有这一条路能使那些在编译时没设备的应用在设备上运行,详细在应用兼容性这一小节描述。

  当设备驱动程序为应用即时编译一些PTX代码时,为了避免应用再次调用时重复编译,会自动缓存生成的二进制代码的副本。缓存-指得是计算机缓存,当设备驱动更新时会自动无效,因此应用可以从新的的设备驱动的更加完善的新的即时编译器获得益处。

  可用的控制即时编译的环境变量在CUDA环境变量这一章节里描述。

3.1.2 二进制兼容性

  未完待续...