CUDA编程指南阅读笔记(四)

4. CUDA C语言编程接口

      接上篇文章继续写。

4.2 兼容性


      1、二进制兼容性
      二进制代码是设备相关的,使用NVCC编译器编译时,若指定-code选项,则会编译产生目标设备的二进制cubin对象。例如,编译时使用-code=sm_13会产生适用于计算能力1.3的二进制代码。二进制代码在CUDA计算设备上具有小版本的向前兼容性,但是在大版本上不具备兼容性。也就是说,对于计算能力X.y的硬件,使用-code=sm_Xy编译后,程序能够运行于计算能力X.z(其中z>=y)的硬件上,但不能运行在计算能力M.n(M!=X)的硬件上。

      2、PTX代码兼容性
      不同计算能力的设备所支持的PTX指令条数是不同的,一些PTX指令只在拥有较高计算能力的设备上被支持。例如,全局内存(global Memory)的原子操作指令只能用于计算能力不小于1.1的设备;双精度浮点运算指令只能用于计算能力不小于1.3的设备。在将C语言编译为PTX代码时,NVCC使用-arch编译选项指定PTX代码目标设备的计算能力。因此,要想使用双精度运算,编译时必须使用选项-arch=sm_13(或使用更高的计算能力),否则NVCC会自动将双精度操作降级为单精度操作。
      为某一特定设备产生的PTX代码,在运行时总是能够被具有更高计算能力的设备JIT编译为可执行的二进制代码。

      3、应用程序兼容性
      执行CUDA程序有两种方式,一种是直接加载编译好的CUDA二进制代码运行,另一种是首先加载程序中的PTX代码,再执行JIT编译得到二进制的设备可执行文件,然后运行。特别需要注意的是,为了让程序运行具有更高计算能力的未来设备上,必须让程序加载PTX代码。
      事实上,在一个CUDA C程序中可以嵌入不止一个版本的PTX/二进制代码。那么,具体执行时哪一个版本的PTX或者二进制代码会得到执行呢?答案是:最兼容的那个版本。例如编译一个名为x.cu的CUDA源代码:

将会产生兼容计算能力1.1硬件的二进制代码(第一排的-gencode选项)以及兼容计算能力1.1设备的PTX和二进制代码,这些代码都将会嵌入到编译后的目标文件中。
      主机端将会产生一些额外的代码,在程序运行时,这些代码会自动决定装载哪一个版本的代码来执行。对于上面的例子:
  • 计算能力1.0的设备运行该程序将会装载1.0版本的二进制代码
  • 计算能力1.1、1.2或者1.3的设备运行该程序将会装载1.1版本的二进制代码
  • 计算能力2.0或者更高的设备运行该程序将会装载1.1版本的PTX代码进而对其进行JIT编译得到相应设备的二进制代码
      同时,x.cu还可以在程序中使用一些特殊的宏来改变不同设备的代码执行路径。例如,对于计算能力1.1的设备而言,宏__CUDA_ARCH__等于110,在程序中可以对该宏的值进行判断,然后分支执行程序。
      NVCC用户手册列出了很多-arch,-code和-gencode等编译选项的简化书写形式。例如,-arch=sm_13就是-arch=compute_13 -code=compute13, sm_13的简化形式。更多详尽的内容请参阅该手册。

      4、C/C++兼容性
      NVCC编译器前端使用C++语法啊规则来处理CUDA源文件。在主机端,CUDA支持完整的C++语法;而在设备端,只有部分C++语法是被支持的。这方面更为详尽的讨论请参见《CUDA C程序设计指南》的C/C++语言支持章节。

      5、64位兼容性
      64位版本的nvcc编译器将设备代码编译为64位模式,即指针是64位的。运行64位设备代码的先决条件是主机端代码必须也使用64位模式进行编译。同样,32位版本的nvcc将设备代码编译为32位模式,这些代码也必须与相应的32位主机端代码相配合方能运行。
      32位nvcc编译器可以使用-m64编译选项将设备代码编译为64位模式。同时64位nvcc编译器也可使用-m32编译选项将设备代码编译为32位模式。

你可能感兴趣的:(CUDA)