移动设备渲染架构以及GPU优化技巧

  • 前言
  • 一、常用的两种GPU渲染架构
  • 二、Immediate Mode Rendering
    • 1.说明
    • 2.优点
    • 3.缺点
  • 三、Tile-Based Rendering
    • 1.说明
    • 2.以Mali GPU为例
    • 3.优势
    • 3.缺点
  • 四、两种渲染架构对比
  • 五、移动端GPU优化建议
  • 总结
  • 参考

前言

目前所有的移动设备基本采用Tile-Based Rendering(基于图块的GPU架构,简称为TBR)渲染主流的渲染架构。本文主要介绍介绍TBR的优缺点。它还将Arm Mali基于图块的GPU架构设计与通常在台式机或控制台中发现的更传统的即时模式GPU进行了比较。
Mali GPU使用基于图块的渲染架构。这意味着GPU将输出帧缓冲区渲染为几个不同的较小子区域,称为图块。然后,它会在完成后将每个图块写出到内存中。使用Mali GPU,这些图块很小,每个图块仅16x16像素。


一、常用的两种GPU渲染架构

目前常用的两种GPU渲染架构是Tile-Based Rendering(基于图块的GPU架构),主要用于移动设备,还有一种是Immediate Mode GPUs(简称IMR, 即时模式架构)传统的台式机GPU架构。

二、Immediate Mode Rendering

1.说明

简称IMR, 也就是Full Screen,因为它不去分Tile,传统的台式机GPU架构通常称为即时模式架构。即时模式GPU将渲染处理为严格的命令流,在每个绘图调用中的每个图元上依次执行顶点和片段着色器。

伪代码如下:

for draw in renderPass:for primitive in draw:for vertex in primitive:execute_vertex_shader(vertex)if primitive not culled:for fragment in primitive:execute_fragment_shader(fragment)

2.优点

硬件数据流和内存交互图:

图上可以看出,顶点着色器以及其他与几何相关的着色器的输出可以保留在GPU内部的芯片,着色器的输出可以存储在FIFO缓冲区中,直到流水线的下一个阶段准备使用数据为止,GPU很少使用外部存储器带宽来存储和检索中间几何结果。
(备注:DDR为数据流, FIFO:First In First Out队列)

IMR的优势分析图:

IMR的优势是每个primitive直接提交渲染,pipeline没有中断,渲染速度快,pipeline并行起来时,每个Raster core只要负责render分给它的primitive即可,无需其他控制逻辑,只需在pixel shader后对Raster出的pixel做个排序。
(备注:raster为光栅化)

3.缺点

1):如果有很大的图形(主要是三角形)需要被渲染,那framebuffer就会很大,比如对于整个屏幕的颜色渲染或者深度渲染就会消耗很多存储资源,但是片上是没有这么多资源的,因此就要频繁读取DDR。很多和当前frame有关的操作( 比如blending, depth testing 或者 stencil testing)都需要读取这个working set,存储器上的带宽负载可能会非常高,并且这样能耗也很高,对于移动设备来说,这种方式很不利于设备运行;
2):z test跟blending都要频繁从framebuffer里读数据,毕竟framebuffer是位于Memory上,带宽压力和功耗自然高;
3):Overdraw的问题,比如Application在一帧里先画了棵树,然后画了面墙刚好遮住了树,在IMR下树仍然要在Pixel Shader里Sample texture,而Texture也是放在Memory,访存功耗大。

三、Tile-Based Rendering

1.说明

基于图块渲染也称基于瓦片渲染或基于小方块渲染,它是一种在光学空间中通过规则的网格细分计算机图形图像并分别渲染网格(grid)或图块(tile)各部分的过程。这种设计的优点在于,与立即绘制整个帧的立即模式渲染系统相比,它减少了对内存和带宽的消耗。这使图块渲染系统的使用特别常见于低功耗硬件设备。图块渲染有时也被称为中置排序(sort middle)架构,因为它在绘图流水线中间而不是接近结束时进行几何排序。

2.以Mali GPU为例

Mali GPU采用不同的方法来处理渲染过程,这就是所谓的基于图块的渲染方法。此方法旨在最大程度地减少片段着色期间GPU需要访问的外部存储器的数量。
基于图块的渲染将屏幕分成小块,并对每个小图块进行着色着色,直到将其写出到内存中为止。为了使这项工作有效,GPU必须预先知道哪些几何图形有助于每个图块。因此,基于图块的渲染器将每个渲染过程分为两个处理过程:
1):第一遍执行所有与几何相关的处理,并生成图块列表数据结构,该结构指示哪些图元对每个屏幕图块起作用。
2):第二遍将逐块执行所有片段处理,并在完成后将切片写回到内存中。请注意,Mali GPU渲染16x16的图块。

伪代码如下:

# Pass one
for draw in renderPass:for primitive in draw:for vertex in primitive:execute_vertex_shader(vertex)if primitive not culled:append_tile_list(primitive)# Pass two
for tile in renderPass:for primitive in tile:for fragment in primitive:execute_fragment_shader(fragment)

下图显示了硬件数据流以及与内存的交互:

优势:解决了传统模型的带宽问题,因为fragment shader每次都是读取一个小块放在片上,不需要频繁读取内存,直到最后操作完成,再写入内存。甚至还能够通过压缩tile的方法进一步减少对于内存的读写。另外在图像有一些区域固定不动的时候,通过调用函数判断tile是否相同,减少重复的渲染。

3.优势

下图显示了TBR的优势:

对于IMR所有read z/framebuffer,到了TBR通通不需要。TBR只需render完tile后把on-chip的pixel写到frame buffer(不需要写z,因为下一帧不需要用到前一帧的z和color)。这个好处在于TBR将Screen Tiling。这样,每次render的区域变小,小到可以把z/framebuffer搬到on-chip,快,省电。

另外另外两点优势是:
1):TBR给消除Overdraw提供了机会,PowerVR用了HSR技术,Mali用了Forward Pixel Killing技术,目标一样,就是要最大限度减少被遮挡pixel的texturing和shading。
2):TBR主要是 cached friendly, 在cache里头的速度要比全局内存的速度快的多,以及有可能降低render rate的代价,降低带宽,省电

3.缺点

1):这个操作需要在vertex阶段之后,将输出的几何数据写入到DDR,然后才被fragment shader读取。这之间也就是tile写入DDR的开销和fragment shader渲染读取DDR开销的平衡。另外还有一些操作(比如tessellation)也不适用于TBR;
2):如果某些三角形叠加在数个图块(Overdraw),则需要绘制数次。这意味着总渲染时间将高于即时渲染模式。

四、两种渲染架构对比

下图显示了两种渲染架构的对比:

说明:
1):IMR的pipeline畅通无干扰,sorting简单,TBR的sorting较复杂,但也给低功耗优化提供了灵活的选择;
2):Geometry的transform和场景的tiling,然后往memory里写入Geometry的数据和每个tile所要rendering的Geometry,相对来说多了内存消耗;
3):PC屏幕大,PC game场景复杂,对Tile list压力大,另外PC追求frame rate,所以很少用TBR,即使用了,遇到复杂游戏场景估计会切换到IMR。

五、移动端GPU优化建议

对于对于GPU优化通常会有两个方向,一个是带宽,另一个是填充率。
1):填充率,可以简单的理解为图形处理单元每秒渲染的像素数量。可以通过对中高低进行分辨率的适配来调整,比如对于低档机子,分辨率(以高为基准)720p的方式,中档机为720p1.2,高档机型为1080(7201.5)的方式来调整。同时也需要控制好Shader的复杂度(顶点着色器和片元着色器)。对于如何分析shader的复杂度,可以通过对shader代码的分析,比如函数的指令级别等进行优化
(参考:http://cdn.imgtec.com/sdk-documentation/PowerVR%20Low%20level%20GLSL%20Optimisation.pdf)
不过最终的性能分析,还是需要借助工具来实现,推荐使用Renderdoc,ios可以直接用XCode,分析每个PS(片段着色器)的耗时,至于如何使用Renderdoc,后续会发文章来介绍。

2):显存带宽,这块很多文章都有介绍,通常大部分图片不要超过1024即可,但场景有些贴图是可以2048的,但要注意是否2048的图是否空出来太多,还有normal贴图,emission图等大小控制,这些贴图通常都是小于等于1024,这块需要约定好一个标准。至于压缩格式,Android和IOS通常使用ASTC_RGBA_6x6或者ASTC_RGBA_8x8,不带Alpha通道为ASTC_RGB_6x6 or ASTC_RGB_8x8,因为目前大部分的Android平台都是支持ASTC,但对于比较老的机型,比如15年,ES3.0,可能会不支持ASTC,目前这块的用户量其实比较少,看项目需求是否坚持采用ASTC,不然就ETC2格式,或者做个兼容。
下图显示了如何通过调整贴图设置去打手机包分析是否带宽瓶颈的一种方式:

上图是unity引擎上的,Unity的质量选项里可以设置纹理的缩小倍数,它会限制GPU使用的纹理大小(但不会减少内存占用),这样能成倍减少贴图的带宽使用量,但对读屏幕那一部分没有任何影响。如果调低它帧数上升了,就可以说明确实遇到了带宽瓶颈,但没变化,也有可能是因为优化幅度太低了看不出来。

还有一种方式可以减少带宽,mipmap,不过这块会多占用33%的内存大小,如果目前内存使用已经很多了,需要注意这块的使用,通常来说一般会对场景和角色的贴图做mipmap,其他的不做mipmap(会糊掉),做mipmap还是根据实际情况分析是否需要做这块。对于一些自研引擎或者是UE4,会有一种贴图加载的mipmap,比如一开始在包体上有一种贴图就有1024,512,256,128的大小的,通过mipmap偏移去加载对应大小的贴图带显存上,这种方式可以优化内存的大小的。

总结

目前通常移动设备采用的架构都是TBR的,对于GPU优化通常会有两个方向,一个是带宽,另一个是填充率。对于TBT架构来说,影响比较大还是填充率,可以通过调整分辨率,Shader的复杂度(顶点和片元着色器的复杂度)等来控制。而带宽的话,通常大部分图片不要超过1024即可,但场景有些贴图是可以2048的,但要注意是否2048的图是否空出来太多,还有normal贴图,emission图等大小控制,这块需要约定好一个标准。

参考

【1】https://developer.arm.com/solutions/graphics-and-gaming/developer-guides/learn-the-basics/tile-based-rendering/immediate-mode-gpus
【2】https://zh.wikipedia.org/wiki/%E5%9F%BA%E4%BA%8E%E5%9B%BE%E5%9D%97%E6%B8%B2%E6%9F%93
【3】https://zhuanlan.zhihu.com/p/92840602
【4】https://www.zhihu.com/question/49141824
【5】 https://community.arm.com/developer/tools-software/graphics/b/blog/posts/killing-pixels—a-new-optimization-for-shading-on-arm-mali-gpus

移动设备渲染架构以及GPU优化技巧相关推荐

  1. 前端框架/架构,性能优化,负载均衡,首屏渲染

    前端数据结构与算法- https://zhuanlan.zhihu.com/p/27659059 > 前端重构方案 前端重构方案了解一下- https://blog.csdn.net/vM199 ...

  2. 深度学习训练的时候gpu占用0_26秒单GPU训练CIFAR10,Jeff Dean也点赞的深度学习优化技巧...

    选自myrtle.ai 机器之心编译机器之心编辑部 26 秒内用 ResNet 训练 CIFAR10?一块 GPU 也能这么干.近日,myrtle.ai 科学家 David Page 提出了一大堆针对 ...

  3. JavaScript 工作原理之十一-渲染引擎及性能优化小技巧

    原文请查阅这里,略有删减,本文采用知识共享署名 4.0 国际许可协议共享,BY Troland. 本系列持续更新中,Github 地址请查阅这里. 这是 JavaScript 工作原理的第十一章. 迄 ...

  4. JavaScript 工作原理之十一-渲染引擎及性能优化小技巧 1

    原文请查阅这里,略有删减,本文采用知识共享署名 4.0 国际许可协议共享,BY Troland. 本系列持续更新中,Github 地址请查阅这里. 这是 JavaScript 工作原理的第十一章. 迄 ...

  5. GPU渲染技术及性能优化

    GPU渲染技术及性能优化 背景:在我们做图形界面程序开发时,不得不考虑一个问题是GPU渲染性能,GPU是否能支持我们想象中炫酷的设计和动画,这就需要我们对GPU渲染技术有一定的了解,这样我们才能在开发 ...

  6. iOS开发中常见的性能优化技巧

    性能问题的主要原因是什么,原因有相同的,也有不同的,但归根到底,不外乎内存使用.代码效率.合适的策略逻辑.代码质量.安装包体积这一类问题. 但从用户体验的角度去思考,当我们置身处地得把自己当做用户去玩 ...

  7. 白鹭引擎王泽:重度H5游戏性能优化技巧

    9月15日,无惧17级台风"山竹",320名开发者齐聚广州贝塔空间共同探讨"怎样做一款赚钱的小游戏".针对众多开发者关心的重度H5游戏性能优化技巧,我们整理了现 ...

  8. 白鹭引擎王泽:重度H5游戏性能优化技巧标题的文章

    我们的引擎架构师做某一沙龙活动的演讲速记,纯纯的干货,分享给大家. 王泽:各位开发者下午好!我叫王泽,是白鹭引擎的首席架构师. 今天给大家分享的题目是<重度H5游戏性能优化技巧>.之所以决 ...

  9. 【Egret优化分享】白鹭引擎王泽:重度H5游戏性能优化技巧

    本文转自:https://mp.weixin.qq.com/s/GIzXA51D7_hMqajCRuJE2g 9月15日,无惧17级台风"山竹",320名开发者齐聚广州贝塔空间共同 ...

最新文章

  1. python文件目录操作方法_Python常用的文件及文件路径、目录操作方法汇总介绍
  2. 10.static_extern
  3. sr650服务器cpu型号,至强Gold 联想ThinkSystem SR650评测
  4. QEMU/KVM原理概述
  5. “Max“ stands for big
  6. 联通最全最新路由表【两种表示方式都在】
  7. 为什么从事软件开发测试?
  8. 《java入门第一季》之面向对象(成员方法)
  9. ssm社区线上超市购物系统毕业设计-附源码211704
  10. Steam流式传输后插耳机没有声音
  11. 只需四天,从零开始选购笔记本电脑【转】【荐】
  12. 小数除法竖式计算过程
  13. 金融小知识 | Fama-Macbeth回归
  14. python opencv把一张图片嵌入(叠加)到另一张图片上
  15. 关于cm5forG1的升级脚本修改
  16. CSS3制作Freebie标签
  17. Flutter Dio网络请求:DioError [DioErrorType.RESPONSE]: Http status error [400]或者[500]
  18. SEO工作者面试基本都会被问到的问题
  19. SpringBoot:概述,注解,搭建,部署
  20. PHPMyWind支持PowerPoint上传

热门文章

  1. ARC Welder——Android 模拟器——App Runtime for Chrome
  2. 渗透之——十大渗透测试演练系统
  3. codeup21751 超过平均身高
  4. python中常用英语口语_课堂上,常用到的英语口语有哪些。?
  5. div 随着内容撑开
  6. 六十五、vue生命周期和发送Ajax请求
  7. magjic mouse2频繁断开连接!
  8. “说”——英语学习的另一转折点
  9. 从零开始搭建公司域环境(七):在文件服务器上为每位域用户创建个人文件夹homefolder
  10. 低延时实时音视频在5G远程操控场景的应用实践