2018年5月11日至 13 日,腾讯 WeTest 与 Unity 联合打造的移动游戏性能分析工具(Unity Performance Analysis,以下称为 UPA)正式亮相 2018 Unite 大会,为 Unity 手游开发者提供更加深度的游戏性能优化、测试服务,带来了更多产品测试与优化的 “新姿势”。

会上,Unity 大中华区企业支持经理&UPA 开发工程师高川先生、腾讯游戏性能优化工程师 & UPA 开发工程师徐森先生代表 UPA 团队,为开发者们带来了题为 “使用 UPA 工具优化项目” 的分享演讲。


Unite 大会技术专场演讲现场

以下为演讲实录

徐森

大家下午好,今天和大家分享一下使用 UPA 工具优化项目的经验。

大家在看到这个题目的时候可能第一时间想到的就是说 UPA 是什么东西?所以由我先为大家分享一下工具的起源或者说我们为什么做这样一款工具?我这边是负责游戏性能的优化工作,所以在腾讯碰到很多游戏优化的案例。时间是游戏的生命线,大家知道手游的生命周期比较短,一款成功的手游大概 2 到 3 年已经很可以了,所以说在这么短的时间内我们需要把一个游戏的功能性能做到最好,其实这是非常耗时间的操作,所以大家可能平时加班比较多一点,这也是没有办法的事情。

腾讯游戏性能优化工程师 & UPA 开发工程师 徐森先生

这么一个大前提下我们说性能优化这个工作既重要也不是很重要,首先它很重要,这是大家玩游戏的过程中都有体会,如果游戏性能优化不好会出现很多问题,比如玩起来卡,闪退或者掉线,这个会导致用户流失掉。这是做性能优化很重要的方面。为什么说它不重要?因为一个游戏的项目组里面最多的同学可能做功能开发或者做美术,或者做发行做运营。其实一个项目组里面专门针对性能优化的人员非常少,一个游戏可能一到两个人左右。这么有限的时间把所有的性能优化好,显然不可能。我们这边进行游戏优化的过程中,最重要的需求就是高效,我们一定在最短的时间内利用最少的人力,帮助我们发现并且解决掉我们游戏可能产生的一些性能问题。

那么说到这里有这样一个想法,我们可以做这个工具帮助我们高效的解决性能问题,所以这是我们 UPA 这个工具产生的前提条件。所以这个标题是效率,我们工具其实主要是帮助我们提升性能优化的效率工具。那么有了目标以后我们考虑怎么根据目标进行产品的开发,首先第一点为什么强调是 Unity 和腾讯合作开发的产品,因为我们觉得做这个工具它的前置条件很多,首先对底层的工具了解,后面对游戏测试或者游戏开发中的流程或者规范非常的清楚,可以帮助我们使用人员更快的上手工具,同时这个工具更有针对性。

所以说 Unity 扮演一个专家角色,对于我们底层的代码负责了解。那么腾讯这边扮演一个偏向于使用者的角色,我怎么设计这个工具,才能最大程度的提高使用人员的效率。所以这是两个前提条件,导致我们两边进行合作产品。这个产品最主要的就是,这边写的可能比较绕口,基于四无产品概念的非侵入式测试。什么意思?解释一下四无,首先第一个我们被测的游戏不需要接入 SDK,第二测试机不需要其他的权限,第三测试时候不需要上传被测的应用,第四测试的时候不需要 Unity 的开发环境。

其实有了四无的概念以后,这个工具在任何场合,只要大家有一款手机,有我需要测试的应用就可以拿到这个工具进行测试了。其实非侵入式我觉得可能是对我们之前的四无的补充,因为我们知道现在很多市面上流行的一些测试产品,在 PC 端还好一点,那么在手机端可能需要一些很苛刻的 Root 权限,很苛刻的限制,所以我们强调非侵入式,相当于它的优点。

讲完了主要的以后下面还有一个,其实是全自助式的测试模式,这是针对使用的用户来讲,这样一款工具我们是完全开放给用户自主使用。我可以在任何时间任何地点,当然在家也可以测,任何时间任何的测试的手机上,可以测试我任何想要的场景,其实这么一款游戏测试工具跟玩游戏的场景其实差不多。

那么说了这些大家可能关注到这个工具会有什么样的特点?其实很多工具功能我们都是为了弥补我们当前测试工具的不足来针对性的开发。大家可能平时会使用很多性能优化工具,相信大家使用过程中也会感觉有这样或者那样的不太好用的地方。

我们可以列举一下目前市面上比较流行的一些性能优化工具。最常接触的可能就是 Unity Profiler,它是嵌在界面中大家用起来最方便,开发的时候就顺手拿过来,这个是 Unity 官方推出的,所以有很多好用的地方,比如采集的数据分类非常明确,到底是 CPU 或者 GPU 数据或者内存数据或者物理数据,我可以看到问题出哪儿。还有其他的优势,比如说里面的数据是用曲线展示的,可能可读性会好一点,并且数据是从引擎官方内部采集的,所以数据可靠性比较高,不会出现误报的情况,这个就是 Profiler 本身的优点。

有优点就有缺点,其实平常我们在和用户沟通过程中,经常听到用户的吐槽。比如说 Profiler 界面显示的数据有限,同一时间有 500 帧,现在不太清楚,可能会有一些提高。这可能是不太好用的一点,还有另外一点 Profiler 的数据虽然分类比较明确,但是读起来有些难读,比如说会有一些函数的名字还有模块的名字,单看名字可能不理解这个东西是什么东西,可能还要上论坛上面求助或者 Unity 的专家去求助,才能大概知道这是什么意思。

还有一个问题其实 Unity 统计数据是从软件层面来统计的,那么深入不到硬件层,最明显的例子就是不支持的 GPU 的型号读不到里面的硬件数据,CPU 也是读不到,这些数据对优化问题还是很重要的。刚才说到 Unity 提供的 Profiler 工具,其实很多硬件上面我们的硬件厂商也有提供一些 Profiler 工具,比如 IOS 和安卓上面都有工具。这些硬件厂商提供的工具会有什么优点?他们这些数据的统计和他们的硬件强相关,可以深入到硬件层。那么这样子的话,统计的数据非常的全面,从软件到硬件层都有,并且他们的可靠性非常高。

但是硬件层的数据有一个明显的缺点,就是它的可读性不是很强,我经常可能看到一些内存地址的数据对不上我自己写的代码,这样导致工具使用门槛很高,非常有经验的人才可能从工具中发现一些问题。

说完了硬件,随着 Unity 在国内使用的幅度越来越大,其实很多第三方的 Profiler 工具也会提供出来。比如商店里面可能有一些性能优化的插件,第三方工具的好处在什么地方?首先第三方工具相当于是针对我们的游戏开发者进行开发的,所以使用方面还有数据可读性方面,比一般的工具强一些的。但是也不是没有问题,因为很多第三方的工具开发商,之前可能也是 Unity 引擎的使用者,他可能对引擎底层的技术不是很了解。那么功能的一些更新可能很滞后,并不一定兼容最新 Unity 的版本,还有数据解读有一些误解,可能误导我们对这个数据的理解。

这个是我们在平常现有一些 Profiler 工具会产生的一些缺点,当然严格来说我们 UPA 是一个第三方的工具,但是我们和 Unity 合作所以可以避免一些第三方工具出现的一些典型的问题。这个合作还有一个比较重要的一点,其实我们是除了工具的可用性以外,其实我们想做一些数据分析以及整理,也就是说我们把 Unity 和腾讯在性能优化过程中积累的经验还有数据标准共享给大家,帮助大家比较快速的发现我们这个游戏到底哪个方面存在性能问题,并且可以方便的优化它,这是这个产品,相当于一些特点或者它想针对的目标。

有了这个产品之后大家可能就会想到这个产品应该怎么用?在平时的开发或者测试过程中应该怎么用这个产品才能更大化的发挥它的效果。其实这个产品我们在平时的推广过程中也积累了一些使用场景,可以跟大家分享一下。首先第一个是数据采集者和数据分析者,其实对于这个产品来说我们数据采集的人员和数据分析的人员可以不是同一个人,我们知道之前的 Profiler 工具可能都是,我那些做性能优化的同学自己用,自己采集数据看这个数据然后优化这个问题。

那么有了这个 UPA 的工具以后,其实这个角色可以分两个部分。首先第一部分是我们的数据采集人员,这个可以交给我们的外包或者测试同学来做,剩下的开发人员做功能就好,等到他们跑完了我们指定的场景或者指定的机型数据以后,可以把我们采集的数据或者生成的报告拿到专门负责性能优化的同学那边,其实省了我们平常可能是一些问题或者是采集数据的时间。这是第一点。

第二点因为我们报告采集以后是存在云端的,所以这个报告可以进行任意应该的分享。比如我们可以分享给我认识的一个比较厉害的大牛,我可以请他给我看一下这个报告有没有问题?如果这个问题我解决不了的话。可以分享我们 Unity 的专家,请他们看一下这个报告减少我分析报告的成本。当然分享给专家以后如果我们有采购 Unity 的驻场支持,他们在驻场的时候可以看一下报告减少他们的驻场时间。

还有应用比较多的场景,我之前已经发现类似的问题并且已经进行优化,这个时候看一下优化效果怎样,这个问题有没有被真正的解决,这个时候可以跟我之前没有进行优化的报告进行对比。那么两边的数据对比以后我可以很明显的发现,这个数据是不是恢复正常?这个代表我之前做的优化效果是不是有效。

最后一个也是我们最近在推广过程中碰到的一些项目的使用,项目组使用这个工具做自动化测试的工作,为什么做这个?因为自动化测试应用面比较小,因为如果是做功能的自动化,那么这些自动化过程中出现的问题可能我并不一定能够自动化的发现。如果自动化跑一个游戏中间突然花屏,有一些角色的渲染不太正常,或者有些文本显示不对,这个时候很难通过自动化的方式来发现,我跑自动化的时候可能还需要人来盯着这个东西。看一下这个跑的过程中有没有问题。

那么这样的话自动化测试的效率其实很低,当然我们刚才说是功能自动化,如果做性能自动化的测试的话,之前大家可能采集一些帧率或者内存这种指标。那么虽然有了这些指标,自动化测试可以帮助我发现一些问题,但是自动化工作能够做的工作到此为止,接下去我们又回到之前的数据优化的这么一个老套路。有了这种性能采集的工具以后,如果结合自动化的测试我们可以在每次自动化的时候,采集一些性能数据。然后通过测试结果的对比我们可以发现一些潜在的性能问题。

比如说一个函数它的时间可能每个版本都会增加 10% 或者 5%,虽然可能一两个版本看不出来问题,但是等真正上线的时候这个问题已经成为一个问题,到时候我们再花时间进行优化,那么效率就会比较低,所以我们自动化测试的时候,提前帮助我们发现一些问题。

这是我们使用 UPA 的场景,说到这里大家已经对这个工具有一点好奇了,这个工具到底什么样的?能达到什么效果?或者能够帮助我们解决什么问题?下面我们请 Unity 的支持工程师高川同学帮助我们详细的演示一下这个工具的使用方法还有典型的使用案例。

高川

大家好!我是来自 Unity 的高川,下面演示一下日常如何使用 UPA 以及我们用 UPA 发现具体项目的具体问题。

在正式开始讲之前打一个广告,我们现在 Unity 在招现场支持工程师,如果你想更多的接触一些客户解决一些非常尖端的难题,欢迎加入我们,这是我们的地址以及二维码。

接下来我们讲一下怎么使用 UPA。UPA 分成两个部分,我先问一下在座的各位有谁之前使用过 UPA?UPA 由两个部分组成的测试系统,一部分是我们手机上的客户端,装在手机上的,还有一部分是我们的网站,首先各位在手机的客户端去下一个我们 WeTest 的助手这样一个软件,通过这个软件我们可以启动测试,下载之后登录之后会看到这样的界面。

Unity 大中华区企业支持经理&UPA 开发工程师 高川先生

我们可以看到有几项,一般来讲就是第一项,我们选择 UPA,进入之后进这样一个界面,这个界面里面我们可以看到有这样几个选项,第一我们要求用户选择一下你们测试哪个 Application,然后下面有三个选择,第一个是性能分析,后面是资源分析和 MONO 内存分析,报告所属你可以对报告进行分组,Unity 版本,我们会有 5.6 以上和 5.6 以下版本,截图这个让用户理解你测试过程中究竟发生了什么。为什么做成开关?因为我们知道有些公司对于项目的截图比较敏感,所以这个截图是关闭的,如果有需要一定打开,这个对于你自己或者你的朋友或者其他的专家来阅读和解析整个报告是非常重要的。

你选择所有的东西之后点开始测试,你的 Application 拉起来,你可以玩游戏一样开始你的测试,测试时长没有限制,我们一会儿可以看一下我们的案例测试。这是我们的 Demo 报告,这是用 Unity 的 AngryBots 做的测试,上面有一个报告是合格还是不合格还是警告,同时收集一些 Application 信息,你的 CPU 性能情况,使用什么手机测试,基于腾讯后台大数据我们对手机进行分类,属于高配中配低配。然后下面是一堆列表,大家比较关注帧率、MONO 的内存、纹理、网格,包括 Tris 在这里有一目了然的展示,我们也会用颜色来区分。这些报告,由于大部分人对自己的游戏很了解,看这儿可能结束了,因为所有的问题列这儿,你可能不需要放其他的数据或者再分析,可能有时候这个地方发现一些非常直接的问题,然后开始着手解决。

再下面是我们建议的这样一个关注点,包括一些模块的耗时这样一个排列,这是概况页,然后下面我们对 CPU 内存图形渲染三个方面进行分析。大家比较关心 CPU 使用情况,如果看截图非常清晰的知道这一帧在干什么。所以会有比较清晰的对比。最上面是我们的性能的摘要报告,包括你的耗时的平均,以及物理的耗时平均。再下面我们看到这是一个主的 TimeLine,这个上面是采集每一帧的数据的采样点,我们可以针对某一帧进行放大,这一帧里面可以看到整个耗时,Rendering 耗时非常凸显,我们可以一帧一帧的展开,看一下每个函数的耗时是什么。

再下面是我们的建议,虽然这里比较凸显,但是整体没有太大,我们 Unity 的 Demo 优化很棒,这真的没有太大问题,我们一会儿可以看到相对优化不那么好的项目。再下面是对于对象激活统计,大家知道 Unity 里面这两个操作是非常耗时的操作,每次都有树的传递,你的脚本有操作,这个传递非常慢,尤其是 UI。比如人物头顶的 billboard,我们在有的项目里面就会看到这个耗时是非常凸显的状况。我们和项目的优化过程中我们经常看到,有一些非常集中的实例化会导致卡顿,一会儿我们的案例也有相关的内容。下面我们会看到有一个内存方面的报告。

这是内存的报告,首先我们可以看到 Mono,在这里有非常频繁的产生,一会儿案例中会看到非常明显的内存使用的问题。然后是动画、音频、材质、网络的细分展示,在图形里面我们关注关注 Draw Calls,再下面是 Verts 和 Triangles,它加载某一些模型的时候加载策略不合适,所以把无用的模型统统加载进来。再下面是 VRAM 的值,这个值是一个估算值,所以给大家做一个参考,再下面是 VBO 的统计,以及这一帧里面更加详细的数据使用。

还有一个模块是我们的合批模块,我经常被问一个问题,要不要开通静态合批和动态合批,我们知道它对 CPU 产生一定的压力,或者对内存产生一定的压力,所以我们给的答案是能或者不能,大部分的答案是试试吧,所以我们通过合批想帮助大家解决这个问题。其实这里最重要的是黄色曲线,你通过开启动态合批为你省掉多少,如果这个曲线非常高,说明你的动态合批做的非常好,你可以付出相对比较小的代价获得比较大的收益,但是反之你不应该开它或者进行材质和渲染顺序之间的调整。这个稍后我们也会在案例里面看到一个非常明显的例子。还有我们认为渲染方面非常耗时的,这是大家平时做项目的时候遇到耗时非常尖峰的地方,所以我们提出来让开发者重点关注一下。

下面看一个案例,这个案例是腾讯的真龙霸业,这是早期的版本,我们看上完了是红通通不通过,真龙霸业的同学比较担心,它是在米 4 测的,它的平均帧率只有 10 帧,纹理资源是 80 多兆,峰值已经达到 500。我们看一下问题建议,首先 FPS 均值很低,逻辑脚本高于渲染,这是我们看项目的时候,90% 的项目都有这个问题,GC 频率 9.42 次,然后是 Canvas,还有就是纹理消耗比较高。我们看一下模块耗时,这个函数比较有意思,一会儿可以重点看一下这个东西应该干什么,它不仅会产生比较高的耗时,同时会产生比较高的 GC alloc。

我们看一下 GPU,我们看很多项目大多数的曲线是锯齿,在下面不停的抖,这个曲线是游戏平均帧率比较低,而且出现偶尔的卡顿,就是不流畅。但是这种曲线玩家的体验会停顿,所有的红色的曲线玩家感觉非常明显的停顿而不是卡顿。因为用 UPA 测试的时候版本比较早,所以没有做截图功能,所以打了一个 Tag,我们看一下典型意义,比如红通通的,有 4 帧,第 94 帧是耗时非常高的一帧,这一帧是在干什么?耗时最高是这个函数,这是你的 UI 在加载一个滚动列表,你加载一个过大的滚动列表,所以这一帧之内大家可以看到它已经是非常夸张的值。而且这一帧里面仅仅一个函数就 400,所以这就是明显的停顿而不是卡顿。

我们再看这个,从名字可以猜出来是第一个场景已经加载,这里有很多加载过程和初始化过程,所以导致这一帧的加载大概 400 多,这个意味着什么?如果这是一个等待的场景还好,如果这是游戏中的动态加载,玩家会卡将近一秒钟的时间,因为这两个函数卡一秒钟,这是难以忍受的。

所以我们给项目组提的优化,第一个向滚动列表我们需要进行少量加载,可以把时间分开,同时第一次进场景的时候检查是不是某一帧做了过多的事情,导致 CPU 卡了非常非常多的时间。129 帧也是类似的问题,我们可以看到有一个 Loading,我们里面又看到了很多的等待这边,它的耗时非常高,这时间开发组开发的时候没有考虑同一帧里面 CPU 的负担,而简单粗暴同一帧里面把所有的加载任务放一帧里面。这是我们给项目组做优化的时候看到一个通病,因为大家会基于项目时间或者管理成本或者代码,在加载的时间管理和 CPU 的时间管理做的不是那么细致,所以经常有粗放的大列表加载,一开始这样做没有问题,但是随着项目增长,这个地方的瓶颈会慢慢的凸显出来。所以我们建议他们初期或者中期做规划的地方,对于提前加载的地方布局一些措施,比如进行监控进行表的自动化筛查,以及提早做分帧加载,这些都是经验上的东西。

我们看一下内存,内存非常有意思,可以看一下总内存大概占将近 500 兆,这个内存已经非常高,我们看一下 Mono Reserved,我们可以看一下,前面几帧的内存比较有意思,前面都是红线,这意味着什么?从系统层面来看,系统看到绿色的,绿色过高系统就会回收,这是时简单粗暴的说法。那么红线是你使用的,对于 Mono 的内存池来讲,你使用内存不够,它分配新的内存拓展内存池,供游戏进一步的使用。我们可以看到前面这个是一个合理的,因为绿色上涨的同时红色也在上涨,这个地方比较有意思,大家可以看到这个地方红色是下降,但是绿色反而上涨,包括后面也是非常大的上涨,这一帧的时候红色有不太大的上涨,但是绿色有非常大的上涨。

我们经常看到非常典型的,第一个就是这样,我们知道 Mono 顶上去非常难以下来,所以尽量控制尖峰不要顶高,另外是没有突破绿色反而上涨的曲线。Mono 是无压缩的内存池,它一直不停的分配,分配大的时候首先找里面有没有可以供你用的。我们可以看到项目里面 GC 非常多,意味着大量分配小碎片内存,最后导致内存碎片化严重,你分配相对大一些的内存,你的内存池已经没有地方可以分配出这样的内存,所以就申请新的内存。所以这个项目在后期浪费非常严重,大家可以关注一下大概有 10 兆左右,有 10 兆内存已经被分配,但是项目根本不会用到。所以大家优化的内存的时候,并不是只考虑我尽量减少分配,同时考虑分配内存的连续性。

所以有一些项目里面建议用户先分配大内存,再分配小内存,先分配大内存使用之后释放掉,然后用大内存的小内存进行碎片。还有一种方式我们 Unity 这边也在尝试升级 Mono 的虚拟机,下一代的虚拟机可能比较好的解决内存碎片化的问题。但是还是那句话,再优秀的机制也抵不住乱写的代码,所以开发上要有一定的节制,如果不节制什么机器也抗不住。这个项目比较有意思的就是它的纹理,80 多兆的纹理内存,为什么?因为这个东西本身不大,但是它是一个 2D 游戏,开发组当时为了加载速度问题,把所有的纹理加进来不释放。

从目前它的数据来看这种策略对于他们项目来说有一点危险,因为整体内存非常高,但是并不是把纹理加载进来不释放这个事儿不能做,只是这个项目里面我们觉得不太合适,所以我们建议他们适当的地方去释放一些内存,对于纹理进行一些更细致的加载。同样这个问题也是非常常见的问题,还是由于开发周期以及人员迭代,导致资源和内存管理上非常粗放,到了后期我们发现内存是几何级的增长,我们之前遇到很多用户后期找到我们我有很多很多奇怪的现象,到底是为什么?我们到了现场之后发现七八十是由于内存爆掉了,但是他们不会意识到这个问题,因为他们是在线上,线上抓回来的不会告诉你是内存,所以内存会导致非常挠头的问题。

所以大家进行管理内存的时候,虽然做资源管理内存管理是非常细致的活,它必须贯穿整个项目,但是这样的收益一定是非常大的,千万不要在项目前一个月发现内存抗不住了,然后找美术找 GD,据我们接触的项目这样的问题不在少数,这是给开发者一个建议,这是我们做 UPA 的初衷,帮助大家尽早发现风险,把风险消灭在萌芽状态。

还有一个是图形,大家看上面有两个 0,他们不是没开,真开了,但是开了之后这边合不掉什么东西,因为他们的材质非常非常复杂,所以我们的建议要么关掉,要不优化一下你的材质的使用。所以通过这个工具我们可以很好的回答我们之前没法回答的问题,我们要不要开?我们直接告诉开发者你的情况是这样,你自己决定优化或者不开,省掉这部分的 CPU 消耗。

由于时间关系我们案例先分享这些,如果大家有兴趣的话一会儿交流之后可以到外面的展台来跟我们工程师进一步交流。关于 WeTest 我们后面做什么东西,我请徐森继续介绍一下。


徐森

其实大家了解这个工具以后,其实可以看到这个工具目前还是处于一个比较初级的阶段,因为可能很多人心里都有一个问题,对于数据来说我们并不是说打算采集一些更深入或者更详细的数据,其实能采集的大概都已经采集光了。其实我们想做的我总结下来是一个收集和分享的功能,我们通过收集很详细的性能数据,然后集合我们平时在游戏测试过程中,游戏优化过程中的经验还有 Unity 他们驻场的经验,然后总结出来一些常见的性能问题,并且常见的优化方案,最后把这些问题和优化方案通过我们自动化报告分析的方式分享给大家,大家看到这个报告以后可能就会很快的知道我到底是哪部分出了问题,这个问题怎么改,这是我们做这个工具最想做的方面。

但是目前来看可能只是针对一些比较初级的问题,比较初级的方案,如果真的是详细的问题,可能具体项目具体分析。所以我们也不会抢了 Unity 专家的服务的市场。另外一个比较重要的问题,大家用测试工具过程中发现虽然数据拿到了,但我可能做二次分析,比如算一个平均帧时间,这是一个非常常用的功能,但是在 Profiler 里面办不到,因为它只是数据展示,没有做数据分析和数据对比,这是我们想做的,未来我们把报告数据的方式提供给大家,方便大家下载下来进行分析,这也是平时做性能优化方面工作很需要的。

还有一点就是我们可能也会考虑做一些现在这些市面上 Profiler 工具没有的功能,现在我们会提供一些快照对比的功能,大家可以尝试一下,最终希望通过 UPA 这个工具把大家平时在工作过程中积累的经验碰到的问题进行整合分析,帮助大家提高性能优化效率,这会是我们的发展方向。


今天就分享这些,谢谢大家!

若有任何疑问,欢迎在公众号留言给我们或联系 WeTest 企业 QQ:800024531 进行问询。

点击http://wetest.qq.com/cube/,WeTest UPA 邀您体验。

进入 UPA 体验页面,认证用户即享 UPA - 60 分钟使用时间。


↙↙↙阅读原文可查看相关链接,并与作者交流