原文由黑子发表于TesterHome社区,点击原文链接可与作者直接交流。
导读
目前游戏行业已经呈现精品化状态,行业对测试岗位的要求也越来越高,前端性能测试仅仅是用工具测试出相关数据(自动化测试即可满足,包括自动化脚本,或者自动化录像),并告知研发,已经不能满足测试要求。所以性能测试岗同学需要具备更多硬性技能,本篇文章适合性能测试新手;分别从测试场景,测试工具,然后测试数据概念,之后到和开发、美术同学在优化中的沟通,以及最后常用的优化方法策略,逐一展开介绍。
一、测试场景
1.导读
前端性能测试,关注用户在玩游戏过程中的性能方面的体验,包括是否卡顿,是否crash,是否手机发热,是否耗电过快等,不管用户的手机是高配机,中配机器,还是很渣的低配机器,都需要关注用户性能体验(有同学问,为什么还这么关注低配机用户的感受,他们能充钱吗?游戏是一个生态,比如5%的RMB用户需要剩余95%的屌丝用户来衬托;另外游戏口碑等都需要考虑所有用户的体验等)。
2.卡顿
游戏流畅是游戏比较基本的性能指标,尤其在核心玩法的时候。从测试角度看,更多关注游戏的fps数据、卡帧率、bigjank值等
3.crash
用户不希望游戏过程中出现crash情况,测试关注crash率数据
4.发热
手机发热之后除了体感不好,另外不同的手机厂商会选择降频或者锁核,从而导致游戏卡顿。手机发热原因较多(比如运行高功耗app、在充电中、不良电池、保护壳不能散热、所处环境温度高等),这里关注的是怎么降低游戏的功耗,其实更多是怎么降低GPU和CPU的使用率
耗电过快
手机电池毫安数本身就是手机的重要指标,耗电快无疑是硬伤。
二、测试工具介绍
1.perfdog
腾讯出品的性能工具,无需root或者越狱。PerfDog支持移动平台所有应用程序(游戏、APP应用、浏览器、小程序、小游戏、H5、后台系统进程等)
安装,使用教程等参考官网详细介绍:
https://bbs.perfdog.qq.com/article-detail.html?id=5
2.UWA
针对unity和unreal引擎的游戏或者VR产品提供服务,包括资源监测(动态和静态,免费),性能诊断和优化(收费),lua性能分析,自动化测试,社区问答等
UWA GOT是UWA推出的本地性能测评工具,需要装对应sdk,无需越狱或者root。
UWA成立2015年,目前积累了不少用户和测试数据,是目前比较主流的测试工具和社区。
安装和使用,官网详细介绍:
https://uwa-public.oss-cn-beijing.aliyuncs.com/uwa-got/document/UWA%20GOT%20%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.pdf
3.UPR
UPR开始于这两年(2019开始,wetest的性能之前和untiy配合,后来wetest自研了Perfdog,游戏性能移交给unity自己做了),目前UPR在积累用户中,所以是免费的,而且技术支持比较好(有什么问题反馈比较及时,甚至会现场解决),UPR的一些功能还在完善和开发中
URP分手机和桌面版,可以带sdk和不带sdk,当然,没有继承UPR sdk的测试数据会少。
安装和使用,参考官网介绍:
https://upr.unity.cn/instructions
4.其他测试工具
比如腾讯GT,网易的Emmagee,以及google的工具等等
5.自研测试工具
对应一些厂商,比如调用引擎给的接口等方法,来获取相关性能数据,来实现工具的目的。
三、测试数据概念介绍
1.内存
一般关注:
①pss内存(实际使用的物理内存)的大小(ios和andriod机器一般都是分三档机器,每档机器的pss内存标准不一样,标准数值随着硬件设备提升也在逐渐而变高)
②内存泄漏(内存泄漏后,内存越来越大,可能会因为申请分配内存越来越慢导致的卡顿,或者crash等)
③内存资源重复率:资源重复是指内存中同一时刻,存在两份或以上相同的纹理、网格、动画、音频等资源。一般是相同的一份资源被打包到多个AB包中,如果这些AB都被加载进内存,内存中就会存在多份相同的资源
2.bigjank
PerfDog计算方法:同时满足两条件,则认为是一次卡顿Jank.
1、 当前帧耗时>前三帧平均耗时2倍。
2、 当前帧耗时>两帧电影帧耗时(1000ms/242=84ms)。
同时满足两条件,则认为是一次严重卡顿BigJank.
1、 当前帧耗时>前三帧平均耗时2倍。
2、 当前帧耗时>三帧电影帧耗时(1000ms/243=125ms)。
3.FPS
帧率,标准要求比如:核心游戏场景默认要求90%数值都不低于25FPS;
流畅度
比如:核心游戏场景,默认要求卡顿率不高于2%
4.CPU
比如:综合CPU平均占用(90%)小于60%,单核CPU峰值占用(90%)小于90%
另外要关注单核CPU使用率,以及是否所有内核都在使用,以及使用是否平均等
还有CPU的曲线是相对平滑,还是锯齿严重
5.工具中常用数据
cpu:
①frameTime:同一帧的耗时
②Rendering Time:当前帧渲染耗时;drawcall越高,这部分开销越大
③ScriptTime:当前帧函数耗时
④PhysicsTime:当前帧物理耗时
内存:
代码中的内存 –Mono内存(mono内存,内存池,只增不减);资源中的内存占用 –Native内存
①ReservedMono:一般是脚本分配的内存
②pss内存:一般用于定位多局战斗、场景跳转、打开关闭UI中是否有内存泄漏
③total_reserved内存:unity_reserved内存+GFX内存+FMOD内存+Mono内存+Profiler内存
④mono reserved:分配的mono内存(绿线部分),只升不降,需要严格控制。mono内存表示游戏中脚本分配的内存
⑤gfxdriver_reserved:表示渲染模块的内存,如果比较高需要对纹理资源和Shader进行优化。
⑥fmod_reserved:表示音频模块的内存,如果比较高需要对音频资源进行优化
⑦内存资源重复率:资源重复是指内存中同一时刻,存在两份或以上相同的纹理、网格、动画、音频等资源。一般是相同的一份资源被打包到多个AB包中,如果这些AB都被加载进内存,内存中就会存在多份相同的资源
其他数据可以参考:
https://segmentfault.com/a/1190000016342638?utm_source=tag-newest
四、研发(开发和美术)概念介绍
1.导读
在和研发同学沟通时,需要对研发上的一些概念,以及常用的优化思路,方法有所了解,可以根据问题数据,提供一些优化建议。
2.图集atlas
是通过专门的工具,将多张图片合并成一张大图,并通过 plist 等格式的文件索引的资源
NGUI强调图集,图集要规划好,否则经常会出现图集不够用等问题;UGUI弱化用户对图集的概念,在打包的时候自动生成图集。各有优缺点
目前研发团队中主要使用的则是Unity自身的 UGUI系统 和Asset Store上的 NGUI插件
3.画布canvas
Canvas画布是承载所有UI元素的区域。Canvas实际上是一个游戏对象上绑定了Canvas组件。所有的UI元素都必须是Canvas的自对象。如果场景中没有画布,那么我们创建任何一个UI元素,都会自动创建画布,并且将新元素置于其下
4.Collider
碰撞体
5.网格mesh
mesh就是我们所说的三角网格。三角网格就是由一系列三角形组成的多边形网格,主要用于模拟复杂物体的表面,事实上游戏开发过程中美术给我们的人体、车辆模型都是由一个或多个三角网络(mesh)组成的。
工具:mash baker,能够有效合并网格以及网格所使用的材质,来有效减少渲染批次所带来的开销
6.纹理Texture
纹理即“纹路”,每个物体表面上不同的样子,譬如说木头的木纹状。纹理就是一段有规律、可重复的图像
7.贴图 Map
贴图是图,最简单的形式是ps之类的软件做出来的一张图,这些图在3D中用来贴到物体的表面,用来表现物体的“纹理”
最有名的是lighting map,即光照贴图, 光照贴图是生成或者绘制出来,用于物体表面模拟光照效果的
8.材质Material
材质主要是用来表现物体对光的交互(反射、折射等)性质的。譬如金属对光的反射和毛毯对光的反射性质完全不一样,那么对3D程序来说,这样的差别就通过材质这个属性来计算出不同的颜色。
材质,本质是数据集:表现物体对光的交互,供渲染器读取的数据,包括贴图,纹理,光照算法等
9.着色器shader
实际上就是一小段程序,它负责将输入的Mesh(网格)以指定的方式和输入的贴图或者颜色等组合作用,然后输出,模拟真实世界中的光影效果,这个效果是由物体表面材质、灯光、观察者的视角等多种因素共同决定的
Unity中所有的渲染都使用着色器完成
10.材质球
U3D引擎中材质的预览方式为一个球体,材质球是什么样子,通常由贴图决定
纹理---贴图--->经过shader---->材质球--->材质球贴到具体的模型上,生成模型1,模型2......
11.Alpha通道
指一张图片的透明和半透明度
对于16bit存储的位图,每5个bit分别表示红黄蓝,最后一个bit是表示阿尔法通道,0或1,所以要么透明要么不透明;对于32位存储的位图,每8个bit分别表示红黄蓝,最后8位表示阿尔法通道,就有256种透明可能
12.draw call
简称DC,由CPU收集美术的资源信息,传递给GPU,通知GPU进行一次渲染过程叫DrawCall。是cpu通知gpu干活的一种命令
- 为什么drawcall多了会影响帧率
- 在每次调用Draw Call之前,CPU需要向GPU发送很多内容,包括数据,状态,命令等。在这一阶段,CPU需要完成很多工作,例如检查渲染状态等
而一旦CPU完成了这些准备工作,GPU就可以开始本次的渲染。 - GPU的渲染能力是很强的,渲染300个和3000个三角网格通常没有什么区别,因此渲染速度往往快于CPU提交命令的速度。
- 如果Draw Call的数量太多,CPU就会把大量时间花费在提交Draw Call命令上,造成CPU的过载。因此造成Draw Call性能问题的元凶是CPU
提交大量很小的Draw Call会造成CPU的性能瓶颈,即CPU把时间都花费在准备Draw Call的工作上了。把很多小的Draw Call合并成一个大的Draw Call,这就是批处理的思想。
13.渲染通道pass
每个pass都会消耗一个drawcall,在满足渲染效果的情况下,尽可能减少渲染通道的数量
14.Lightmap
其实就是打了灯光的贴图,通常是对游戏场景中静态物体上,贴了一层带灯光效果的贴图
优点:省去了很大光照相关的计算,减少了性能的消耗
缺点:多了一层纹理,我们使用了灯光贴图肯定多了一层纹理。另外静态贴图无法改变灯光的方向,比如灯泡被用户打碎了,灯光效果还在,实际要干掉
15.mipmap
也是贴图。使用Mipmap后,贴图会根据摄像机距离的远近,选择使用不同精度的贴图
Mipmap技术有点类似于LOD技术,但是不同的是,LOD针对的是模型资源,而Mipmap针对的纹理贴图资源
缺点:会占用内存,因为mipmap会根据摄像机远近不同而生成对应的八个贴图,所以必然占内存!
优点:会优化显存带宽,用来减少渲染,因为可以根据实际情况,会选择适合的贴图来渲染
16.LOD
在游戏场景中,根据摄像机与模型的距离,来决定显示哪一个模型,一般距离近的时候显示高精度多细节模型,距离远的时候显示低精度低细节模型。
优点:可根据距离动态地选择渲染不同细节的模型,从而提高渲染的效率
缺点:加重美工的负担,要准备不同细节的同一模型,同样的会稍微增加游戏的容量
17.烘焙
物体表面的反光或者阴影,记录到模型里,形成新的贴图,运行的时候,显卡和CPU不需要进行对环境光效果的运算了。实际上就是lightmap的生成过程
18.面数Tris
模型上的三角形面数,对应不同类型的模型,一般有不同的标准,比如小怪多少面,精英怪多少面,boss多少面,随着游戏制作精度和硬件的提高,面数的标准也随着变多
19.bloom
Bloom放在后期特效中,是实现光线绽放,灯光溢出的效果
特效有有2个最常见的后期:Color Grading(调色) 和 Bloom(泛光/辉光)
参考链接:
https://zhuanlan.zhihu.com/p/76505536
20.GC
垃圾回收,一种内存管理机制(针对堆内存)
参考链接:
https://www.jianshu.com/p/db449e84a7ab
21.AssetBundle
资源打包,简称AB包,主要考虑打包策略和加载策略,比如:把需要同时加载的Asset尽量打包到同一个AB里。例如模型,其纹理和动画
参考链接:
https://zhuanlan.zhihu.com/p/91926428
22.渲染技术汇总
https://blog.csdn.net/poem_qianmo/article/details/78309500
五、开发优化工具介绍
不同的项目组,有不同的优化工具,也有共用的。
1.常见的共用优化工具
Unity Profiler,Unity Memory Profiler, XCode Instrument. XCode Instrument内又包含了很多工具,其中最常用的有Time Profiler,Allocation以及Capture GPU Frame。adb命令
比如:XCode Allocation,会统计内存的分配和释放情况,从而看出是否存在内存泄漏情况(比如主城--战斗--主城,内存快照的情况下)
自研优化工具
比如:场景优化时:按照格子(比如4米*4米)获取场景内的热点数据;比如按照场景摄像机内的物件个数和物件类别的比例曲线,比如场景中,重复材质检查工具等
六、常用的优化方法策略
1.导读
①性能优化是一个长期的过程
②性能优化不但是程序部门的事情,而是需整个项目组共同配合和努力的结果,一般项目组每个部门都会有对应的专职人员
③好的优化工具至关重要
④不同的机器设备,展示的美术品质是不一样的,所以针对机型(分三档机器)有不同的优化策略
⑤每个核都充分利用,多线程渲染技术(unity5以上就开始支持了)
⑥在不同的场景,时间和空间的选择(时间换空间,还是空间换时间,CPU和GPU可以互换,CPU和内存可以互换、内存和磁盘可以互换)
⑦不必要渲染的东西不渲染(比如UI层级,不显示的UI不渲染;不在摄像机内的不渲染;遮挡减少渲染;imposter,LOD,minimap等)。不必加载的内容不加载(比如大表拆分按需加载;图集拆分按需加载等;AB包加载策略等)。能压缩的都压缩(这个好理解)
⑧性能优化不是一劳永逸的事情,是持久战;即便是已经上线多年的长线产品,性能测试也是一如既往在挖掘性能点并优化
参考:
https://segmentfault.com/a/1190000019844821?utm_source=tag-newest
2.场景优化
①关注场景的热点数据(比如按照2米一个计算范围单位),通过调整物件的位置,优化物件的资源等来优化热点问题
②添加关键遮挡物,来减少相机内的渲染量
③LOD技术的运用,或者imposter技术的运用等
④远景物件包括角色怪物等平滑渲染(多帧完成渲染)
等等(方法还有很多)
3.同屏人数优化
①同屏人主要集中的场景点,第一是要场景分离,比如拍卖行和交易地点分开,一个室内,一个室外;第二是减少对应场景的物件消耗
②计算策略优化,优先渲染离自己近的角色和场景物件
②效果优化,比如同一类型的特效到一定数量后不在渲染等
④同屏时用户角色是动态的,不停的加载和释放,做平滑处理(按帧控制渲染数目方法等)。避免瞬间加载导致的卡顿
⑤同屏战斗时,尤其国战,同角色avatar一样
⑥Imposter(伪装者,或者叫替代物)技术:(基本原理用相机把模型各个角度的图片拍下来,然后根据玩家相机的角度选取不同的图片显示)
等等(方法还有很多)
4.UI优化
比如:
①格式
②尽可能将动态UI元素和静态UI元素分离到不同的UIPanel中(UI的重建以UIPanel为单位),从而尽可能将因为变动的UI元素引起的重构控制在较小的范围内
③带通道和不带通道图集,尽量分开
④同一个UI界面或者同一个功能点的ui资源放在一个图集,可以减少drawcall
等等(方法还有很多)
参考:
https://www.cnblogs.com/wetest/p/6147011.html
5.GC优化
GC的时候会占用大量计算资源,如果GC之后发现内存依然不够用,需要再次分配(unity非官方数据一次大概6MB),那么就更耗资源了。GC优化一般有:
①对象池技术---重复使用对象(比如子弹,需要频繁的生成和销毁)
②减少内存垃圾的数量(比如:不要在频繁调用的函数中反复进行堆内存分配,后者使用缓存技术)
③减缓GC的时间,不要在关键时候GC操作;在非敏感期主动gc
④其他技术手段,比如装箱,list,字符串等导致GC的解决方案
等等(方法还有很多)
参考:
https://www.cnblogs.com/u3ddjw/p/8624438.html
6.内存优化
内存性能原因主要有这几点:内存碎片过多(内存池解决)、内存频繁创建销毁(对象池解决)、内存加载慢、内存占用过高。
①资源(贴图,模型,动画,声音等)有损压缩,每种资源都有最优的压缩方式和格式等。
②脚本和配置,及时卸载,以及拆分等
③第三方shader库,冗余预编译宏占用
④AB包打包策略和加载策略,都会影响内存占用。AB自动打包工具(公共包合并,AB包要在10MB内),游戏类型逻辑强关联打包模式,比如moba,把一个英雄的所有资源打到一个包里。
比如:
第三方库内存占用,延时加载和模块隔离方法(第三方库内存泄漏,或者占用过大,方便处理)
比如技能表,常驻优化方案
去掉内存中同时存在的相同资源(比如特效资源)
Unity资源内存优化,资源内存占用排行榜(优化性价比):贴图>动画>网格>音频>材质
一、贴图优化
1.降低分辨率
2.拆分透明通道
3.调整压缩格式(比如带阿尔法通道的贴图拆分2两张,分别压缩;格式转换大概是原来1/4的内存)
4.禁用Mipmap
5.启用Use Crunch Compression
1张512*512位图,安卓:RGBA ETC2(带通道)占用256KB,RGB ETC2(不带通道)占用128KB内存;在iOS:RGBA PVRTC(带通道)和RGB PVRTC都占用128KB内存
二、动画优化
1.减小动画长度
2.减少骨骼数量
3.减少关键帧密度
4.减少动画精度
三、网格优化
1.减少顶点
2.开启Optimize Mesh选项
四、音频优化
建议较长的音频使用.mp3或.ogg格式,较短的音频使用.wav 或.aiff格式
7.CPU优化
方法:
微观方法:从每一帧中发现问题(主要方法)
宏观方法:从统计中发现问题,比如一局战斗,每个模块和函数的耗时和调用次数统计,也方便不同版本的对比(工具或者日志来统计)
分类:
①GC,GCAlloc耗时
②渲染耗时(合并批处理,减少drawcall:比如使用动、静态批处理,GPU Instance技术)
③逻辑耗时(比如循环查找,比如大量服务器消息集中处理等)
④其他引擎消耗(动画,物理)
参考:
https://gameinstitute.qq.com/community/detail/120536
8.GPU优化
GPU的计算目前看,大部分还是能胜任,设置错错有余的。所有在CPU优化方案里,有一部分就是把CPU做的事情,让GPU做。
GPU优化思路:
①减少渲染批次
②同一个drawcall里,减少渲染类型
③平滑渲染
9.细节点
①模型尽量不要做成多个物体挂点组合的方式,如果多个物体用到不一样的材质,那额外产生的DC可是很酸爽的
②如果模型是带动作的话,模型的顶点数和骨骼数也是模型动作制作时的重要标准。
③图片占用内存的大小与图片大小、颜色深度、图片格式有关,与美术是否对图片资源进行压缩无关(android用ETC1,ios用pvrtc,不带alpha通道图片可以用jpg)
10.性能监控
①内部监控(上传资源时性能监控,和版本测试时,性能监控;从而及时发现问题)
②外网性能监控,比如wetest APM监控系统。
12.耗电相关
工具:比如google的Battery Historian
优化思路:
①计算优化。算法、for循环优化、Switch..case替代if..else、避开浮点运算
②避免 Wake Lock 使用不当
③使用 Job Scheduler 管理后台任务
④降低亮度等
七、总结
手游性能测试的核心竞争力,更多是设计合理的测试用例,在测试完毕后分析数据,并根据问题数据提供合理化的优化建议;从而给研发团队提供高效服务,体现价值。
原文由黑子发表于TesterHome社区,点击原文链接可与作者直接交流。