首页 > 代码库 > 移动GPU全解读(一)

移动GPU全解读(一)

【编者按】:本文作者为爱搞机特约作者、技术达人“炮神”@ioncannon。

本文将从移动GPU的结构、参数、兼容性、跑分几方面让读者全方位对移动GPU有一定的概念。由于篇幅较长,分成两部分介绍,这是第一部分,讲解的是移动GPU的结构和相关参数。

 

前言

现在移动设备的“核战”越来越激烈,已经从CPU引发到了GPU上,于是“16核”、“8管线”、“MP4”、“三角形生成率”和“填充率”等各种吸引眼球的宣传铺天盖地而来。一直很希望能有些文章来介绍科普下,但或许是专业人士都觉得这些太基础,最后忍不住,只能由我这个半桶水的非专业人士来写点啥了。本文参考和引用了网上的一些资料,篇幅有限恕不一一列举。内容尽可能的科普浅显,但限于个人的知识层次、理解能力和表达能力,如果有不确切或者错误的地方,还请多多指正。

 

基本的3D流水线

首先我们来简单的介绍下3D的画面是如何生成的,一个基本的3D流水线如下图所示:

首先,运行在CPU上游戏引擎根据游戏中的一些参数,产生一系列的图元,将它们的顶点数据发送给GPU。

第二步,顶点处理器(Vertex Processor)对顶点数据进行一系列的变换和光照处理。简单的想想,游戏中的各个物体的坐标都是参照游戏中的世界坐标系的,而实际显示的画面是玩家视角或者摄像机视角,这中间就有许多坐标系的转换。这些活就需要顶点处理器来做,最终我们得到了我们所需要视角的画面。

但是,到这一步,画面还只是一些多边形,而实际显示在屏幕上的是一个个像素,这里就需要Rasterizer进行光栅化(Rasterization,3),从而将画面变成一个像素图。

第四步,对这些像素进行上色,Fragment Processor中的像素着色器(Pixel Shader)按照程序规定的算法,计算出画面中每个像素的颜色,之后第五步就是把结果输出到内存中,全部完成后拿去显示。当然在这整个过程中,还跟纹理贴图6有关系。所谓贴图就是把纹理(一个二维的静态图片)按照一定的算法给贴到游戏里的三角形表面上去。

 

参数,究竟靠不靠谱?

终端厂商在宣传他们手机芯片的GPU如何强劲时,往往会提到一些参数,最常见的就是三角形生成率和填充率。但实际上,不同公司的GPU,他们的这些理论参数,并不具有直接的可比性。我们也可以发现,有些GPU可能给出的理论参数很高,但实际表现却很一般,甚至不如一些参数低的GPU。这是因为,各个GPU的供应商,比如IMGtec(PowerVR SGX),高通(Adreno),Vivante(GC系列),ARM(Mali),nVIDIA(GeForce),他们给出这些理论数据的测试方式,可能不太一样。

比如三角形生成率,本身就受到很多测试因素的影响。例如,有些三角形在一开始就会被剔除掉(比如在屏幕外,或者太小了根本覆盖不到一个像素),不会被显示也不会需要执行太多的运算,那么这部分三角形到底应该算吗?如果算进去的话,三角形生成率自然就高了。或者,测试程序把一些已经计算好的坐标提交给GPU,那么GPU的Vertex Shader就不需要进行复杂的计算,数值自然就高了。再或者,并非生成一个三角形就一定需要处理三个顶点。如果有三角形共享顶点,用indexed的办法绘制,顶点的数目就可以减少。就像下图,2个三角形只需要处理4个顶点。如果测试的时候大量使用这种方式,也可以提高三角形生成率的数值。

同样,填充率反映了GPU的像素输出能力。但是厂家给出的理论值,很多都是没有贴图,没有Shader计算,仅仅是生成无色点的能力,跟实际使用的情况有较大的差距。又比如Imagination Technologies 的PowerVR SGX系列给出的填充率,并不是实际值,而是实际值乘以了一个2.5x的系数。这是由于PVR GPU架构的特殊性,可以剔除画面中被遮蔽的部分,不作渲染,减少了无用功。200MHz的SGX540,原生的填充率是400M,而由于这种技术的存在,IMG认为其等效填充率相当于1000M。在实际的场景中,如果遮蔽的部分较多,这个系数可能远超过2.5x。当然,如果场景中遮蔽较少,这个系数相应的也会变小。

 

事实上三角形生成率和像素填充率作为衡量GPU性能的参数,在PC平台上,几年前就已经被淘汰了。由于从DX8开始,现代GPU都已经由可编程的Shader来代替固定功能的单元实现各种特效,所以Shader的计算能力成为很重要的一点,在移动平台也是一样的。

 

移动平台的特点和移动GPU的架构

不过呢,移动平台相比于PC平台,还是有很多不同的。从本质上看,是由功耗和体积两方面限制的,对于图形处理来说,主要是两点:

第一,是有限的带宽。实际上,要增加计算能力,在功耗允许的情况下,堆核心并不是一件难事,事实上我们也看到了不少SOC集成了四核乃至“16核”GPU。但是难点在于,需要有足够的带宽去满足这颗强大的GPU,避免其出现“饿死”的情况。在左图的移动平台中,CPU、GPU和总线被共同集成在一颗芯片上,称之为SOC。整个SOC,包括其中的CPU和GPU,共享有限的内存带宽。即使是相对高端的,采用64bit内存位宽的一些SOC,如三星4412,高通8064等,也只是6.4 - 8.5GB/s的带宽,相比起PC平台主内存十几GB/s的带宽,和PC GPU GDDR5显存动辄几十,不少都超过100GB/s的带宽,只能说是少的可怜。相对另类的苹果在iPad4中,给A6X芯片搭配了128bit的LPDDR2-1066,带宽达到了17GB/s,用以喂饱强大的SGX 554 MP4 GPU,但相比PC平台依旧是小巫见大巫。因此,移动平台要在有限的带宽下实现合理的性能,在不少时候,瓶颈可能并不在于计算能力上,而在于带宽上。

 

第二,相比PC平台的CPU,移动平台的CPU浮点较弱,在Cortex-A9开始虽然有所好转,但64bit的NEON跟桌面128bit甚至256bit的SIMD还是有显著差距,外加主频的差别。因此更多的计算也依赖硬件Vertex Shader去完成。

 

因此,移动平台的GPU相对于PC平台,也会有一些不同。我们回过头来看一下移动平台的GPU的一些架构。

首先是传统的IMR(Immediate Mode Rendering)架构

 

目前几乎所有的桌面GPU(nVIDIA,AMD)都是IMR架构,在移动领域,nVIDIA的GeForce ULP和Vivante的GC系列GPU都是属于IMR架构。IMR架构的GPU渲染完物体后,都会把结果写到系统内存中的帧缓存里,因此就可能出现GPU花了大量的时间渲染了一个被遮挡的看不见的物体,而最后这些结果在渲染完遮挡物后被覆盖,做了无用功。这个问题称之为Overdraw。虽然现代的IMR架构GPU在一定程度上可以避免这个问题,但要求应用程序将场景里的三角形按照严格的从前往后的顺序提交给GPU,要完全避免Overdraw还是很困难的。

另一方面,由于IMR架构的GPU频繁的读写和修改帧缓存,因此对带宽的要求比较高,同时也增加了电力的消耗。

 

所以,大部分的移动GPU都采用TBR(Tile Based Rendering)的架构

ARM的Mali GPU和高通的Adreno GPU采用TBR(分块渲染)架构,实际上IMG的PowerVR也是分块渲染的。TBR架构在把三角形场景变成像素图(光栅化)前,先把整个画面分成小块,这些小块的渲染在GPU上的高速缓存里进行,这样就避免了对帧缓存(位于系统内存里)的频繁读写和修改。当然,由于一个三角形可能被分在几个不同的块里,三角形的数据(几何数据)可能被需要多次读取,但总的来说还是能大大减少对系统内存的访问,节约了带宽的同时也减少了电力消耗。

当然,不同的GPU分块的大小也有所不同,PowerVR和Mali一般是16*16像素的块大小,而大部分的高通Adreno都带有256K的缓存,以256K作为块的大小进行渲染,高通称之为binning。

但是,除去PowerVR外的TBR GPU同IMR一样,还是不能避免Overdraw的问题。

 

而PowerVR的不同之处在于,它采用的TBDR(Tile Based Deferred Rendering)架构,可以彻底避免Overdraw的问题。

 

相比TBR更进一步的是,TBDR在光栅化之后,有一个HSR(Hidden Surface Removal))硬件单元,通过对一个块内的三角形进行测试,剔除掉被遮挡的三角形,合成一幅由所有可见部分组成的画面,交给后续的流水线去渲染。这样不可见部分就不需要Pixel Shader去做相应的计算,也不需要去拾取相应的纹理,节省了计算量的同时也节省了带宽,对移动设备来说有很大的帮助。

移动GPU全解读(一)