前段时间有同学问我CUDA到底是什么东西,Caffe源码中的.cu文件又是什么东西?我发现我没办法很有系统的回答这个问题,当时就觉得在想:哇,搞深度学习这么久了,居然没办法很好的回答这个问题,所以在充满愧疚感之下,抽空恶补了一下~
CUDA的产生就是英伟达公司为深度学习从业者使用GPU提供的必备工具,因此我们先来讲讲什么是GPU,它和CPU之间的有什么异同。首先要明确一点,CPU和GPU都可以作为计算机的大脑,两者的组成部分是一致的,如下图所示:
绿色:计算单元
橙色:存储单元(硬盘+缓存)
黄色:控制单元
从图中我们可以发现:
- CPU具有很强的控制器,也有很强大的缓存(Cache)
- GPU有很多控制器,很多的计算单元,每个控制器都配有缓存
从两者的架构来看,我们发现,这两者的设计逻辑是不一样的,CPU秉承着低延时性,而GPU的思路是高吞吐量。所谓低延时性,直白来说就是一台挖掘机(控制器),用它的爪子(缓存),一次就能够挖很多的资源(计算)。所谓高吞吐量,直白来说就是一个团的人(控制器),用他们的手(缓存),一次一个个的也能捧很多资源(计算)。所以CPU和GPU用两种不同的思路实现了计算能力最大化。而基于不同的设计思路,两者的应用场景也是大不相同,CPU适合用于逻辑控制,串行的计算场景,而GPU适合用于大规模的并行计算场景。对图像数据的应用就是一种并行计算场景,图像数据由很多像素点组成,各个像素相互独立,并行存在的。,因此GPU最早用于图像渲染等操作。而最近,利用深度学习解决图像问题的场景也很适合用GPU计算。
言归正传,为了让上述的GPU能够发挥作用,CUDA应运而生。CUDA的诞生就是为了让GPU能够有可用的编程环境,使得开发人员可以用程序控制GPU的硬件进行并行计算。所以本质上,CUDA是一个软件体系,如下图所示,该体系结构三部分组成:
- CUDA驱动API
可以通过直接操纵硬件来实现GPU的使用,但编程复杂,编程难度大,类似与汇编语言。(函数前缀为cu
) - CUDA运行时API
对驱动API中的操作进行了一次封装,使用起来相对更友好,因此在编程过程中使用会比驱动API的频率要高。需要注意的是不可以和驱动API混合使用。(函数前缀为cuda
) - CUDA函数库(官方和第三方)
为了实现更高级的功能,官方或者第三方开发者提供的针对于某个领域的高级函数库,使得普通开发人员能够快速上手实现定制化功能。比如我们安装CUDA时经常会要连带安装的CUDNN,这就是针对于卷积计算的CUDA函数库,使得深度学习开发者能够很容易的调用CUDA实现深度学习算法的构建。
当然如上图所示,当开发人员编写CUDA应用程序时,可以通过直接调用底层的驱动API来调用GPU。也可以通过调用CUDA运行时API间接调用GPU。当然也可以通过直接使用GUDA函数库,进一步简化开发过程。而目前大部分GUDA应用程序开发者使用的都是后两种策略(就先现在很少有人用汇编语言开发功能一样)。CUDA应用程序是直接支持C语言开发的,当然随着CUDA版本的更迭,目前已经支持C++11了。
最后当开发人员利用C语言编写好CUDA应用程序后,还需要用特殊的编译器将我们程序员能够看懂的C语言,编译成计算,GPU能够识别的机器语言。如上图所示,CUDA的应用程序是以CPU作为宿主,然后达到操纵GPU的目的,所以最终真正运行时整个解决方案中既有运行在CPU上的代码,也会有运行在GPU上的代码。NVCC编译器就是专门针对这种情形开发出来的编译器。最终通过编译,开发人员就可以顺利操作GPU啦~
网友评论