不知不觉做CUDA程序已经有大半年的时间了,参加CUDA校园竞赛也得到一个优秀作品奖,也算是对自己的一个肯定,但是从来没有好好整理和记录自己的技术应用心得。由于最近实验室要求统一自己的CUDA软件开发环境,当然一个大问题就是编译选项如何配置。原先一直使用网上勇哥提供的向导自动配置好的环境,以及参照模仿SDK下的一些模板进行配置,这样就做了这么久,但是boss的意思是要我们自己更多的掌握,也就是要知其所以然。故我在自己的技术博客里将分几次把我从CUDA提供的关于nvcc里整理出来的一些东西贴出来!欢迎有兴趣的朋友交流讨论。那么就从CUDA编译流程的介绍开始吧!
不畏浮云遮望眼,只缘身在最高层!要真正了解CUDA程序的编译和像高手一样自如的进行nvcc配置,第一步在我看来,就是整体上把握CUDA程序的编译流程。所以开篇还是要看起来很务虚的介绍下基本的程序编译框架。
一、CUDA编译流程简介
Nvcc是一种编译器驱动,通过命令行选项可以在不同阶段启动不同的工具完成编译工作,其目的在于隐藏了复杂的CUDA编译细节,并且它不是一个特殊的CUDA编译驱动而是在模仿一般的通用编译驱动如gcc,它接受一定的传统编译选项如宏定义,库函数路径以及编译过程控制等。CUDA程序编译的路径会因在编译选项时设置的不同CUDA运行模式而不同,如模拟环境的设置等。nvcc封装了四种内部编译工具,即在C:\CUDA\bin目录下的nvopencc(C:\CUDA\open64\bin),ptxas,fatbin,cudafe。Nvcc的工作流程说明如下:
首先是对输入的cu文件有一个预处理过程,这一过程包括的步骤有将该源文件里的宏以及相关引用文件扩展开,然后将预编译已经产生的与C有关的CUDA系统定义的宏扩展开,并合并分支编译的结果。
预处理后,首先将预处理的结果送给CUDA前端,即CUDAfe。通过CUDAfe分离源文件,然后调用不同的编译器分别编译。cudafe被称为CUDA frontend,会被调用两次,完成两个工作:一是将主机代码与设备代码分离,生成gpu文件,二是对gpu文件进行dead code analysis,传给nvopencc。 Nvopencc生成ptx文件传给ptxas,最后将cubin或ptx传给fatbin。
同时,在编译阶段CUDA源代码对C语言所扩展的部分将被转成regular ANSI C的源文件,也就可以由一般的C编译器进行更多的编译和连接。也即是设备代码被编译成ptx(parallel thread execution)代码或二进制代码,host代码则以C文件形式输出,在编译时可将设备代码链接到所生成的host代码,将其中的cubin对象作为全局初始化数据数组包含进来,但此时,kernel执行配置也要被转换为CUDA运行启动代码,以加载和启动编译后的kernel。在使用CUDA驱动API时,可单独执行ptx代码或cubin对象,而忽略nvcc编译得到的host代码。
另外,Nvcc的各个编译阶段以及行为是可以通过组合输入文件名和选项命令进行选择的。它是不区分输入文件类型的,如object, library or resource files,仅仅把当前要执行编译阶段需要的文件传递给linker。
以上是我个人对CUDA编译过程的一个阐述,我想再结合下图就应该可以对CUDA的编译驱动nvcc有个整体的把握了吧!
注:摘自文档《The CUDA Compile Driver NVCC》,版本号2.3中的CUDA程序编译路径全景图。
嘟嘟互动视觉网站是多点触控、虚拟现实、增强现实、大屏幕投影显示等技术的交流学习网站网站