CPU性能
该游戏在CPU占用方面的性能非常优异。我们在红米2和华为6Plus两款中低端设备上按照剧情进行测试,下图则为对应的运行性能数据。
红米2:
华为6Plus:
可以看出,在红米2上运行的18143帧中,超过33ms的帧数占比为11.1%,超过50ms的帧数占比为1.3%。在华为6Plus上运行的16026帧中,超过33ms的帧数占比为8.7%,超过50ms的帧数占比为3.3%。目前,在我们测评过的重度ARPG游戏中,能在红米2上达到这样如此高效的运行效率,只此一款!
其整体CPU性能的优秀表现与其各个模块的合理使用是分不开的。下面,我们就详细讲解一下其CPU性能方面的亮点之处。
1)渲染模块
通过UWA性能测评报告,我们可以看到该游戏详尽的渲染模块性能开销。该游戏在红米2上运行时的渲染模块CPU开销如下图所示。通过统计,半透明物体渲染的CPU消耗均值为 1.3 ms,主要集中在 0.0~3.7ms 范围内(5%~95%)。不透明物体渲染的CPU消耗均值为 4.2 ms,主要集中在 0.0~13.9ms范围内(5%~95%)。Draw Call峰值为 142,且主要集中在 4~115 范围内(5%~95%),均属于合理范围之内。
该游戏在华为6Plus上运行时的渲染模块CPU开销如下图所示。可以看出,虽然是中低端机,但较之红米2,其渲染模块的性能开销已经大幅下降。通过统计,半透明物体渲染的CPU消耗均值为 1.0 ms,主要集中在 0.0~1.9ms 范围内(5%~95%)。不透明物体渲染的CPU消耗均值为 2.7 ms,主要集中在 0.0~5.9ms范围内(5%~95%)。Draw Call峰值为 154,且主要集中在 5~120 范围内(5%~95%),均属于合理范围之内。
下图为该游戏在红米2上的具体CPU性能堆栈。可以看到,该游戏在红米2上开启了实时阴影功能,且仅ShadowMap的渲染一项则占据了总渲染开销的7%,考虑到渲染ShadowMap时接收阴影物体的重绘,实时阴影带来的真实开销可能占据10%左右。这也是该游戏在红米2这种低端机上不透明渲染开销较大的主要原因之一。
同时,从性能堆栈中可以看到,该游戏同样开启了图像后处理特效功能,占据总体渲染性能的13%。这是因为图像后处理特效在战斗副本中全程开启。下图为Graphics.Blit在游戏运行时的CPU占用情况。
在低端设备上开启了实时阴影功能和图像后处理,并达到了如此高的渲染效率,这足以说明了研发团队对于移动设备渲染底层的深刻理解和深厚的功底!
2)动画模块
在UWA测评报告中,该游戏运行时的动画模块CPU开销如下图所示。通过统计,MeshSkinning.Update的CPU占用主要集中在 0.0~1.5ms 区间,该值处于合理范围之内。
另外,游戏中的动画系统主要以Mecanim为主,Animator.Update的CPU占用主要集中在 0.0~4.5ms 区间,其运行时的CPU占用如下图所示。
我们来继续查看一下它的性能堆栈,可以看到,Animator.Update函数的主要CPU占用为两个函数所占据:
1)MOnAnimatorMoveDelegate.OnAnimatorMove,占据该函数总开销的41%;
2)FK & Statemachine,占据该函数总开销的30%。
对于前者,这个是开发团队重写的OnAnimatorMove函数,如果您的项目中也可以看到相似的开销,则需要您去仔细检测一下项目中重写的OnAnimatorMove函数,看看是否有不必要的CPU占用可以优化。对于后者,则是Mecanim动画系统的自身状态机控制开销。一般来说,Animator Controller中的状态机越复杂,该项越高。如果研发团队同样也是该项值较高,我们建议直接查看Animator Controller的制作,并尝试对其进行简化。
注意:我们不推荐将大量甚至所有角色用到的AnimationClip全部放入到Animator Controller中,因为这会带来两个问题:
- Animator Controller中到处都是状态机的连接线,复杂且不易于维护;
- Animator Controller初始化时的开销较高。
因此,我们建议研发团队善用AnimatorOverrideController,在Runtime时动态替换所需的AnimationClip,从而尽可能避免上述问题的出现。
3)粒子系统
在UWA测评报告中,该游戏运行时的粒子系统CPU开销如下图所示。可以看出,ParticleSystem.Update的CPU占用主要集中在3ms 以下,该值处于合理范围之内。同时,粒子系统的渲染在CPU端的开销主要集中在 0.0~1.2ms 范围内(5%~95%)。由于该游戏使用的是Unity 4.x版本,所以此处的CPU占用仍然在主线程中体现。如果您的项目使用的是Unity 5.3以后版本,那么此处的CPU占用将会为0。这是因为Unity引擎已经将粒子系统的这部分操作移植到子线程中进行。
4)UI模块
通过测试,我们发现该游戏的UI系统中,既使用了UGUI,也使用了NGUI。具体的分配是,在主UI界面中使用的是NGUI,在战斗场景中使用UGUI。其具体的CPU占用如下图所示。通过进一步分析,经过统计,NGUI模块总体在红米2上的CPU占用主要集中在0.1~3.0ms范围内(5%~95%),堆内存累积分配6.6MB;UGUI模块总体在红米2上的CPU占用主要集中在0.4~4.2ms范围内(5%~95%),堆内存累积分配4.98MB。
NGUI:
UGUI:
从上图中可以看出,虽然UI模块的持续CPU占用不高,但存在离散的CPU占用高值。通过进一步分析,这些均为UI界面的Active和Deactive操作所致。下图为主UI界面和战斗副本中UI元素的具体Active情况。
NGUI:
UGUI:
我们建议研发团队可以根据不同的UI界面使用频率,来尝试以下方案:
- 如果该UI界面开启的频率很低,那么可直接通过Instantiate/Destroy来进行切换;
- 如果该UI界面使用的频率较为频繁,那么可尝试通过Active/Deactive来代替Instantiate/Destroy操作,从而降低UI切换时的性能开销;
- 如果该UI界面使用非常频繁,则可尝试直接改变UI界面位置的方式来移进/移出相机视域体,从而来极大提升UI界面的切换效率。
因此,如果您项目中的UI开销出现了很高的离散CPU占用,那么建议您通过报告中的“资源管理”页面详细定位Instantiate/Destroy或者Active/Deactive的UI元素,并根据上述方案进行针对性的完善。
5) Instantiate实例化
目前,游戏的战斗副本中Instantiate实例化的频率很低,这说明研发团队对于GameObject的缓存操作非常注意,且进行了大量的试验和完善。下图则是游戏运行过程中,战斗副本中发现的Object实例化调用情况。该图表您可以在UWA测评报告中的“资源实例化/激活”页面中进行查看。
如果您的项目中存在较为频繁的Instantiate调用,我们的建议如下:
- 对于一般的GameObject(比如技能特效、怪物角色等),可将其放入缓存池并通过Active/Deactive来进行切换;
- 对于使用频率较高的UI界面,则可通过直接改变Transform的方式来移进移出相机视域体,可以得到更加高效的性能。
内存模块
《聚爆Implosion》在内存上的表现如下图所示。总内存峰值达到191MB,Mono堆内存峰值为13.7MB,且内存在游戏运行过程中表现较为平稳。
1) Mono堆内存
从上图可知,该游戏的总体Mono堆内存控制得非常好,在16000+帧中,Mono的堆内存峰值仅为 13.7MB,该值属于合理范围之内(<40MB)。
如此少量的Mono堆内存分配,主要得益于项目中函数堆内存分配控制得当,下图为当前游戏运行16000+帧的函数堆内存分配情况。因此,建议大家对函数代码堆内存的分配进行严格控制,对于堆内存分配较高(10000帧10MB+)的函数进行详细定位其分配原因。在UWA测评报告中,我们提供了堆内存分配Top10的具体堆栈,以方便大家尽快地定位堆内存分配出处。
2) 资源内存
经过统计,该游戏的纹理资源数量峰值为364个,内存占用峰值80.8MB。在全部纹理资源中,ETC1格式纹理占有145个,Alpha8格式纹理占有6个,RGBA32和ARGB32格式纹理共占有59个,RGB24格式纹理占有16个,其余为RGBA16格式纹理。
对于RGBA32、ARGB32和RGB24格式的纹理,我们建议在视觉效果可以保证的情况下,尽可能使用ETC1格式纹理(Android平台)进行替换,不仅可以达到更小的内存占用,同时可以获得更快的加载效率。对于纹理资源的加载效率,我们在之前的加载模块深度解析之纹理篇中进行了详细的分析和阐述,建议大家进一步查看,以加深加载模块的掌控能力。
3) 其他资源的内存占用情况如下:
Mesh资源:
AnimationClip资源:
AudioClip资源:
以上则为《聚爆Implosion》游戏在CPU性能和内存管理方面的具体使用情况。优秀的CPU性能、超低的堆内存分配以及引擎模块间的合理使用,足以看出该研发团队非常深厚的技术功底和对于引擎相当优秀的把控能力。
原文出处:侑虎科技
本文作者:admin
转载请与作者联系,同时请务必标明文章原始出处和原文链接及本声明。