WeTest腾讯质量开发平台 UPA 深度性能报告解读

腾讯WeTest · September 10, 2018 · 1673 hits

作者:张涛,腾讯互娱测试工程师
商业转载请联系腾讯 WeTest 获得授权,非商业转载请注明出处。
原文链接:http://wetest.qq.com/lab/view/403.html

WeTest 导读

UPA 作为腾讯 WeTest 与 Unity 官方联合打造的客户端性能分析工具,为开发者提供了极大的便利和效能提升。产出的分析报告内容详尽,但您是否真的读懂了报告?是否了解每项数据的含义?此次就让我们的大咖来为您详细解读 UPA 的性能报告,让您瞬间秒懂。


测试概况

一般做完数据收集后,查看 upa 深度性能报告,最先看到的就是测试概况页面。

上面的数据大致可以分成这几个方面来看:

1)平均帧率既和 CPU 耗时有关(点击下方的通过/未通过按钮可跳转到 CPU 模块),也和 GPU 耗时有关。

2)ReservedMono 内存可以理解为游戏中脚本分配的内存,进一步定位可以借助 upa 的 mono 内存测试(详见附录)。

3)纹理、网格、动画、音频等可以理解为资源内存,进一步定位可以借助 upa 的资源内存测试(详见附录)。

4)drawcall 和 Tris 和 GPU 耗时有关,进一步定位可以借助针对 GPU 分析的工具(详见附录)。

5)pss 内存一般用于定位多局战斗、场景跳转、打开关闭 UI 中是否有内存泄漏,可以借助 wetest 助手中的通用性能测试获取。

通过概况页面可以大致看出游戏存在的性能问题,upa 也给出了问题和优化建议:

CPU

cpu 模块提供了 CPU 耗时相关的详细数据。

cpu 性能占用这一页签的概述给出了各模块的整体耗时:

frameTime:当前帧总耗时;

RenderingTime:当前帧渲染耗时;drawcall 越高,这部分开销越大。可以通过减少所渲染物体的材质种类(内存页签下的材质资源),降低 drawcall。

ScriptTime:当前帧函数耗时。

PhysicsTime:当前帧物理耗时。

从上图中可以看出函数和渲染耗时比较多,可以看下概况页面下的耗时排名 top10 的模块:

针对耗时较高的帧,可以查看详细的模块耗时情况:


比如上图选取的第 1401 帧耗时较大(场景加载),可以展开模块耗时,查看具体模块具体函数的耗时、时间占比以及每一帧的 GC Alloc。

Loading.UpdatePreloading,主要负责卸载当前场景的资源,并且加载下一场景中的相关资源等。下一场景中,自身所拥有的 GameObject 和资源越多,其加载开销越大。

内存

内存模块反映了游戏各方面的内存占用情况。

上图中的 total_reserved 是 unity 引擎在内存方面的总体分配量,total_used 是 unity 引擎在内存方面的总体使用量,unused_total 是空闲的内存。这里的引擎分配内存和空闲内存都比较多。

total_reserved 内存=unity_reserved 内存 +GFX 内存 +FMOD 内存 +Mono 内存 +Profiler 内存

下面分别展开说明:

unity reserved:这部分主要包括资源内存。可以针对纹理、网格、动画、材质、音频资源优化。比如 FBX 模型导入时,"Read/Write Enable"是默认开启的,mesh 数据会保留一份在 unity reserved 中,关闭可以减少该模型在 unity reserved 中占用内存一半的大小。

mono reserved:分配的 mono 内存(绿线部分),只升不降,需要严格控制。mono 内存表示游戏中脚本分配的内存,虽然 mono 本身提供了垃圾回收机制,但还是可能出现内存泄漏。如果需要进一步定位,需要借助 upa 的 mono 内存测试(详见附录)。

gfxdriver_reserved 表示渲染模块的内存,如果比较高需要对纹理资源和 Shader 进行优化。

fmod_reserved 表示音频模块的内存,如果比较高需要对音频资源进行优化。

profiler_reserved 表示 unity profiler 分配的内存,无需关注。

图形

图形模块和 GPU 耗时相关。

图像概况页签的几个指标:

1)SetPassCalls

渲染 Pass 的数目,每个 Pass 都会消耗对应的一个 drawcall,在满足渲染效果的情况下尽可能的减少 Pass 的数量。

Shader “ShaderLab Tutorials/TestShader"{

SubShader{

Pass

{

//...

}

}}

2)drawcalls:

cpu 发送给 gpu 的渲染请求数,请求中包括渲染对象所有的顶点、三角面、索引值、图元个数等。

3)verts:

摄像机视野内渲染的顶点总数。

4)tris:

摄像机视野内渲染的三角面总数。

5)VRAM usage:

显存的使用情况,它的总大小取决于显卡的显存。

6)VBO Total:

渲染过程中上传到图形卡的网格的数量。

这是合批页签中的概述,表示在标识区域中开启动态合批后平均节省下 3.24 个 drawcall。

这是模块耗时页签中的概述,Camera.Render 表示相机渲染准备工作的 cpu 耗时;Shader.Parse 表示资源加入后 untiy 引擎对 shader 的解析耗时。Shader.CreateGPUProgram 表示 GPU 对加载进来的新 shader 针对目标平台编译的耗时。


附录

1、mono 内存测试

条件:手机已 root,且系统非 android 7.0 及以上。

测试方式:在合适的时间点打 2 次以上的内存快照,进行对比(获取保留和新增的资源类型、对象堆栈、引用次数)。比如主城反复跳转的场景发现 mono 内存一直在增长,就可以在场景跳转前打一个 snapshot1,在场景跳转后打一个 snapshot2,最后在场景跳转回原主城再打一个 snapshot3。

2、资源内存测试

条件:手机已 root,且系统非 android 7.0 以机上。

资源结论:

资源重复是指内存中同一时刻,存在两份或以上相同的纹理、网格、动画、音频等资源。一般是相同的一份资源被打包到多个 AB 包中,如果这些 AB 都被加载进内存,内存中就会存在多份相同的资源。这个比率是按重复资源的大小除以总资源的大小来算的。

如果资源重复率超标,一般是优先处理资源较大、重复数量较多的纹理或网格。

纹理资源超标,一般优化的方向:

1)纹理用于 UI,禁用 mipmaps;

2)尽可能降低纹理分辨率,不要超过 2048*2048;

3)android 尽量使用 ETC 格式,ios 使用 PVRTC 格式;

4)低配机目前一般不支持 openGL3.0,故使用 ETC2 时会自动转换成 RGBA32,纹理占用大概是中高配机的 4 倍。解决方法是统一改成所有机型都支持的 ETC1,一张 RGB,一张 alpha,渲染时再合并。

网格资源超标,一般优化的方向:

1)减少顶点和三角面数。Simple LOD 插件可以用来简化网格资源;

2)如果网格资源数据不进行读写操作,需要将 Read/Write Enable 关闭。

动画资源超标,一般优化的方向:

1)在不影响表现的前提下,减少 Animation 的帧数;

2)开启"Optimize GameObject";

3)按需加载,比如在战斗中会有角色站立、死亡、攻击等动画剪辑,这些不用在战斗的每一帧全部加载。

音频资源一般很少超标。

3、Adreno Profiler

比较常用的针对 GPU 分析的工具有 Mali、PowerVR、Adreno Profiler 等,比较方便使用的还是高通的显卡分析工具 Adreno Profiler。(P.S. 目前 adreno profiler 不更新了,如果抓取不了游戏单帧,推荐使用 intel GPA+ 模拟器的组合)

使用条件:查看手机是否高通芯片,PC 上装有 adb 环境。

首先手机上打开游戏,运行到需要抓取的界面,然后在 PC 端打开 Adreno Profiler,点左上角的 Connect。

双击连接之后,点击 Scrubber GL 弹出抓取界面,然后点击 Caputure Frame 等待即可。


Frame states 下查看渲染相关参数:

比如 Miscellaneous 选项下 Total Texture Usages 为纹理显存使用总量:

比如 Texture Formats 选项下为纹理格式分布:


比如 Render Calls 可视为 draw call 统计:

左边是抓取到的当前帧的所有绘制指令,鼠标在 listview 中从上到下点击,可以还原当前帧的绘制过程。

这个是纹理浏览器,是捕获帧加载进来的纹理资源。从上面的截图可以看出来这个图集(将许多单个的纹理合并到一个较大的纹理上)填充的不饱和,可以拆分成 1024*512 的图集。

也可以发现有一模一样的纹理且重复多个:


这个是 shader 浏览器,可以针对一些消耗性能比较大的 shader 做优化。

vertex shader:顶点着色器,逐顶点计算,计算次数等于顶点数。

fragment shader:像素着色器,逐像素计算,计算次数等于像素数。

一般对于 shader 优化的建议:

1)在不影响效果输出的情况下减少变量的精度;避免数据类型的转换。

2)减少或避免使用幂函数、指数函数、三角函数等复杂的函数运算,使用近似方程替代。

怎样查看 shader 优化后,性能是否提升了呢?

这里要使用 Grapher->App Metris Graph 里的一些监测指标进行优化前后的对比:

EGL(FPS)

GPU General(%Busy)

GPU Shader Processing(%Shaders Busy,%Time Shading Fragment/Vertices)

另外还有一些可以进行覆盖测试,比如 fps 均值比较低,那到底是 CPU 还是 GPU 造成的瓶颈呢?将 DisableDrawElements 替换为 false,看 FPS 和 GPU General(%Busy),如果有较大变化则是 GPU 造成的瓶颈。

最后对 GPU 瓶颈识别做个总结:


欢迎使用 WeTest UPA,无需 ROOT 或接入 SDK,认证用户即享 60 分钟使用时长,点击:http://wetest.qq.com/product/cube 即可下载。

如果使用当中有任何疑问,欢迎联系腾讯 WeTest 企业 QQ:2852350015

No Reply at the moment.
需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up