美文网首页渲染管线
【GPU Gems】Chapter 28. Graphics P

【GPU Gems】Chapter 28. Graphics P

作者: 离原春草 | 来源:发表于2021-03-11 22:35 被阅读0次

    今天分享的是GPU Gems上关于性能优化的文章,这里是原文地址

    1. 概览

    随着硬件的升级,图形渲染管线也变得越来越复杂,使得渲染瓶颈的定位也变得复杂起来。

    1.1 渲染管线

    图形渲染管线从大的方面可以分成CPU跟GPU两部分,这里的主要关注点在GPU上面。下面这张图给出了GPU渲染管线并行执行的且容易导致瓶颈的几个主要的功能单元:

    GPU渲染管线

    1.2 优化方法

    之所以要定位瓶颈,其最终的目的是为了优化应用的渲染表现,使之用最小的消耗得到最优的表现,而优化工作总的来说可以分成如下三步:

    1. 定位瓶颈
    2. 优化瓶颈
    3. 重复上述两步

    2. 瓶颈定位

    瓶颈流程图

    上图给出了瓶颈定位的主要流程图,这里的定位是从(图形渲染管线顺序)后往前进行的,这里需要注意的是,不同的物体其瓶颈可能是不一样的(比如一个天空盒的主要瓶颈可能在PS上,而一个蒙皮物体的瓶颈可能在VS或者CPU上)。

    这里定位瓶颈的方法是通过对每个阶段,调整其负载,观察性能表现是否有变化而得到的。

    2.1 Raster Operations(RO)

    图形渲染最后一个阶段为RO阶段,在这个阶段会完成depth/stencil的读写与test,color的读写,alpha blend/test等工作,从这些描述可以看出,这个阶段对于frame-buffer的带宽有着比较强的依赖。

    定位frame-buffer带宽瓶颈的最好的方法就是调整color/depth buffer的格式,如果格式精度下降导致性能上升,说明就是这个地方出了问题。

    需要说明的是frame-buffer带宽是GPU memory clock的一个函数,因此修改memory clock也可以用来定位瓶颈。

    2.2 Texture Bandwidth

    贴图带宽可以理解为读取贴图数据所需要的时间,出于对功耗的考虑,移动端的芯片硬件尺寸注定不能过大,否则功耗过高,掉电快发热高,十分影响体验,而对功耗影响最显著的一项因素就是带宽,这也就注定了移动端的带宽占用不能过高(Arm在Unity Forum 2019上的建议是,移动端在CPU的带宽占用不能超过2GB/s),因此也就导致了对带宽依赖较强的一些环节,比如贴图读取等在处理速度上会受到限制,虽然当代GPU增加了贴图缓存来降低贴图读取的延迟,但是延迟依然还比较明显。

    定位这个问题当然可以通过修改贴图格式来判断,不过这种做法比较麻烦,更常用的做法为通过mipmap bias降低读取的贴图的mip层级,采取更低分辨率的贴图来看看性能是否提升。

    贴图带宽同样也是GPU memory clock的函数(这里能通过memory clock来判断瓶颈吗?那不就跟前面的冲突了,导致无法识别?)。

    2.3 Fragment Shading

    这个阶段主要对应的是fragment着色计算的消耗。通常fragment shading+frame-buffer带宽对应的是GPU的一项非常重要的参数:fill-rate。虽然这两项都可以通过降低渲染分辨率来提升性能,但是他们两项本质上是不同的。

    固定管线中基本上不会在这个地方产生瓶颈,但是随着可编程管线的开放与优化,现在这个地方成为瓶颈的概率也在增加。

    定位fragment shading瓶颈的第一个方法是降低渲染分辨率,因为之前已经分析过不是frame-buffer带宽的瓶颈,因此如果因此出现了性能提升,那就肯定是这个地方的问题。另一个方法则是修正fragment shader的长度,这里注意不要添加一些会被编译器优化的代码。

    Fragment shading是GPU core clock的函数。

    2.4 Vertex Processing

    在这个阶段会完成顶点相关的一些运算,包括坐标变换,法线转换等,经过这个处理后,会输出与顶点相关的若干属性,后面会用作clipping与光栅化输入。

    定位VS瓶颈的方法是修改VS的长度,VS处理的速度同样也是GPU core clock的函数。

    2.5 Vertex & Index Transfer

    在渲染管线开始前,GPU需要从某个地方将顶点与索引数据读取出来,这就是这个阶段所完成的功能。

    这个阶段的性能表现取决于GPU是从哪个地方获取这些数据的,比如最开始是直接从系统主存中读取,而后面出于优化考虑,将数据提前传输到了local frame-buffer memory中。

    判断这个阶段是否会成为瓶颈就是直接修改顶点格式,减少每个顶点传输的数据长度。

    如果上述的所有过程都没有导致性能上升,那么问题就是出在CPU上面了。在定位到瓶颈之后,下一步就是优化过程。

    3. 优化

    根据不同的瓶颈,这里的优化方法也有所不同。

    3.1 CPU瓶颈

    CPU瓶颈主要有如下两种优化方法:

    1. 降低资源Lock操作。避免CPU/GPU的频繁传输
    2. 增加合批的力度,避免CPU提交导致的高消耗

    3.2 Vertex Transfer

    顶点、索引传输阶段的额瓶颈有如下几种方法:

    1. 减少顶点属性
    2. 将部分属性放到VS中直接计算
    3. 降低索引位数
    4. 按照顺序来对顶点进行访问(调整顶点顺序,增加缓存命中率)

    3.3 VS优化

    VS阶段的优化有如下几种思路:

    1. 优化顶点访问的顺序,增强缓存命中率
    2. 减少物件的定点数量
    3. 使用Mesh LOD
    4. 将一些低频计算放到CPU
    5. 使用正确的坐标空间,减少无谓计算
    6. 使用VS动态分支,减少代码计算的浪费

    3.4 Fragment Shading优化

    PS优化有如下几条思路:

    1. 先单独绘制一遍深度
    2. 使用early-z的功能降低浪费
    3. 将一些复杂计算的结果离线算好存储到贴图中
    4. 将一些低频计算放到VS中
    5. 降低格式精度
    6. 避免不需要的normalization
    7. 针对不同的物体使用不同计算复杂度的PS
    8. 减少三线性采样
    9. 使用尽可能简单的shader格式

    3.5 贴图带宽优化

    贴图带宽优化有如下几种方法

    1. 缩小贴图尺寸
    2. 选择合适的压缩方法
    3. 尽可能的避免大尺寸高精度的贴图
    4. 使用mipmaping

    3.6 Frame-buffer带宽优化

    FB带宽优化有如下几条方法:

    1. 先绘制一遍depth
    2. 避免alpha-blending带来的overdraw
    3. 避免无所谓的depth writes
    4. 避免不必要的color clear
    5. 在CPU侧做一下粗糙排序,按照从前往后的顺序进行绘制
    6. 优化天空盒渲染方案
    7. 不必要的情况不要使用浮点格式的RT
    8. 使用尽可能低精度的depth与color

    参考文献

    [1]. Chapter 28. Graphics Pipeline Performance

    相关文章

      网友评论

        本文标题:【GPU Gems】Chapter 28. Graphics P

        本文链接:https://www.haomeiwen.com/subject/sraoqltx.html