心如工画师,能画诸世间,五蕴悉从生,无法而不造 。 ---------佛说
CPU与GPU
CPU作为中央处理器,除了要负责逻辑计算外,还需要做内存管理,显示操作,因此随着各种复杂App的出现,其实际运算的性能会大打折扣。
设计原由:为了提高图形显示效率以及复杂的图形的显示,设计出了GPU
主要功能:为帮助CPU分担图形显示。

CPU
蓝色的Control微控制器,用于协调控制整个CPU的运行,包括取出指令,控制其他的模块运行等;
绿色的ALU(Arithmetic Logic Unit)为算数逻辑单元,用于数学以及逻辑运算;
橙色的Cache和DRAM分别为缓存和RAM,用户存储信息
CPU控制器比较复杂,ALU数量较少,因此CPU擅长各种复杂的逻辑运算,但不擅长数学尤其浮点运算
GPU
GPU和CPU唯一不同的是GPU的ALU模块占据了相当大的板块,为什么说GPU中ALU占据了这么大的板块呢?它主要的原因就是因为ALU擅长数学运算以及逻辑运算。而我们都知道GPU是为了提高图形的显示效果,为什么说ALU擅长数学运算以及逻辑运算就能够处理好图形的显示呢?首先我们都知道我们的屏幕上面之所以可以看到五颜六色的图片的话,手机它自己是不知道把这么一张五颜六色的图片显示出来的,它只会根据我们传过去的像素点来显示,屏幕是由一个一个的像素点而组成,那么它只需要知道屏幕上的每一个像素点是什么颜色即可,从而达到显示的效果。我们都知道在手机上显示颜色的时候我们都会用一个16进制的数来表示,比如说刚开始有一块A区域颜色是#FFFFFFFF,这个时候我们要将白色的A区域转换成黑色的#22222222,在这个转换的过程中是一个数学的逻辑运算,对于数学运算的ALU是比较擅长的,这也恰恰说明了在GPU中ALU为啥占据了这么大的一个板块。
XML布局显示至屏幕流程

首先我们在XML文件里面定义了一个button,这个button包含了一些height ,width,background...等一些这样的信息,然后通过LayoutInflater解析布局将解析出来的这些信息加载进内存,然后CPU将LayoutInflater解析出来的信息通过计算处理成位图,紧接着CPU将处理出来的这个位图交给GPU,GPU呢会对这个位图做一些删格化,什么是删格化????,比如说我们的这个button,长是50dp,高是50dp,背景是红色,GPU拿到CPU交给它的这个宽高50dp的位图以后,GPU首先会将这个红色区域转化成一个一个的红色像素点,也就是说GPU将位图转化成像素点的过程即为删格化。删格化以后GPU将转化成的像素点传递给屏幕从而达到显示的效果,这个时候我们手机屏幕上面会显示出来一个宽高50dp,背景是红色button。
FPS概念
12fps:画面帧率高于每秒约10-12帧时,眼睛会认为它是连贯的。
24fps:有声电影拍摄一般为24帧
30fps:早期动态电子游戏,一般会在每秒30帧左右
60fps:手机交互过程中,需要接触和反馈。需要60帧才能达到不卡顿的效果(比如说我们手机上面要显示一个button,这个button显示到屏幕的过程中如果每秒中绘制少于60帧的化,用户就会觉得有卡顿的效果)
了解了FPS概念以后我们需要了解安卓系统每隔16ms,它就要发送一次Vsync信号对UI进行一次渲染,如果每次都能成功的话,就会达到流畅,也就是我们刚说的每秒60帧。这个16ms是怎么来的呢?因为每秒钟要达到60帧的效果,UI我们才看起来不会卡顿这也意味着每秒要是绘制60帧,1秒=1000ms,1000/60=16ms,这也就是为啥安卓系统要每隔16ms要发送一次vsync信号对UI进行一次渲染。这也充分说明如果我们写的自定义View或者使用系统的控件组合的自定义View或者我们写的XML布局文件,如果在16ms内完成不了绘制,客户就会觉得卡顿。
优化目标
1 CPU减少XML转换成对象的时间
2 GPU减少重复绘制
在实际开发中以上两步必须要在16ms内完成,否则用户会感觉到卡顿效果。
记住是16ms内完成绘制 ,记住是16ms内完成绘制 ,记住是16ms内完成绘制 记住是16ms内完成绘制 ,重要的事情说四边
过渡绘制的概念
GPU每个16ms发送一个vsync信号画一次,如果CPU传递过来的图形有重复的位置,会造成用户智能看到顶层画面,而底层画面则被遮盖,底层画面的绘制虽然用户无法看到,但同样也占据了计算资源,造成不必要的浪费,这种情况叫过度绘制。
过度绘制查看工具


打开开发人员选项,开启调试GPU过度绘制,颜色说明,浅蓝色表示只有一层绘制,浅绿色表示只有两层绘制,粉色表示有三层绘制,红色表示4层或者更多绘制,一般情况下我们只需要关注红色区域的布局文件或者自定义View的代码,即优化这个区域的代码即可达到性能优化的效果,接下来我们用一个示例程序来演示过度绘制以及优化方案。


XML布局代码



运行效果图如下

分析,当前这个页面存在过度绘制的情况,页面出现粉红色的主要原因,是XML里面嵌套了太多的层级。下面对示例代码中XML层级做出具体的分析。
首先GPU在绘制的过程中会绘制一个LinearLayout,紧接着又会绘制imageView和LinearLayout,LinearLayout绘制完毕以后又有一个android:background="@android:color/darker_gray"的背景颜色,紧接着会绘制这个灰色的背景色,背景色绘制完毕以后紧接着又会绘制RelativeLayout和一个TextView和一个android:background="@android:color/white"白色背景,RelativeLayout绘制完毕以后又会绘制android:background="@android:color/white"白色背景,白色背景绘制完毕以后紧接着又绘制两个TextView,这样多层级的嵌套是导致过度绘制的主要原因,过度绘制导致了GPU资源的浪费。
解决方案
减少布局嵌套层级以达到同样的功能效果,修改以后的代码以及运行效果如下图。



网友评论