GPU编程--CPU和GPU的设计区别
本篇结构
前⾔
概论
CPU简介
GPU简介
并⾏计算
CPU/GPU对⽐
适于GPU计算的场景
GPU开发环境
参考博⽂
⼀、前⾔
因为⼯作需要,需要从github上⼀个CUDA的DBSCAN聚类实现,刚开始从github上获取到的代码只⽀持⼆维数据,为了适配多维数据,要对代码简单改造,这就需要了解CUDA编程模式。之前没有接触过GPU编程相关概念,甚⾄于没有学过c语⾔,加上脑袋笨重,费了好些功夫,才让CUDA DBSCAN运⾏起来。
为了⽅便⾃⼰后⾯回顾,所以将涉及到的知识点简单串联起来,并加以记录。
如果可以,也希望给其他朋友⼀些can参考(肯定是有很多不⾜,还望海涵)。
⼆、概论
由于其设计⽬标的不同,GPU和CPU分别针对了两种不同的应⽤场景。
CPU需要很强的通⽤性来处理各种不同的数据类型,同时⼜要逻辑判断⼜会引⼊⼤量的分⽀跳转和中断的处理。这些都使得CPU的内部结构异常复杂。
⽽GPU⾯对的则是类型⾼度统⼀的、相互⽆依赖的⼤规模数据和不需要被打断的纯净的计算环境。
三、CPU简介
CPU (Central Processing Unit) 即中央处理器,是机器的“⼤脑”,也是布局谋略、发号施令、控制⾏动的“总司令官”。
CPU的结构主要包括运算器(ALU, Arithmetic and Logic Unit)、控制单元(CU, Control Unit)、寄存器(Register)、⾼速缓存器(Cache)和它们之间通讯的数据、控制及状态的总线。
CPU是基于低延时的设计,简单来说包括:计算单元、控制单元和存储单元,架构可参考下图:
CPU的特点是:
(1)CPU有强⼤的ALU(算术运算单元),它可以在很少的时钟周期内完成算术计算
当今的CPU可以达到64bit 双精度。执⾏双精度浮点源算的加法和乘法只需要1~3个时钟周期(CPU的时钟周期的频率是⾮常⾼的,达到1.532~3gigahertz(千兆HZ, 10的9次⽅))。
(2)⼤的缓存可以降低延时
保存很多的数据放在缓存⾥⾯,当需要访问的这些数据,只要在之前访问过的,如今直接在缓存⾥⾯取即可。
(3)复杂的逻辑控制单元
当程序含有多个分⽀的时候,它通过提供分⽀预测的能⼒来降低延时。
数据转发。当⼀些指令依赖前⾯的指令结果时,数据转发的逻辑控制单元决定这些指令在pipeline中的位置并且尽可能快的转发⼀个指令的结果给后续的指令。这些动作需要很多的对⽐电路单元和转发电路单元。
四、GPU简介
GPU全称为Graphics Processing Unit,中⽂为图形处理器,就如它的名字⼀样,GPU最初是⽤在个⼈电脑、⼯作站、游戏机和⼀些移动设备(如平板电脑、智能⼿机等)上运⾏绘图运算⼯作的微处理器。
GPU是基于⼤的吞吐量设计,GPU简单架构参考下图:
GPU的特点是:
(1)有很多的ALU和很少的cache
缓存的⽬的不是保存后⾯需要访问的数据的,这点和CPU不同,⽽是为thread提⾼服务的。如果有很多线程需要访问同⼀个相同的数据,缓存会合并这些访问,然后再去访问dram(因为需要访问的数据保存在dram中⽽不是cache⾥⾯),获取数据后cache会转发这个数据给对应的线程,这个时候是数据转发的⾓⾊。但是由于需要访问dram,⾃然会带来延时的问题。
(2)GPU的控制单元(左边黄⾊区域块)可以把多个的访问合并成少的访问。
(3)GPU的虽然有dram延时,却有⾮常多的ALU和⾮常多的thread
为了平衡内存延时的问题,GPU可以充分利⽤多的ALU的特性达到⼀个⾮常⼤的吞吐量的效果。尽可能多的分配Threads。
五、并⾏计算
在对⽐CPU/GPU前,先了解下并⾏并⾏计算。
并⾏计算(Parallel Computing)是指同时使⽤多种计算资源解决计算问题的过程,是提⾼计算机系统计算速度和处理能⼒的⼀种有效⼿段。它的基本思想是⽤多个处理器来共同求解同⼀问题,即将被求解的问题分解成若⼲个部分,各部分均由⼀个独⽴的处理机来并⾏计算。
并⾏计算可分为时间上的并⾏和空间上的并⾏。
时间上的并⾏是指流⽔线技术,⽐如说⼯⼚⽣产⾷品的时候分为四步:清洗-消毒-切割-包装。
如果不采⽤流⽔线,⼀个⾷品完成上述四个步骤后,下⼀个⾷品才进⾏处理,耗时且影响效率。但是采⽤流⽔线技术,就可以同时处理四个⾷品。这就是并⾏算法中的时间并⾏,在同⼀时间启动两个或两个以上的操作,⼤⼤提⾼计算性能。
空间上的并⾏是指多个处理机并发的执⾏计算,即通过⽹络将两个以上的处理机连接起来,达到同时计算同⼀个任务的不同部分,或者单个处理机⽆法解决的⼤型问题。
⽐如⼩李准备在植树节种三棵树,如果⼩李1个⼈需要6个⼩时才能完成任务,植树节当天他叫来了好朋友⼩红、⼩王,三个⼈同时开始挖坑植树,2个⼩时后每个⼈都完成了⼀颗植树任务,这就是并⾏算法中的空间并⾏,将⼀个⼤任务分割成多个相同的⼦任务,来加快问题解决速度。
六、CPU/GPU对⽐
CPU:
CPU的架构中需要⼤量的空间去放置存储单元(橙⾊部分)和控制单元(黄⾊部分),相⽐之下计算单元(绿⾊部分)只占据了很⼩的⼀部分,所以它在⼤规模并⾏计算能⼒上极受限制,⽽更擅长于逻辑控制。
CPU遵循的是冯诺依曼架构,其核⼼就是:存储程序,顺序执⾏。这使得CPU就像是个⼀板⼀眼的管家,⼈们吩咐的事情它总是⼀步⼀步来做。但是随着⼈们对更⼤规模与更快处理速度的需求的增加,这位管家渐渐变得有些⼒不从⼼。
GPU:
GPU的构成相对简单,有数量众多的计算单元和超长的流⽔线,特别适合处理⼤量的类型统⼀的数据。
GPU的⼯作⼤部分都计算量⼤,但没什么技术含量,⽽且要重复很多很多次。GPU就是⽤很多简单的计算单元去完成⼤量的计算任务,纯粹的⼈海战术。这种策略基于⼀个前提,就是并⾏计算的线程之间没有什么依赖性,是互相独⽴的。
GPU在处理能⼒和存储器带宽上相对于CPU有明显优势,在成本和功耗上也不需要付出太⼤代价。由于图形渲染的⾼度并⾏性,使得GPU 可以通过增加并⾏处理单元和存储器控制单元的⽅式提⾼处理能⼒和存储器带宽。GPU设计者将更多的晶体管⽤作执⾏单元,⽽不是像CPU那样⽤作复杂的控制单元和缓存并以此来提⾼少量执⾏单元的执⾏效率。
但GPU⽆法单独⼯作,必须由CPU进⾏控制调⽤才能⼯作。CPU可单独作⽤,处理复杂的逻辑运算和不同的数据类型,但当需要⼤量的处理类型统⼀的数据时,则可调⽤GPU进⾏并⾏计算。
另外:CPU的整数计算、分⽀、逻辑判断和浮点运算分别由不同的运算单元执⾏,此外还有⼀个浮点加速器。因此,CPU⾯对不同类型的计算任务会有不同的性能表现。⽽GPU是由同⼀个运算单元执⾏整数和浮点计算,因此,GPU的整型计算能⼒与其浮点能⼒相似。
关于GPU和CPU,知乎上有个不是很雅观的例⼦:
就像有个⼯作需要算⼏亿次⼀百以内加减乘除⼀样,因为这些计算没有太⼤的难度,⼀个办法是雇上⼏⼗个⼩学⽣⼀起算,⼀⼈算⼀部分,算是个体⼒活。
GPU就是这样,⽤很多简单的计算单元去完成⼤量的计算任务,纯粹的⼈海战术。但是这种策略基于⼀个前提,就是⼩学⽣A和⼩学⽣B的⼯作没有什么依赖性,是互相独⽴的。很多涉及到⼤量计算的问题基本都有这种特性,⽐如你说的破解密码,挖矿和很多图形学的计算。这些计算可以分解为多个相同的简单⼩任务,每个任务就可以分给⼀个⼩学⽣去做。
CPU就像⽼教授,积分微分都会算,就是⼯资⾼,⼀个⽼教授资顶⼆⼗个⼩学⽣。有⼀些任务并不是简单的计算,⼆是涉及
到“流”的问题。⽐如你去相亲,双⽅看着顺眼才能继续发展。总不能你这边还没见⾯呢,那边⼈把证都给领了。这种⽐较复杂的问题都是CPU来做的。
厉害的编程代码总⽽⾔之,因为最初⽤来处理的任务就不同,所以CPU和GPU设计上有不⼩的区别。GPU的运算速度取决于雇了多少⼩学⽣,CPU的运算速度取决于请了多么厉害的教授。教授处理复杂任务的能⼒是碾压⼩学⽣的,但是对于没那么复杂的任务,还是顶不住⼈多。当然现在的GPU也能做⼀些稍微复杂的⼯作了,相当于升级成初中⽣⾼中⽣的⽔平。但还需要CPU来把数据喂到嘴边才能开始⼲活,究竟还是靠CPU来管的。
七、适于GPU计算的场景
尽管GPU计算已经开始崭露头⾓,但GPU并不能完全替代X86解决⽅案。很多操作系统、软件以及部分代码现在还不能运⾏在GPU上,所谓的GPU+CPU异构超级计算机也并不是完全基于GPU进⾏计算。⼀般⽽⾔适合GPU运算的应⽤有如下特征:
运算密集
⾼度并⾏
控制简单
分多个阶段执⾏
GPU计算的优势是⼤量内核的并⾏计算,瓶颈往往是I/O带宽,因此适⽤于计算密集型的计算任务。
PS:所谓计算密集型(Compute-intensive)的程序,就是其⼤部分运⾏时间花在了寄存器运算上,寄存器的速度和处理器的速度相当,从寄存器读写数据⼏乎没有延时。可以做⼀下对⽐,读内存的延迟⼤概是⼏百个时钟周期;读硬盘的速度就不说了,即便是SSD,也实在是太慢了。
⼋、GPU开发环境
**CG(C for Graphics)**是为GPU编程设计的⾼级绘制语⾔,由NVIDIA和微软联合开发,微软版本叫HLSL,CG是NVIDIA版本。Cg极⼒保留C语⾔的⼤部分语义,并让开发者从硬件细节中解脱出来,Cg同时也有⼀个⾼级语⾔的其他好处,如代码的易重⽤性,可读性得到提⾼,编译器代码优化。
**CUDA(ComputeUnified DeviceArchitecture,统⼀计算架构)**是由NVIDIA所推出的⼀种集成技术,是该公司对于GPGPU的正式名称。通过这个技术,⽤户可利⽤NVIDIA的GeForce8以后的GPU和较新的QuadroGPU进⾏计算。亦是⾸次可以利⽤GPU作为C-编译器的开发环境。NVIDIA营销的时候,往往将编译器与架构混合推⼴,造成混乱。实际上,CUDA架构可以兼容OpenCL或者⾃家的C-编译器。⽆论是CUDAC-语⾔或是OpenCL,指令最终都会被驱动程序转换成PTX代码,交由显⽰核⼼计算。
ATIStream是AMD针对旗下图形处理器(GPU)所推出的通⽤并⾏计算技术。利⽤这种技术可以充分发挥AMDGPU的并⾏运算能⼒,⽤于对软件进⾏加速或进⾏⼤型的科学运算,同时⽤以对抗竞争对⼿的NVIDIA CUDA技术。与CUDA技术是基于⾃⾝的私有标准不
同,ATIStream技术基于开放性的OpenCL标准。
**OpenCL(Open Computing Language,开放计算语⾔)**是⼀个为异构平台编写程序的框架,此异构平台可由CPU,GPU或其他类型的处理器组成。OpenCL由⼀门⽤于编写kernels(在OpenCL设备上
运⾏的函数)的语⾔(基于C99)和⼀组⽤于定义并控制平台的API组成。OpenCL提供了基于任务分区和数据分区的并⾏计算机制。
OpenCL类似于另外两个开放的⼯业标准OpenGL和OpenAL,这两个标准分别⽤于三维图形和计算机⾳频⽅⾯。OpenCL扩展了GPU⽤于图形⽣成之外的能⼒。OpenCL由⾮盈利性技术组织KhronosGroup掌管。
下⾯是对⼏种GPU开发环境的简单评价:
CG:优秀的图形学学开发环境,但不适于GPU通⽤计算开发。
ATIStream:硬件上已经有了基础,但只有低层次汇编才能使⽤所有的硬件资源。⾼层次的brook是基于上⼀代GPU的,缺乏良好的编程模型。
OpenCL:开放标准,抽象层次较低,较多对硬件的直接操作,代码需要根据不同硬件优化。
CUDA:仅能⽤于NVIDIA的产品,发展相对成熟,效率⾼,拥有丰富的⽂档资源。
九、参考博⽂
想更好理解CPU和GPU的区别,可以参考下⾯的博⽂:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论