游戏测试 Perfdog 实战之减少 CPU 消耗
导语:
最近在测试过程中发现了一些比较典型的性能问题,所以来分享下作为测试怎么为解决问题提供更多的有效信息,本次主要从优化角度分析Perfdog测试报告。本次主要介绍关于CPU的优化;
怎么获取测试报告此处不再赘述,有关perfdog怎么使用的教程可以参考
Perfdog使用教程
# 1. 第一部分,查找问题,找出问题特征点
首先我们看到FPS数据,可以看到FPS波动较大,但这是从某一时间开始的,在前期游戏FPS还是较为稳定的,那我们就要分析是什么原因导致的FPS开始变得不稳定;
我们发现CPU的消耗在这个时间段开始骤然上升,CPU的温度升高,导致手机的降频保护开启,CPU的频率开始下降,
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200321160918644.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0Njk2MjAz,size_16,color_FFFFFF,t_70)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200321161010934.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0Njk2MjAz,size_16,color_FFFFFF,t_70)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200321161051267.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0Njk2MjAz,size_16,color_FFFFFF,t_70)
# 2. 第二部分,分析报告后,得到分析结果
经过以上的数据分析,我们发现是游戏在那个时间点时CPU消耗上升,导致CPU的温度升高,处发了CPU的保护机制,引起CPU频率下降,而游戏得不到充足的算力支持,自然FPS变得不稳定;
# 3. 第三部分,得到分析结果,分析可以优化的空间
我们已经得知问题是CPU温度过高的问题,那么就要相应降低CPU的消耗,而CPU的消耗主要有以下几个方面(这里仅针对Unity引擎的,其他引擎仅供参考)
对于MMORPG手游:
CPU的消耗可以从半透明渲染和不透明渲染入手解决;
可能有的同学会疑问,渲染通常都是GPU做的,和CPU有毛线的关系,这里要解答一下,
在安卓机器设计结果中目前大部分都是沿用的冯·诺依曼结构,也就是我们通常说的计算机的五大部件:
运算器、控制器、存储器、输入设备、输出设备, 而运算器、控制器组合就是CPU,所以算力通常都是由CPU提供的,而如果不在游戏中另做设置的话,即使渲染也是由CPU提供的算力,而GPU就是为了减轻CPU的这种渲染压力而设计出来的一个部件,严格意义上来讲也属于运算器;
所以为了减轻压力,我们要把一些算力分给GPU,减轻CPU的负担,而unity常用的手法有以下几种:
1.开启GPU Instancing,降低drawcall:
该技术可有效降低Draw Call的占用,从而对渲染模块的CPU端压力起到一定的缓解作用。但是,在使用该技术时,需要注意机型的测试,此技术仅可以用于OpenGL ES 3.0,而且一些低端设备虽然支持OpenGL ES 3.0,且SystemInfo.supportsInstancing API返回也为True,但经过实际测试时,其底层并没有按照真实的GPU Instancing功能来进行渲染,而是通过逐个Draw Call来进行渲染,所以,虽然开启了GPU Instancing功能,但其渲染耗时并没有下降;
这里涉及到了drawcall,简单介绍一下:
drawcall是CPU对底层图形绘制接口的调用命令GPU执行渲染操作,一次渲染就是一个Drawcall
渲染流程采用流水线实现,CPU和GPU并行工作,它们之间通过命令缓冲区连接,CPU向其中发送渲染命令,GPU接收并执行对应的渲染命令,过多的DrawCall会造成CPU的性能瓶颈:大量时间消耗在DrawCall准备工作上。很显然的一个优化方向就是:尽量把小的DrawCall合并到一个大的DrawCall中,这就是批处理的思想,也就是GPU Instancing主要做的事情;
但要注意不要过于消耗GPU,在开发游戏过程中随着PBR、图像后处理的大量使用会导致GPU端的压力越来越大,甚至影响到了CPU端的Draw Call无法正常传输。可以说,主线程等待时间的体现方式因芯片的不同、具体使用情况的不同和引擎版本的不同,可谓是五花八门,在这里不一一进行说明,但归根原因主要还是GPU压力过大;
2.注意控制GC触发频率很
随着MMORPG游戏越来越重度化,GC平均耗时在逐步上升,也会造成卡顿,大量的GameObject在频繁实例化和Destroy会造成很大的性能开销;
3.Shader.Parse
这里给出一些建议,
1)Shader在游戏运行过程中是否存在冗余情况,即重复加载的情况;
2)是否有自定义的Shader资源放入到Always Included中,如有,请尽量去除;
3)移动端上Standard Shader的使用是否确实有必要。没有必要,则详细检测并删除。
4.动画模块
大量动画的产生会产生严重的开销,unity引擎可以考虑使用GPU Skinning的方式进行优化,这种方式对于实现场景中的大量同种怪物非常有效,可以减少很多开销。其核心其实也是合批的思想;
5.粒子系统
这里建议尽可能将粒子使用数量峰值控制在600以下(低端设备)和1000以下(中高端设备),
可以检查下
1)粒子系统(特别是技能特效)的配置文件是否过量;
2)特效中是否含有长久不用的粒子系统。
以上是结合Perfdog的测试报告针对在游戏开发中CPU优化的一些常用手段,相信可以带来一些启发,大家可以根据自己的项目实际情况做参考;减少CPU的消耗,降低CPU的温度。