● GPU内部通用计算代码运算过程
在绘制图像时,GPU首先接收宿主系统以三角顶点形式发送的几何数据。这些顶点数据由一个可编程的顶点处理器进行处理,该处理器可以完成几何变换、亮度计算等任何三角形计算。接下来,这些三角形由一个固定功能的光栅器转换成显示在屏幕上的单独“碎片(fragment)”。在屏幕显示之前,每个碎片都通过一个可编程的碎片处理器计算最终颜色值。
计算碎片颜色的运算一般包括集合向量数学操作以及从“纹理”中提取存储数据,“纹理”是一种存储表面材料颜色的位图。最终绘制的场景可以显示在输出设备上,或是从GPU的存储器重新复制到宿主处理器中。
0 && image.height>0){if(image.width>=700){this.width=700;this.height=image.height*700/image.width;}}" style="BORDER-BOTTOM: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-RIGHT: black 1px solid" alt="从Folding@home项目看GPU通用计算发展 " align=no src="http://2e.zol-img.com.cn/product/46_500x2000/204/ceAxCLejQroE.jpg" _fcksavedurl="http://2e.zol-img.com.cn/product/46_500x2000/204/ceAxCLejQroE.jpg">
两向量相加的简单Brook代码示例
图为执行两向量相加的简单Brook代码示例。Brook支持所有带附加流数据的C句法,流数据存储于GPU的存储器中,而核函数也在GPU上执行。可编程顶点处理器和碎片处理器提供了许多相同的功能和指令集。但是,大部分GPU编程人员只将碎片处理器用于通用计算任务,因为它通常提供更优的性能,而且可以直接输出到存储器。
利用碎片处理器进行计算的一个简单例子是对两个向量进行相加。首先,我们发布一个大三角形,其所包含的碎片数量和向量大小(容纳的元素)相同。产生的碎片通过碎片处理器进行处理,处理器以单指令多数据(SIMD)的并行方式执行代码。进行向量相加的代码从存储器中提取两个待加元素,并根据碎片的位置进行向量相加,同时为结果分配输出颜色。输出存储器保存了向量和,这个值在下一步计算中可以被任意使用。
可编程碎片处理器的ISA类似于DSP或Pentium SSE的指令集,由四路SIMD指令和寄存器组成。这些指令包括标准数学运算、存储器提取指令和几个专用图形指令。
● 更加优秀的通用计算API
优秀的编程模型能给帮助基于此架构的产品迅速发展,在这个领域各家厂商都尽全力推广自己的编程架构,因为只有程序员认可这套编程模型,最终的产品才有生命力。目前的“OpenCL”、“Stream”、“Compute Shader”和“CUDA模型C语言包”都是面向异构系统通用目的并行编程的开放式、免费标准,也是统一的编程环境。便于软件开发人员为高性能计算服务器、桌面计算系统、手持设备编写高效轻便的代码,而且广泛适用于多核心处理器(CPU)、图形处理器(GPU)、Cell类型架构以及数字信号处理器(DSP)等其他并行处理器,在游戏、娱乐、科研、医疗等各种领域都有广阔的发展前景。
0 && image.height>0){if(image.width>=700){this.width=700;this.height=image.height*700/image.width;}}" style="BORDER-BOTTOM: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-RIGHT: black 1px solid" alt="从Folding@home项目看GPU通用计算发展 " align=no src="http://2c.zol-img.com.cn/product/46_500x2000/190/ceK9OoQ6Y6hsQ.jpg" _fcksavedurl="http://2c.zol-img.com.cn/product/46_500x2000/190/ceK9OoQ6Y6hsQ.jpg">
众多厂商鼎力相助的OpenCL工作组
OpenCL实际上是针对异构系统进行并行编程的一个全新的API,OpenCL可以利用GPU进行一些并行计算的工作。我们知道,图形里面有很多API,比如OpenGL是针对图形的,而OpenCL则是针对并行计算的API。OpenCL开发人员可以利用GPU和CPU的计算能力,把GPU和CPU异构的系统运用在很多并行计算的领域。
Stream是AMD提出的GPGPU编程接口。基本上还是基于一种传统CPU的一种方式,Stream主要包括CAL与Brook+。CAL是一套指令集,可以用汇编语言的方式来开发软件,然而我们汇编方式开发软件的话,对搞计算的人来说不大现实,让他们用汇编语言来说的话可能确实是一个折磨。Brook+是斯坦福大学开发的,它是类似于C语言的东西,是把底层GPGPU的计算方式类似于C的这种语言,这里要说明的是Brook+不是C语言而是类C语言,语法和C语言比较类似。
Compute Shader技术是微软DirectX 11 API新加入的特性,在Compute Shader的帮助下,程序员可直接将GPU作为并行处理器加以利用,GPU将不仅具有3D渲染能力,也具有其他的运算能力,也就是我们说的GPGPU的概念和物理加速运算。多线程处理技术使游戏更好地利用系统的多个核心。Compute Shader主要特性包括线程间数据通信、一整套随机访问和流式I/O操作基本单元等,能加快和简化图像和后期处理效果等已有技术,也为DX11级硬件的新技术做好了准备,对于游戏和应用程序开发有着很重大的意义。
而NVIDIA提出的CUDA架构主要包含两个方面:一个是ISA指令集架构;第二硬件计算引擎;实际上是硬件和指令集。也就是说我们可以把CUDA看作是与X86或者cell类似的架构,但是CUDA基于GPU,而不是传统的CPU。实际上CUDA是NVIDIA的GPGPU模型,它使用C语言为基础,可以直接以大多数人熟悉的C语言,写出在显示芯片上执行的程序,而不需要去学习特定的显示芯片的指令或是特殊的结构。
0 && image.height>0){if(image.width>=700){this.width=700;this.height=image.height*700/image.width;}}" style="BORDER-BOTTOM: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-RIGHT: black 1px solid" alt="从Folding@home项目看GPU通用计算发展 " align=no src="http://2f.zol-img.com.cn/product/46_500x2000/205/ceenA6Usv6kKo.jpg" _fcksavedurl="http://2f.zol-img.com.cn/product/46_500x2000/205/ceenA6Usv6kKo.jpg">
OpenCL与CUDA在编程模式方面的区别
OpenCL是一个API,在{dy}个级别,CUDA架构是更高一个级别,在这个架构上不管是OpenCL还是DX11这样的API,还是像C语言、Fortran、DX11 Computer Shader,都可以支持。作为程序开发员来讲,一般他们只懂这些语言或者API,可以采用多种语言开发自己的程序,不管他选择什么语言,只要是希望调用GPU的计算能,在这个架构上都可以用CUDA来编程。CUDA架构与OpenCL是包容关系,我们把他们放在同一级别进行讨论本来就是错误的,与OpenCL在同一级别不是CUDA架构,而是CUDA的C语言包,也就是我们常说的CUDA版本。
Folding@home项目的GPU客户端版本是最早利用Stream来开发的应用软件之一,当然也是名气{zd0}的。NVIDIA进入以后使用CUDA的语言来写Folding@home客户端的软件,CUDA的C语言包可以说是真正在GPU上运行的C语言,脱离了对图形学API的依赖,它近乎xx地使用了C语言的存储体系,把大部分的数据尽可能的在Shared memory上进行计算。极大提高GPU运算效率。
不管C语言还是Fortran,与OpenCL、Computer Shader这种API都是长期共存的关系。通过GPU通用编程语言的迅速发展,我们非常欣喜地看到越来越多的通用计算程序出现,显卡已经远远不止是娱乐工具,而变身为高性能并行计算机。优秀的编程模型配合高性能硬件系统,让个人和小型科研机构也可以非常轻松地配置自己的高性能计算机平台。
● 着色器模型变化历程与总结
在图形渲染中,GPU中的可编程计算单元被称为着色器(Shader),着色器的性能由DirectX中规定的Shader Model来区分。GPU中最主要的可编程单元式顶点着色器和像素着色器。
为了实现更细腻逼真的画质,GPU的体系架构从最早的固定单元流水线到可编程流水线,到DirectX 8初步具备可编程性,再到DirectX 10时代的以通用的可编程计算单元为主、图形固定单元为辅的形式,{zx1}的DirectX 11更是明确提出通用计算API Direct Compute概念,鼓励开发人员和用户更好地将GPU作为并行处理器使用。在这一过程中,着色器的可编程性也随着架构的发展不断提高,下表给出的是每代模型的大概特点。
表:Shader Model版本演化与特点
Shader Model |
GPU代表 |
显卡时代 |
特点 |
|
1999年{dy}代NV Geforce256 |
DirectX 7 1999~2001 |
GPU可以处理顶点的矩阵变换和进行光照计算(T&L),操作固定,功能单一,不具备可编程性 |
SM 1.0 |
2001年第二代NV Geforce3 |
DirectX 8 |
将图形硬件流水线作为流处理器来解释,顶点部分出现可编程性,像素部分可编程性有限(访问纹理的方式和格式受限,不支持浮点) |
SM 2.0 |
2003 年 ATI R300 和第三代NV Geforce FX |
DirectX 9.0b |
顶点和像素可编程性更通用化,像素部分支持FP16/24/32浮点,可包含上千条指令,处理纹理更加灵活:可用索引进行查找,也不再限制[0,1]范围,从而可用作任意数组(这一点对通用计算很重要) |
SM 3.0 |
2004年 第四代NV Geforce 6 和 ATI X1000 |
DirectX 9.0c |
顶点程序可以访问纹理VTF,支持动态分支操作,像素程序开始支持分支操作(包括循环、if/else等),支持函数调用,64位浮点纹理滤波和融合,多个绘制目标 |
SM 4.0 |
2007年 第五代NV G80和ATI R600 |
DirectX 10 2007~2009 |
统一渲染架构,支持IEEE754浮点标准,引入Geometry Shader(可批量进行几何处理),指令数从1K提升至64K,寄存器从32个增加到4096个,纹理规模从16+4个提升到128个,材质Texture格式变为硬件支持的RGBE格式,{zg}纹理分辨率从2048*2048提升至8192*8192 |
SM 5.0 |
2009年 ATI RV870 和2010年NV GF100 |
DirectX 11 2009~ |
明确提出通用计算API Direct Compute概念和Open CL分庭抗衡,以更小的性能衰减支持IEEE754的64位双精度浮点标准,硬件Tessellation单元,更好地利用多线程资源加速多个GPU |
传统的分离架构中,两种着色器的比例往往是固定的。在GPU核心设计完成时,各种着色器的数量便确定下来,比如xx的“黄金比例”——顶点着色器与像素着色器的数量比例为1:3。但不同的游戏对顶点资源和像素资源的计算能力要求是不同的。如果场景中有大量的小三角形,则顶点着色器必须满负荷工作,而像素着色器则会被闲置;如果场景中有少量的大三角形,又会发生相反的情况。因此,固定比例的设计无法xx发挥GPU中所有计算单元的性能。
顶点着色单元(Vertex Shader,VS)和像素着色单元(Pixel Shader,PS)两种着色器的架构既有相同之处,又有一些不同。两者处理的都是四元组数据(顶点着色器处理用于表示坐标的w、x、y、z,但像素着色器处理用于表示颜色的a、r、g、b),顶点渲染需要比较高的计算精度;而像素渲染则可以使用较低的精度,从而可以增加在单位面积上的计算单元数量。在Shader Model 4.0之前,两种着色器的精度都在不断提高,但同期顶点着色器的精度要高于像素着色器。
Shader Model 4.0统一了两种着色器,所以顶顶点和像素着色器的规格要求xx相同,都支持32位浮点数。这是GPU发展的一个分水岭;过去只能处理顶点和只能处理像素的专门处理单元被统一之后,更加适应通用计算的需求。
DirectX 11提出的Shader Model 5.0版本继续强化了通用计算的地位,微软提出的全新API——Direct Compute将把GPU通用计算推向新的{df}。同时Shader Model 5.0是xx针对流处理器而设定的,所有类型的着色器,如:像素、顶点、几何、计算、Hull和Domaim(位于Tessellator前后)都将从新指令集中获益。
● GPU通用计算正在快速普及
GPU是半导体芯片领域少数发展迅速同时应用范围得到极大扩展的芯片。自诞生起,GPU就将摩尔定律的定义大大扩展。研究表明,从1993年开始,GPU的性能以每年2.8倍的速度增长,这个数字大大超过了PC其他子系统的发展速度。在高密度的大规模并行运算领域,GPU已经xx有实力和传统的CPU竞争。
0 && image.height>0){if(image.width>=700){this.width=700;this.height=image.height*700/image.width;}}" style="BORDER-BOTTOM: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-RIGHT: black 1px solid" alt="从Folding@home项目看GPU通用计算发展 " align=no src="http://2c.zol-img.com.cn/product/46_500x2000/208/ceuNCZF7VlQv2.png" _fcksavedurl="http://2c.zol-img.com.cn/product/46_500x2000/208/ceuNCZF7VlQv2.png">
GPU运算能力约为同等级CPU十倍
截止2008年末,全球拥有1亿颗以上支持通用计算与编程的GPU产品,开发人员超过了2.5万人,全世界有50多所大学开设了GPU并行编程与应用课程,包括中国科学院、清华大学等,一个基于GPU的计算生态圈已初步形成。普通玩家也应该顺应潮流,不要固步自封只是把GPU当成娱乐工具,或者把CPU当作电脑中{wy}的运算处理器,在更多领域大胆尝试GPU这种高密度运算器的优势。相信通用计算项目在不久的将来也必将成为显卡决胜的新战场。