ZOL上一篇GPU相关介绍的分析(3)

来到系列的第三篇文章《像素处理那点儿事儿》,作为近年来GPU技术革新的主要战场,像素的问题值得好好分析。文章一开始,作者就力图让读者明确像素处理并非简单的2D贴图,而是需要通过数学关系确定的。

而在Pixel Shader出现前,程序员只能通过“固定的单元”实现简单的、预设好的染色方式(通过API),无法在像素层面实现特效。从功能上来说,对像素的直接控制其实并不困难,只需要将传统的“固定管线”替换成可编程运算单元从而对ARGB数值做任意处理即可。可直到2001年微软发布DX8.0才正式提出可编程shader program概念,于是GPU也就推出了与之适应的第一代Pixel Shader,其可编程单元为combine。后者的推出让程序员可以实现诸如真实的表面光照效果、界面半反射、散射以及折射等特效,而非单纯的alpha贴图。

但第一代的Pixel Shader由于不支持浮点类型,所以其数据(颜色值)精度受限。Pixel Shader 2.0通过对浮点FP24/32的支持提高了色彩精度、利用miniALU替换了前期的combine并通过增加指令条数的手段提升了执行效率。然而Pixel Shader 2.0采用的miniALU由于不支持跳转、分支以及流控制等可以提升执行效率的手段,最终渲染性能低下。此外,虽然指令条数增加到512条,但仍然无法满足程序员的需求,从而导致一个像素需要反复进入Pixel Shader单元处理,从而效率低下的问题得以成倍数放大。

针对Pixel Shader 2.0的问题,微软在DX9.0C中通过支持65535条指令、增加寄存器数量、引入动态程序流控制以及多目标渲染和延时渲染提升了效率,搭配Pixel Shader 3.0获得了空前的成功。然而急剧放大的指令长度引入了另一个问题,即执行单元的总体效率。这里面主要的原因在于那时Vertex Shader和Pixel Shader在硬件上各自独立,程序员必须按照一定的比例分配这两种program,一旦稍有偏颇就会导致性能的下滑(硬件资源利用率下降)。

针对Shader Modle 3.0的问题,微软在DX 10(Shader Modle 4.0)中引入Unified Shader,通过扩展传统的执行单元为通用计算单元的方式整合了Vertex、Geometry以及Pixel三类Shader,从而从理论上得到100%的硬件使用率。此外,相对传统DX9.0中固定的Shader格式(Vertex为4D、Pixel为3D+1D),Shader Modle 4.0中由于采用通用计算单元,解放了指令格式的要求,使得程序员可以方便使用1D、2D指令以及算数函数,这也就为GPGPU应用奠定了基础。Shader Modle 4.0也有自身的问题,主要是并行度和几何关联性。一般来说,在对像素处理时,每个像素对应一个线程,大量线程汇集为CTA,一定数量的CTA组成一个kernel,而kernel就是GPU处理的最小粒度(GPU顺序执行每个kernel)。正是犹豫kernel内部线程的处理本身区别较大(其间有大量跳转等),因此很难填满ALU,导致效率降低。此外在面向通用计算时,由于其API都是针对图形处理,很难直接用于通用计算,这就是所谓几何关联性较强带来的问题。

针对Shader Modle 4.0的问题,微软在DX11(Shader Modle 5.0)中引入了两个核心技术:并行kernel执行与Compute Shader。其中前者意义比较明确,后者是通过完全开放的数学指令型shader实现通用计算与图形计算的融合。

最后,该文回到最初的问题:为什么像素本身如此难缠?原因还是文章开头就提到的:如果是静态的,则直接调用烘培材质+纹理贴图就能搞定,而一旦需要动画,则必须考虑像素点的光照等物理过程。比如如果处理室外环境,则仅需要multi-pass render pipeline(单个光源),其实质就是一组分别针对R、G、B处理的方程式。而如果是multi-light single pass render(多个光源),则后续还需考虑多光源复合效应等等,非常复杂。而这还仅仅是单个像素的处理,一个屏幕上的像素点只要发生变化就需要进行这样的渲染过程。

总的来说,整个像素渲染的过程是:首先,将像素颜色原本数值与其光线等变化因素通过一组方程表达出来,继而将这些方程式转化为GPU可以执行的指令队列。然后,通过将单个像素点对应的单个线程组合成CTA(GPU最小执行粒度),并进而组合成Block。而一个GPU最小执行执行单元SM可以同时处理多个Block,所有由同一个SM执行的多个Block组成一个Grid,而对一个屏幕上所有像素点更新的操作就是一个kernel。

然而,由于对全屏所有像素点的直接处理消耗过大,所以还是需要运用实现烘培好的纹理(大量已经具备基本效果关系的像素,不进行额外处理)以应付细节要求不是太严格的情况。

Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s