现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

10年GPU通用计算回顾

2014-06-22 06:32 工业·编程 ⁄ 共 19009字 ⁄ 字号 暂无评论

前言:从世界上第一款GPU横空出世到今天,显卡已经走过了10年历史。GPU在这10年演变过程中,我们看到GPU从最初帮助CPU分担几何吞吐量,到Shader单元初具规模,然后出现Shader单元可编程性,到今天GPU通用计算领域蓬勃发展这一清晰轨迹。

这10年包含了无数设计者艰辛努力的成果,GPU也用自己的发展速度创造了半导体行业的奇迹,而GPU当今成就的见证者,正是我们的无数硬件玩家和游戏爱好者。我们可以肯定以GPU诞生初期的设计定位和市场需求,没有人敢相信今天GPU能走上通用计算这条道路,正所谓无心插柳柳成荫。

● 硬件T&L单元催生GPU诞生

    Geforce 256——代号NV10于1999年8月发布。这是图形芯片领域开天辟地的产品,也是第一款提出GPU概念的产品。GPU英文全称Graphic Processing Unit,中文翻译为“图形处理器”。Geforce 256所采用的核心技术有硬体T&L、立方环境材质贴图和顶点混合、纹理压缩和凹凸映射贴图、双重纹理四像素256位渲染引擎等,而硬体T&L技术可以说是GPU的标志。

无心插柳柳成荫 GPU通用计算十年发展
Geforce 256诞生

    1999年,已经凭借RivaTNT2在图形芯片界立足的NVIDIA,主动放弃帮自己打下江山的Riva品牌,新启用的Geforce强调力量并沿用至今,并衍生出驱动品牌Forceware及芯片组品牌nForce。

    Geforce256之所以被称作GPU原因就在于Geforce256划时代的在图形芯片内部集成了T&L(几何光照转换)功能,使得GPU拥有初步的几何处理能力,彻底解决了当时众多游戏瓶颈发生在CPU几何吞吐量不够的瓶颈。

    Geforce 256显卡的出色表现,NVIDIA强大的技术实力得到全面释放,这块显卡是真正的全面领先型产品,而不是靠16bit色和32bit色的区域优势或者是单纯依赖特定的3D API支持。

    T&L几何光照转换原先由CPU负责,或者由另一个独立处理机来负责处理(例如一些旧式工作站显视卡)。较强劲的3dfx Voodoo2 和 Rendition Verite显示核心已整合了几何(三角形)建构,但硬件T&L仍是一大进步,原因是拥有该技术的显示核心从CPU接管了大量工作。硬件T&L单元让Geforce 256几乎成为一个全新的GPU标准,也让GPU更加独立自主。

无心插柳柳成荫 GPU通用计算十年发展
DirectX 7.0推出获得众多支持

    不可否认在成功的背后,离不开微软推出的图形API——DirectX 7.0的鼎力支持。DirectX 7.0最大的特色就是支持T&L,在T&L问世之前,位置转换和灯光都需要CPU来计算,CPU速度越快,游戏表现越流畅。使用了T&L功能后,这两种效果的计算用显示卡的GPU来计算,这样就可以把CPU从繁忙的劳动中解脱出来。同时从另一个角度提升了GPU在PC系统中的地位。

    值得一提的是GeForce2首开了GPU通用计算的先河,凭借其强大的多纹理处理性能,结合纹理环境参数和纹理函数可以实现一些很灵活的应用。它具有Texture Shader以及Register Combiner单元,有一定的数值计算能力。开发人员可以利用Texture Shader的依赖纹理进行数据访问,用Register Combiner进行计算。GeForce2被用于求解数学上的扩散方程,成为GPU通用计算的最早应用。

● Shader单元概念形成,GPU开始走上“邪路”

    面向图形计算,让GPU逐渐找到了自己的方向,这个方向就是给予用户更真更快地视觉体验,但是GPU架构也遇到一些问题亟待解决。首要问题就是,要实现更加复杂多变的图形效果,不能仅仅依赖三角形生成和固定光影转换。

    虽然当时游戏画面的提高基本上都是通过大量的多边形、更复杂的贴图来实现的。但是后期发展中,顶点和像素运算的需求量猛增。每个顶点都包含许多信息,比顶点上的纹理信息,散光和映射光源下表现的颜色,所以在生成多边形的时候带上这些附加运算,就可以带来更多的效果,但这也更加考验顶点和像素计算能力。研究人员发现,同硬件T&L仅仅实现的固定光影转换相比,VS和PS单元的灵活性更大。

    可编程模型与旧有的预定义模型是不同的。这种模型中,数据是透过virtual machine以一个类似于带有特殊汇编指令集的pre-arranged(事先安排好)程序进行处理的,程序员可以直接对其进行编程。

    凭借可编程几何管线和可编程像素管线,使用者可以自由的控制几何和像素的代码设计。这对于图形开发者是空前的,他们可以通过基本的着色器,利用开发工具,产生全新的、极具创造力的效果。也正是可编程管线的引入,为GPU发展翻开了新的篇章,GPU开始向SIMD处理器方向发展,凭借强大的并行处理性能,使得GPU开始用有了部分流式处理器特征。

无心插柳柳成荫 GPU通用计算十年发展
UT2003已经模拟出比较真实的场景

    Shader概念的提出,意味着程序员可通过它们实现3D场景构建的难度大大降低。通过VS和PS的渲染,可以很容易的宁造出真实的水面动态波纹光影效果。此时DirectX的权威地位终于建成。

    Pixel Shader(顶点着色器)和Vertex Shader(像素着色器)硬件逻辑,真正支持像素和顶点的可编程。虽然当时可编程性很弱,硬件限制太多,顶点部分出现可编程性,像素部分可编程性有限。但这的确是硬件T&L之后PC图形技术的又一重大飞跃。3D娱乐的视觉体验也因此向接近真实迈进了一大步,波光粼粼的水面是那个时期用于演示Shader能力的典型DEMO,相比之下DirectX 7绘制的水面效果就单调得多。

    Shader单元概念提出之后,无论NVIDIA还是ATI,都在做强显卡前端(Setup Engine及其相关部分,如光栅器Rasterizer、设定Setup和顶点装配器Vertex Assembler)的同时,逐渐将竞争重点放在显卡核心部分——Pixel Shader(顶点着色器)和Vertex Shader(像素着色器),无论是Radeon 8500还是Geforce Ti 4200都内置的规格和频率更强的PS和VS单元。同时显卡的后端ROP(光栅化引擎,负责完成像素的输出)也逐渐强大,各种各样的多重采样AA模式和更高的抗锯齿模式逐步得以实现。

● Shader Model 2.0时代到来,Shader编程性逐步增强

    随后到来的DirectX 9.0时代,让Shader单元具备了更强的可编程性。2002年底微软发布的DirectX9.0中,PS单元的渲染精度已达到浮点精度,传统的硬件T&L单元也被取消。全新的Vertex Shader(顶点着色引擎)编程将比以前复杂得多,新的Vertex Shader标准增加了流程控制,更多的常量,每个程序的着色指令增加到了1024条。

    PS 2.0具备完全可编程的架构,能对纹理效果即时演算、动态纹理贴图,还不占用显存,理论上对材质贴图的分辨率的精度提高无限多;另外PS1.4只能支持28个硬件指令,同时操作6个材质,而PS2.0却可以支持160个硬件指令,同时操作16个材质数量,新的高精度浮点数据规格可以使用多重纹理贴图,可操作的指令数可以任意长,电影级别的显示效果轻而易举的实现。

无心插柳柳成荫 GPU通用计算十年发展
Mark 2003第四项游戏测试Mother Nature

    基于Shader Model 2.0的3D Mark 2003第四项游戏测试Mother Nature,对Shader单元运算复杂度和材质大小提出非常严苛的要求,当时只有高端显卡才能流畅通过该测试。

    VS 2.0通过增加Vertex程序的灵活性,显著的提高了老版本(DirectX 8)的VS性能,新的控制指令,可以用通用的程序代替以前专用的单独着色程序,效率提高许多倍;增加循环操作指令,减少工作时间,提高处理效率;扩展着色指令个数,从128个提升到256个。

    最重要的一点改进是增加对浮点数据的处理功能,以前GPU只能对整数进行处理,改进后提高渲染精度,使最终处理的色彩格式达到电影级别。Shader Model 2.0时代突破了以前限制PC图形图象质量在数学上的精度障碍,它的每条渲染流水线都升级为128位浮点颜色,让游戏程序设计师们更容易更轻松的创造出更漂亮的效果,让程序员编程更容易。而从通用性方面理解,支持浮点运算让GPU已经具备了通用计算的基础,这一点是至关重要的。

    如果说DirectX 8中的Shader单元还是个简单尝试的话,DirectX 9中的Shader则成为了标准配置。除了版本升级到2.0外,DirectX 9中PS单元的渲染精度已达到浮点精度,传统的硬件T&L单元也被取消,在较低DirectX版本游戏运行时会使用VS单元模拟执行硬件T&L单元的功能。

● Shader计算能力快速发展,灵活度不断提升

    在图形渲染中,GPU中的可编程计算单元被称为着色器(Shader),着色器的性能由DirectX中规定的Shader Model来区分。GPU中最主要的可编程单元式顶点着色器和像素着色器。

    为了实现更细腻逼真的画质,GPU的体系架构从最早的固定单元流水线到可编程流水线,到DirectX 8初步具备可编程性,再到DirectX 10时代的以通用的可编程计算单元为主、图形固定单元为辅的形式,最新的DirectX 11更是明确提出通用计算API Direct Compute概念,鼓励开发人员和用户更好地将GPU作为并行处理器使用。

    图形流水线中可编程单元的行为由Shader单元定义,并可以由高级的Shading语言(例如NV的Cg,OpenGL的GLSL,Microsoft的HLSL)编写。Shader源码被译为字节码,然后在运行时由驱动程序将其转化为基于特定GPU的二进制程序,具备可移植性好等优势。传统的图形渲染流线中有两种不同的可编程着色器,分别是顶点着色单元(Vertex Shader,VS)和像素着色单元(Pixel Shader,PS)。表一和表二比较详细地罗列出从Shader 2.0到Shader 4.0像素着色单元和顶点着色单元的演进过程。

无心插柳柳成荫 GPU通用计算十年发展
表一 Pixel Shader像素着色器单元的演进

无心插柳柳成荫 GPU通用计算十年发展
表二 Vertex Shader顶点着色器单元的演进

表中:PS 2.0 = DirectX 9.0 original Shader Model 2 specification。

PS 2.0a = NVIDIA Geforce FX-optimized model。

PS 2.0b = ATI Radeon X700 X800 X850 shader model,DirectX 9.0b。

PS 3.0 = Shader Model 3。

PS 4.0 = Shader Model 4。

N = NO,Y = YES。

“32+64”指32个纹理指令和64个算术指令。

● Shader Model着色器模型快速发展

    传统的分离架构中,两种着色器的比例往往是固定的。在GPU核心设计完成时,各种着色器的数量便确定下来,比如著名的“黄金比例”——顶点着色器与像素着色器的数量比例为1:3。但不同的游戏对顶点资源和像素资源的计算能力要求是不同的。如果场景中有大量的小三角形,则顶点着色器必须满负荷工作,而像素着色器则会被闲置;如果场景中有少量的大三角形,又会发生相反的情况。因此,固定比例的设计无法完全发挥GPU中所有计算单元的性能。

    顶点着色单元(Vertex Shader,VS)和像素着色单元(Pixel Shader,PS)两种着色器的架构既有相同之处,又有一些不同。两者处理的都是四元组数据(顶点着色器处理用于表示坐标的w、x、y、z,但像素着色器处理用于表示颜色的a、r、g、b),顶点渲染需要比较高的计算精度;而像素渲染则可以使用较低的精度,从而可以增加在单位面积上的计算单元数量。在Shader Model 4.0之前,两种着色器的精度都在不断提高,但同期顶点着色器的精度要高于像素着色器。

    Shader Model 4.0统一了两种着色器,所以顶点和像素着色器的规格要求完全相同,都支持32位浮点数。这是GPU发展的一个分水岭。过去只能处理顶点和只能处理像素的专门处理单元被统一之后,更加适应通用计算的需求,应用程序调用着色器运算能力的效率也更高。

    DirectX 11提出的Shader Model 5.0版本继续强化了通用计算的地位,微软提出的全新API——Direct Compute将把GPU通用计算推向新的巅峰。同时Shader Model 5.0是完全针对流处理器而设定的,所有类型的着色器,如:像素、顶点、几何、计算、Hull和Domaim(位于Tessellator前后)都将从新指令集中获益。

    在这一过程中,着色器的可编程性也随着架构的发展不断提高,下表给出的是每代模型的大概特点。

无心插柳柳成荫 GPU通用计算十年发展

● GPGPU概念提出并付诸行动

    对GPU通用计算进行深入研究从2003年开始,并提出了GPGPU概念,前一个GP则表示通用目的(General Purpose),所以GPGPU一般也被称为通用图形处理器或通用GPU。随着GPU Shader单元计算能力的不断增长,一场GPU革命的时机也成熟了。GPU已经从由若干专用的固定功能单元(Fixed Function Unit)组成的专用并行处理器,进化为了以通用计算资源为主,固定功能单元为辅的架构,这一架构的出现奠定了GPGPU的发展基础。

无心插柳柳成荫 GPU通用计算十年发展
Shader单元运算性能不断增长

    在SIGGRAPH 2003大会上,许多业界泰斗级人物发表了关于利用GPU进行各种运算的设想和实验模型。SIGGRAPH会议还特地安排了时间进行GPGPU的研讨交流。与此同时,DirectX 9 Shader Model 3.0时代,新的Shader Model在指令槽、流控制方面的显著增强使得对应GPU的可编程性能得到了大大的提升。GPGPU的研究由此进入快车道。

    在众多GPGPU项目研究中最接近成功的是英国剑桥大学的BionicFx课题组。剑桥大学的BionicFx课题组便宣布在NVIDIA的Geforce FX 5900产品中实现了专业的实时音频处理功能,并且准备进行商业化的运作,对其产品进行销售,给音乐创作者带来实惠。

无心插柳柳成荫 GPU通用计算十年发展
GPU所能涉及的领域正在迅速增加

    2004年9月份,剑桥大学的BionicFx课题组宣布在NVIDIA的最新GPU产品中实现了专业的实时音频处理功能,并且准备进行商业化的运作,对其产品进行销售,给音乐创作者带来实惠。现在,该解决方案命名为“音视频互换技术”(Audio Video EXchange,AVEX)。BionicFx的工作流程是:待处理的音频数据—〉转换成图形数据—〉GPU处理—〉处理后的图形数据—〉转换成所需音频数据。这说明AVEX实际上是作为虚拟硬件层在与GPU通讯,但GPU不仅是图形处理器,而是变成了一颗独立的数字信号处理器(DSP)。

    在计算机上进行专业音频处理或音乐创作时,专业人员的追求完美的精神和对各种音频插件的苛刻要求总是使得系统资源不够用,DSP不够强。然而高端设备的高昂价格往往令人望而却步。AVEX的出现无疑可能大大缓解这种窘境,因为它依托于浮点运算能力强大的GPU。这是目前所有资料中可查证的,并且是有详细记载地第一次大规模开发GPGPU通用程序并用于商业化运作。

 

● ATI黄金架构诞生,

    DirectX 9.0c无可争议是我们经历过的所有图形API中最长寿和多产的一款,更长的指令支持与动态流控制,使得基于DirectX 9.0c的游戏具备前一代游戏无法比拟的真实感和幻想般的画质,甚至也为很多影视作品和其他图形领域提供了可以实现梦想的平台,GPU走进更多玩家的视野,也正是因为GeForce 6、GeForce7系列以及Radeon X1000等一系列经典显卡,和《极品飞车:变速》和《使命召唤4:现代战争》等经典游戏的出现。

    而后期的大量DirectX 9.0c游戏已经对Shader单元运算能力提出难以达到的要求,GPU必须适应游戏画面渲染发展趋势才能生存。根据ATI的研究,在2001年刚刚出现具备像素着色器的显示卡时,当时游戏的像素着色器程序中算术指令和纹理指令数量的比例在1:1左右,打这以后,算术指令的数量呈显著增加之势。

无心插柳柳成荫 GPU通用计算十年发展
算术指令与贴图指令数量对比

    在2005年像素着色器程序中,平均每5条算术指令才会出现一条贴图指令,而这样的算术指令数量急剧增长趋势仍将继续保持下去。

    我们对于一条像素流水线定义是“Pixel Shader(像素着色器)+TMU(纹理单元)+ROP(光栅化引擎,ATI将其称为Render Back End)。从功能上简单的说,Pixel Shader完成像素处理,TMU负责纹理渲染,而ROP则负责像素的最终输出,因此,一条完整的传统流水线意味着在一个时钟周期完成1个Pixel Shader运算,输出1个纹理和1个像素。但是目前的情况是TMU纹理填充单元和ROP单元并没有成为GPU设计的瓶颈,反倒是更长更复杂的着色器程序指令让多个像素渲染管线感受到前所未有的压力。

    据此研究结果,ATI在代号R520的Radeon X1800核心上市之后果断推出了酝酿已久的增强型改进产品R580——Radeon X1900。在R580面世之后人们才知道,这颗核心早在RADEON X1800发布的时候就完成流片、取样等一系列的后期研发,几乎是进入生产阶段了。它相对于R520最大的改进之处就在于提供了三倍于前者的像素着色器算术计算能力,实现这一目标的方式是采用了3个Pixel Shader对1个贴图单元的方式。最后的开销仅仅是在晶体管数量只增加20%的情况下提供了相对R520 200%的Pixel Shader性能增长。

    Radeon X1900系列最终做到了3个Pixel Shader对1个贴图单元,将Pixel Shader单元数量从X1800的16个推升到48个。这一改动使得GPU运算能力空前强大,其高端产品RADEON X1900XTX的FP32精度像素运算能力达到374.4GFLOPS,如果再加上顶点着色器的话,RADEON X1900XTX的FP32计算能力总共会是426.4 GFLOPS——R580因此得名“3:1黄金架构”。大幅提升的运算能力除了提高了对像素着色器运算需求饥渴的游戏之外,也引起了另一方的注意,那就是斯坦福大学。

无心插柳柳成荫 GPU通用计算十年发展
Folding@home项目蛋白质实时折叠示意图

    2006年由斯坦福大学化学系的潘德小组(Pande Group)主持的全球最大的分布式计算项目——Folding@home,逐步将眼光转向GPGPU领域。该项目可精确地模拟蛋白质折叠和错误折叠的过程,以便能更好地了解多种疾病的起因和发展,任何一台个人电脑都可以下载客户端参与。

    ATI在2006年8月惊人地宣布即将联手斯坦福大学在其Folding@Home项目中提供对ATI Radeon X1900的支持。在显卡加入Folding@Home项目后,科研进展速度被成倍提升,人们第一次感受到了GPU的运算威力。

    2006年10月2日,Folding@home项目公开发行供Windows系统使用的GPU测试版本,测试期间收到由450颗ATI X1900 GPU提供的31 TFLOPS运算性能,每颗显核平均运算运力为一颗传统CPU的70多倍。此后GPU客户端成为Folding@home项目中最耀眼的明星,GPU使用和CPU近乎相同的功耗,却提供了平均10倍于CPU的运算能力。GPU的Shader单元在经过了长期的演化之后,终于在GPGPU领域释放了其强大动力。

    该项目同时引来了全世界大量GPU高端玩家的参与,这是第一个可以让民用级别显卡开展大规模通用计算的尝试,也是目前最火爆的分布式计算项目。该项目在中国发展缓慢,主要是因为真正能理解GPU的玩家数量还是很少,甚至高端发烧友都对它一知半解。而事实上比较运算量可以得出,一款普通的9600GSO显卡的运算能力,已经远远超越一颗高端的4核心CPU。

    中国分布式计算总站作为一个公益性团体,一直在致力于各个分布式计算项目的推广,特别是属于生命科学类别的Folding@home项目。该项目中国团队代码为3213,有兴趣或者想提升技术的玩家,可以尝试参与该项目,为自己的GPU通用计算能力找到一个“发泄”的空间。

● 统一着色器架构再次释放GPU运算能力

    Shader Model 在诞生之初就为我们提供了Pixel Shader(顶点着色器)和Vertex Shader(像素着色器)两种具体的硬件逻辑,它们是互相分置彼此不干涉的。但是在长期的发展过程中,NVIDIA和ATI的工程师都认为,要达到最佳的性能和电力使用效率,还是必须使用统一着色器架构,否则在很多情况下Pixel Shader计算压力很轻造成大量Pixel Shader单元闲置,Vertex Shader资源有限但遇到大量三角形时会忙不过来。也就是说不再区分Pixel Shader和Vertex Shader,最终设计出来的产品可以在任何API编程模型中都不存在任何顶点/像素着色器固定比率或者数量限制。

无心插柳柳成荫 GPU通用计算十年发展
Vertex Shader和Pixel Shader的负载对比

    每一帧渲染中Vertex Shader和Pixel Shader负载压力几乎没有相关性,总是在出现资源闲置和资源紧缺,所以有必要使用统一着色器架构。

    在统一着色器架构的GPU中,Vertex Shader和Pixel Shader概念都将废除同时代之以ALU。ALU是个完整的图形处理体系,它既能够执行对顶点操作的指令(代替VS),又能够执行对象素操作的指令(代替PS)。GPU内部的ALU单元甚至能够根据需要随意切换调用,从而极大的提升游戏的表现。

    微软XBOX 360所采用的Xenos图形处理器,第一次引入了统一着色器架构,这个着色器架构包含了3个独立的着色器矩阵,每个着色器矩阵内有16个5D向量SIMD单元,这些SIMD单元既可以执行Vertex Shader也可以执行Pixel Shader,可以称之为符合DirectX9标准的统一着色器架构。随后NVIDIA推出的GeForce 8800 GTX使用了128个标量流处理器(Stream Processor)。在通用计算方面,GeForce 8800 GTX的统一架构比Xbox 360的C1更先进、更强大,这表现在标量设计、整个US和Shader簇内的MIMD化执行。

无心插柳柳成荫 GPU通用计算十年发展
AMD历代着色器演进

    在GeForce 8800 GTX之后,AMD经过数月的延迟后推出了代号R600的RADEON HD 2900XT核心,这款产品和NVIDIA的新品一样使用了统一渲染架构,不同之处在于2900XT的64个SIMD着色器内包含了5路超标量(superscalar)的运算单元(ALU),我们习惯性称其拥有320个流处理器。组织形式方面,SIMD单元采用超标量+VLIW(甚长指令)设计,虽然从数量上看规模庞大(共拥有320个ALU,8800 GTX为128个),但是执行效率在实际运算特别是通用计算中会发生不可忽视地衰减。

    为方便讨论,在后文分析中,我们将更多地把着色器Shader称为流处理器Stream Processor。

● 揭秘GPU为何如此强大

    近30年来,由Intel、IBM、SUN、AMD和富士通生产的通用CPU虽然有了很大发展,但性能提高速度却已经不能与上世纪八十年代末九十年代初相比。单线程处理性能在很大程度上受到了限制。这些限制一方面来自于通用计算程序中过低的指令级并行;另一方面来自于“功率墙(Power Wall)”——集成电路的功率消耗的物理限制。

    而GPU的用途已经远远超出运行游戏,我们买到的显卡其实是一块高性能加速器。特别是现在NVIDIA和AMD的显卡产品都体现出了极高的浮点运算能力,双精度浮点运算中的衰减也越来越小。

    举例说,在Folding@home项目中,一款中端显卡一天24小时可以计算10个左右的大分子蛋白质折叠,而一款酷睿2双核E7200处理器的一个核心在24小时内完成一个小分子包运算任务都非常困难。CPU和GPU在高密度多线程浮点运算中体现出的性耗比差异,相信大家已经非常清楚。在这一节,我们将着重分析GPU相对于CPU的架构优势。

    ● 两种架构设计方向不同

    CPU和GPU架构差异很大,CPU功能模块很多,能适应复杂运算环境;GPU构成则相对简单,目前流处理器和显存控制器占据了绝大部分晶体管。CPU中大部分晶体管主要用于构建控制电路(比如分支预测等)和Cache,只有少部分的晶体管来完成实际的运算工作。

无心插柳柳成荫 GPU通用计算十年发展
CPU和GPU逻辑架构对比

    而GPU的控制相对简单,而且对Cache的需求小,所以大部分晶体管可以组成各类专用电路、多条流水线,使得GPU的计算速度有了突破性的飞跃,拥有了惊人的处理浮点运算的能力。现在CPU的技术进步正在慢于摩尔定律,而GPU(视频卡上的图形处理器)的运行速度已超过摩尔定律,每6个月其性能加倍。

    CPU的架构是有利于X86指令集的串行架构,CPU从设计思路上适合尽可能快的完成一个任务;对于GPU来说,它的任务是在屏幕上合成显示数百万个像素的图像——也就是同时拥有几百万个任务需要并行处理,因此GPU被设计成可并行处理很多任务,而不是像CPU那样完成单任务。

无心插柳柳成荫 GPU通用计算十年发展
CPU内部架构

    当今CPU仅前端部分就非常复杂,指令解码、分支预测等部分消耗晶体管数量巨大。CPU的设计目标是不仅要有很高的吞吐量,还要有良好的应用环境兼容性,CPU所要面对的应用面远远超过了GPU。CPU是设计用来处理通用任务的处理、加工、运算以及系统核心控制等等的。CPU中包含的最基本部件有算术逻辑单元和控制单元,CPU微架构是为高效率处理数据相关性不大的计算类、复杂繁琐的非计算类的等工作而优化的,目的是在处理日常繁复的任务中应付自如。

    GPU设计的宗旨是实现图形加速,现在最主要的是实现3D图形加速,因此它的设计基本上是为3D图形加速的相关运算来优化的,如z-buffering消隐,纹理映射(texture mapping),图形的坐标位置变换与光照计算(transforming & lighting)等等。这类计算的对象都是针对大量平行数据的,运算的数据量大。但是GPU面对的数据类型比较单一,单精度浮点占到其处理数据的绝大多数,直到GTX200和HD 4800系列显卡才对双精度运算提供了支持。

● 两种架构运算能力不同

CPU的整数计算、分支、逻辑判断和浮点运算分别由不同的运算单元执行,此外还有一个浮点加速器。因此,CPU面对不同类型的计算任务会有不同的性能表现。而GPU是由同一个运算单元执行整数和浮点计算,因此,GPU的整型计算能力与其浮点能力相似。如果你仔细观察一个串行程序的运行结果,你就会发现与浮点计算能力相比,CPU的整数计算能力与GPU中流处理器的整型计算能力更接近,这是因为CPU的设计更侧重于整数计算能力。

    举例来说,一个3GHz的双核CPU每秒能完成60亿条整数指令,而NVIDIA的G80芯片,有128个工作频率为1.5GHz的流处理器,每个流处理器每个计算周期可以执行两条整数指令,把这些数据相乘的结果大约是每秒3500亿~3750亿条指令,这大概是CPU运算能力的50~100倍。GPU在整型计算方面并没有任何劣势。尽管不如在浮点计算方面优势那么大,但是GPU的整型计算能力几乎是CPU的100倍。

无心插柳柳成荫 GPU通用计算十年发展
CPU与GPU芯片面积对比

    现在的CPU和GPU相比芯片规模也呈现出巨大的差异。从相关资料中我们可以了解到,GTX200使用台积电65nm工艺生产,集成多达14亿个晶体管,核心面积576平方毫米,是有史以来规模最庞大的图形芯片。45纳米Penryn家族处理器中的双核心版本内建4.1亿个晶体管,分析图片我们可知其中约2亿个晶体管用于SRAM二级缓存。

    以当前高端GPU为例,AMD HD 4870拥有800个SIMD流处理器,是上一代产品的2.5倍,晶体管总数为9.65亿个,同时它是首款浮点运算能力超过1TeraFLOPS(1000GFLOPS)的GPU芯片。NVIDIA GTX280则使用MIMD流处理器架构,拥有240个SP单元,浮点运算效率出众,分支能力强大。HD 4870和GTX280的并发可执行线程数同样达到了30720条,而CPU在正常情况下可执行线程数是与核心数目相等的,具备超线程技术的四核I7处理器也只能同时运算8条线程。所以在大规模的多线程运算中,GPU可以体现出上百倍于CPU的运算能力。

    凭借强大的可编程流处理器阵容,GPU在单精度浮点运算方面将CPU远远甩在身后。以我们现在最顶级的英特尔Core i7 965处理器来说,在默认情况下,它的浮点计算能力只有NVIDIA GeForce GTX 280 的1/13,与AMD Radeon HD 4870相比差距就更大了。当然这里仅仅是理论峰值,也就是说当GPU的所有流处理器都满载时得到的运算能力。

● GPU逐渐强化的双精度运算能力和存储子系统优势

    从GTX200和HD 4870系列显卡开始,两大厂商都提供了对双精度运算的支持。HD 4870集成的大ALU依靠ALU.transcendental电路来执行双精度浮点数据的运算,ALU.transcendental主要的作用是为了指令补完,每个时钟周期内能执行一个双精度乘加运算。因为可以每个周期能执行160条MULADD指令也就是说HD 4870的峰值双精度运算能力是单精度运算能力的四分之一,也就是240GFLOPS。但是在通常情况下,HD 4870的双精度性能会被看作是1/4或者1/2,因为人们在编写通用程序的时候,可能很少使用到ALU.transcendental,这时候程序就会表现出1/4的单精度 MULMAD 指令吞吐率或者1/2的单精度ADD指令吞吐率。

    GTX200核心的每一个SM都包括了一个双精度64Bit浮点运算单元,这个单元就是SFU(Special Function Unit,特殊功能单元)。这个处理单元可以用来辅助SP单元处理特殊的函数运算、插值属性的顶点+像素着色、执行浮点乘法运算指令(MUL)。GTX200芯片中的SFU单元已经不像G80时代的线程调度器,而是具备完整的线程发放能力,支持单周期一个乘加+一个连加运算。所以GT200的双精度运算性能衰减是单精度的1/8。这样GTX200就相当于一个30核心的双精度64Bit处理器。根据资料计算,GTX280峰值双精度64Bit浮点运算能力大概在90GFLOPS左右。

无心插柳柳成荫 GPU通用计算十年发展
运算能力对比

    目前困扰GPU厂商的一个主要问题还是周边资源特别是共享寄存空间的不足,因为双精度运算寄存器系统消耗最大,这里的寄存器即缓存,NVIDIA称之为Shared memory,AMD称之为LDS(Local Data Share)。这个共享寄存器位于每个流处理器单元内部的所有运算单元中,它在通用计算时负责共享数据和临时挂起线程。

    共享寄存空间的提升需要半导体工艺的强大支持,因为这部分缓存和CPU一样使用6T SRAM晶体管,SRAM的每一个比特位需要占用6个晶体管,存储密度较低,1MB容量的二级缓存就需要占用5000万个晶体管,这是一个相当惊人的数字。目前在CPU的逻辑分布中,二级缓存占据的硅芯片面积甚至大于运算核心。在晶体管数量已经相当庞大的GPU(如GTX 280集成度多达14亿个晶体管)中,要集成大量的缓存更是难上加难。

无心插柳柳成荫 GPU通用计算十年发展
6T-SRAM晶体管构成缓存

    容量足够大的共享缓存可以在运算时提高线程的挂起能力,这将直接提升GPU的分支运算能力。同样大容量的缓存在运算精度提升时可以确保更低的性能衰减,届时GPU将拥有更强的双精度能力,理论上会和其单精度运算能力一样远超CPU。这样的直接后果是让GPU更加适应混合精度环境,让通用计算走得更远。

    如未来的DirectX 11强制要求每组流处理器拥有32k大小的共享寄存空间,正是为了加强GPU的双精度运算能力。又如2008年12月,另外一个重要的分布式项目SETI@home宣布正式利用CUDA平台支持显卡计算。SETI的重要研究方向,就是从天球背景中接收到的无线电中滤掉杂音。这种降噪运算必须依赖混合精度,而GPU支持这种运算的前提就是拥有稳定和强大的混合精度运算能力。

    GPU运算相对于CPU还有一项巨大的优势,那就是其内存子系统,也就是显卡上的显存。当前桌面级顶级产品3通道DDR3-1333的峰值是32GB/S,实测中由于诸多因素带宽在20 GB/S上下浮动。HD 4870 512MB使用了带宽超高的GDDR5显存,内存总线数据传输率为3.6T/s或者说107GB/s的总线带宽。GTX280使用了高频率GDDR3显存,但是其显存控制器支持的位宽达到了512bit,搭载16颗0.8ns GDDR3显存,带宽高达惊人的142GB/s。而主流GPU普遍拥有40-60 GB/s显存带宽。存储器的超高带宽让巨大的浮点运算能力得以稳定吞吐,也为数据密集型任务的高效运行提供了保障。

    目前GPU已经是足够强大的可编程处理器,非常适合大运算量的科学应用,诸如地质勘探,生物学,流体力学,金融建模等等。这使得GPU应用于地球科学、分子生物学和医学诊断领域的高性能计算为实现重大的发现提供了可能,这些发现会改变数十亿人的生活。

● GPU架构设计导致的运算能力差异

GTX280总共拥有十个流处理器阵列,每个阵列内部拥有8×3=24个流处理器,其中每8个为一组构成SIMT(单指令多任务架构),并共享16K指令缓存,三组SIMT共享一级缓存。这样的标量流处理器设计适合执行高度并行化指令,无论对于传统的图形渲染,还是物理加速运算、大规模数据处理都游刃有余。HD 4870同样不干落后,800个高度优化的流处理器由160个Stream Processing Units构成,每个流处理器单元的“1大4小”结构包括一个全功能SP单元和4个能执行乘加运算的SP。同样拥有可怕的理论运算能力。

无心插柳柳成荫 GPU通用计算十年发展
图解SIDM与MIMD区别

    需要注意的是两家图形芯片厂商设计的产品的实际性能并不能用理论峰值性能来推算。比如AMD的SIMD+VLIW结构流处理器由于架构因素几乎无法做到所有SP单元满载,主要原因是科学运算类的指令段没有相当多的天然4D指令。SIMD最大的问题是程序数据必须一致,也就是说当你同时操作5D(4D+1D)数据的时候,这5D数据必须在同一个数据流程中,5D的相关性是默认的。同时条件分支数目庞大,所以导致R600和RV770的架构性能相比NVIDIA产品有更一定幅度性能衰减。

    Radeon HD 4870与GTX 280最明显的区别就是流处理器结构,Radeon HD 4870选择延续上一代非统一执行架构GPU产品的SIMD结构,用庞大的规模效应压制对手,偏向于ILP(指令并行度)方向,而GTX 280则使用了G80以来创新的MIMD架构,更偏重于TLP(线程并行度)方向。在单指令多数据流(SIMD)的结构中,单一控制部件向每条流水线分派指令,同样的指令被所有处理部件同时执行。另外一种控制结构是多指令多数据流(MIMD),每条流水线都能够独立于其他流水线执行不同的程序。

无心插柳柳成荫 GPU通用计算十年发展
NVIDIA和AMD使用了两种不同的流处理器架构

    其实在上一代非统一执行架构GPU中(如Geforce 6800 Ultra),顶点着色器流水线已经使用了MIMD方式控制,像素着色器流水线则继续使用SIMD结构。MIMD能比较有效率地执行分支程序,而SIMD体系结构运行条件语句时会造成很低的资源利用率。TLP要求强大的仲裁机制,丰富的共享cache和寄存器资源以及充足的发射端,这些都是极占晶体管的部件。不过SIMD需要硬件少,这是一个优势,这也就是为什么Radeon HD 4870拥有800个流处理器,晶体管集成度却低于240个流处理器的GTX 280。

    此外在高密度并行运算中,AMD的R600和RV770的发射端资源面临一定程度的短缺。以RV770(Radeon HD 4870)为例,每个流处理器单元(“1大4小”5个流处理器)配备了1个发射端,所以如果要保证指令吞吐不受限制就通过VLIW,也就是超长指令打包的形式将若干个短指令打包在一起。VLIW应用在RV770中理论上可以做到1个4D+4个1D打成一个包一起丢进US,这样可以最大限度的避免发射端不足的问题。可是如果遇到条件分支,也就是说这个包里面有一个1D指令的结果很不凑巧是同一个包里另外一个1D指令的初始条件,整个架构的效率会受到影响。

无心插柳柳成荫 GPU通用计算十年发展
GPU流处理器架构对比

    还有一个不可忽视的问题是最小线程执行粒度。粒度越细,能够调用并行度来进行指令延迟掩盖的机会越大,性能衰减越小。细化粒度偏向TLP方向,对GPU的线程仲裁机制要求很大,最终会导致硬件开销过大。我们知道GPU通用计算中最小的执行单位是线程(Thread),多个线程会被打包成一个线程束,NV称线程束为Warp,AMD称之为Frontwave。但是在粒度上两家厂商做出了不同的选择,Frontwave包含64个线程,NV的线程管理粒度更小,每个Warp包含32个线程。R600和RV770每凑够64个线程,仲裁器就会动作一次,把一个Frontwave发送给空闲的一个SIMD Core。NV的G80和GT200比较特殊,存在Half-Warp,也就是说每16个线程就可以发送给SM一次。Half-Warp由线程中的前16个线程或者后16个线程组成。

    总体来说,两家厂商的差异在于:AMD堆砌了更大规模的运算器单元,NVIDIA则更注重如何利用有限的运算器资源。AMD将更多的晶体管消耗在大量的SIMD Core单元上,NVIDIA则将更多的晶体管消耗在仲裁机制、丰富的共享缓存资源和寄存器资源以及充足的发射端方面。AMD的GPU偏向于ILP结构,NVIDIA偏向于TLP结构。TLP(线程并行度)考验线程能力和并行能力,ILP(指令并行度)则考验指令处理。从G80和R600的对垒开始,两大图形芯片厂商一直延续着这种竞争思路。

● Fermi GPU架构带给我们的思考

    在经过漫长的4年开发期之后,众望所归的Fermi架构GPU终于诞生,这款GPU身上凝聚了众多“第一”,打破了很多芯片设计的世界记录。有人说Fermi拥有强大的Tessellation细分曲面单元,也有人说Fermi拥有高倍的AA特性,而实际上这都只是Fermi架构的毛皮,或者说在图形领域的一些细微改进。实际上Fermi的真正提升在于架构代差……

    NVIDIA的Tony Tamasi先生(NVIDIA公司高级副总裁,产品与技术总监)表示:“以前的G80架构也是非常出色的图形处器。但Fermi则是一款图形处理同样出色的并行处理器。” 这句话揭示了Fermi的与众不同,它已经不再面向图形领域设计了,因为更广阔的通用计算市场在等待它。Fermi将为通用计算市场带来前所未有的变革,图形性能和游戏被提及已经越来越少。

    诸如曲面细分之类的东西在未来更长一段时间内将逐渐淡化,因为那些不过是体现了一个公司对微软历代DirectX要求的理解和按图索骥的能力罢了。真正体现水平的是运算单元部分,是每一个运算器的构成和组织方式。

    如果说从G80身上已经看到了GPU迈入通用计算领域的影子,那在代号GF100的Fermi身上,你能更多地找到CPU的烙印Fermi的cache,并行kernel,分支论断,warp级的乱序执行,都已经远远超越GPU的意义。它们消耗了Fermi大量的晶体管资源,而有些设计甚至是和图形运算完全无关或者说不能提高图形性能的。

无心插柳柳成荫 GPU通用计算十年发展
Fermi架构设计图

    这篇文章写在Fermi发布之前,鉴于文章篇幅有限,且未来我们将给出Fermi架构的细节分析,所以在这里简单说明一些Fermi的设计新方向和新特性:

1、更大更全的缓存体系:GF100核心和上一代GPU相比,除同样拥有12KB的L1纹理缓存之外,其拥有真正意义的可读写L1缓存和L2缓存。GF100核心使得GPU中首次出现了64KB的RAM支持可配置的shared memory和L1缓存。

    Shared memory可以解决一部分程序的问题,但是不能解决所有的问题。一些应用程序天然需要shared memory,有些应用程序则需要缓存cache,有的既需要shared memory也需要cache。优化的内存设计可以既提供shared memory也提供cache,可以让程序员根据自己的需求来做选择。Fermi的SM单元比过去大得多,所以每个SP独享的shared memory可以减少,可通用的资源也就更多了,这些改进全靠缓存的引入。

    为GPU引入缓存也意味着风险,首先缓存的可读写性带来了很多问题,它包括缓存一致性协议,这需要用复杂的逻辑进行控制。其次缓存的命中率等问题需要NVIDIA着手解决,如果缓存的命中率过低,引入缓存将带来数据读写减速。同时还不得不考虑缓存引入的大量晶体管开销(前文已经分析)。

2、底层计算单元不断改进:毫无疑问,G80到 GT200以来,NVIDIA的MIMD架构流处理器设计一直是图形芯片中效率最高的,虽然它很耗费晶体管,但是以最后实际性能衡量,还是和划算的。这次Fermi延续了这种设计,但是在计算单元和周边资源方面做了扩充,更高的精度和更小的衰减是永远的目标。

    Fermi所支持的FMA指令在做乘运算和加运算的时候只在最后运算的时候作一次舍入,不会在执行加法的时候就出现精度损失。其次Fermi架构为支持双精度浮点运算进行了特别设计每一个SM在一个时钟周期内可以完成16个双精度浮点数的FMA操作。同时大量原子操作单元和L2缓存的使用,大大增强了Fermi GPU架构中的原子操作能力。

3、更强大的线程调度能力和分支论断:在Fermi上的一个重要特性,就是它的双层分布式调度机制。在片上的层面(SPA Streaming Processor Array,流式处理器矩阵级别),全局的分布式线程调度引擎(global work distribution engine)分发block到每一个SM上,在SM层面,每一个warp分布式调度引擎按照32个线程为一个warp执行。

    Fermi实现了SM级别的双发射,意味着SPMD(单线程多任务)的实现。并行kernel下到最底层实际上就是靠的SM级别的双发射。SM级别的SPMD上升到GPU核心级别,Fermi就是MPMD(多线程多任务)。这种设计已经越来越像CPU,而且随着GPU的发展,每走一步,就多像一份。

    PTX是NVIDIA针对支持并行线程处理器运作而设计的低级虚拟机和ISA,当程序执行之前,PTX指令会被GPU驱动转译为GPU的本机代码。Fermi所支持的PTX 2.0 ISA为所有的指令提供了predication(论断)支持,使得这个特性可以更容易、更快地去执行条件语言。在Fermi中为这一功能的初步实现提供了一个独立单元,它和仲裁器、Atomic单元的地位一样重要。分支论断只能算是分支预测的雏形或前身,但这种功能在以前的GPU上是可望而不可及的。

● GPU通用计算正在飞速发展

    因为具备强大的并行处理能力和极高的存储器带宽,GPU如果被抽象成一个“流处理器”(Stream Processor),来用于诸如科学运算、数据分析、线性代数、流体模拟等需要大量重复的数据集运算和密集的内存存取的应用程序,那么我们就能获得比CPU强悍得多的计算能力。

无心插柳柳成荫 GPU通用计算十年发展
GPU应用在各种领域,提供了不可思议的加速比

    巨大的运算能力让人们对GPU充满期待,似乎在一夜之间,GPU用于通用计算(General Purpose GPU)及其相关方面的问题成为一个十分热门的话题。视频编码应用,比CPU快18倍;期货风险控制系统,整个系统性价比提升9倍;医疗行业应用,CT立体化且提速20倍;地理信息系统应用,速度提升可达50倍;生命科学研究,等待时间缩短12倍;矩阵计算以及仿真能力,比CPU快17倍……一个以GPU为中心的高效运算平台正在向我们走来。

    2009年10月29日,国防科技大学成功研制出的峰值性能为每秒1206万亿次的“天河一号”超级计算机在湖南长沙亮相。我国成为继美国之后世界上第二个能够研制千万亿次超级计算机的国家。天河一号采用6144个Intel通用多核处理器和5120个AMD图形加速处理器GPU,其中GPU的型号正是大家熟悉的ATI上一代高端GPU产品HD 4870X2。截止2009年11月17日,“天河一号”超级计算机在第34届TOP500榜单中排名第五,这也是中国超级计算机目前为止达到的最高排名成绩。

无心插柳柳成荫 GPU通用计算十年发展
GPU通用计算的基础与周边

    在此之前,GPU系统在全球高性能计算机TOP500排行榜中最好的成绩是第29位,运算速度为77.48TFLOPS——东京大学的Tsubame超级计算机。构成这台计算机的主体是GPU,由170个NVIDIA Tesla S1070 机架式单元组成。东京工业大学全球科学资讯和计算中心总监Satoshi Matsuoka博士曾公开表示,他打算使用GPU在2010年打造出一台荣登世界最快榜单的计算机。

    GPU一直在促进游戏画面的进步,客观上造就了自身强大的性能,最终走上了和图形计算完全不相关的领域,并成为一颗新星。不要不相信你的眼睛,GPU通用计算这些年来的发展正所谓无心插柳柳成荫,强大的Shader着色器资源最终转化为大规模并行计算的流处理器。

    基于GPU通用计算的实例已经越来越多地出现在我们的生活中。在接下来的几年里,GPU将越来越多地被大型计算所采用。GPU拥有超高的计算密度和显存带宽,足以支持这种计算性能的增长,终将成为超级计算机中极其重要的动力源泉。读者或许很难想象手中的这块显卡搭载的GPU在超级计算领域中,现在已经成为高性能、低能耗并且是人们买得起的大规模并行处理器。

———————————————————————————

本文参考文献:

[1] 抛弃CPU 迎接 GPGPU计算新时代
[2] 从平民到皇帝 NVIDIA产品14年发展回顾
[3] 虚拟世界由此开始 追逐3D世界的脚步
[4] 3D游戏的盛宴:DirectX10深入剖析
[5] 16毫米攻防战 RADEON HD 4850测试报告
[6] GPU,颠覆的不仅仅是视界
[7] 改变翻天覆地 史上最全Fermi架构解读
[8] GPU高性能计算之CUDA

给我留言

留言无头像?