今天我們?yōu)榇蠹規(guī)?lái)由福州朱雀網(wǎng)絡(luò)研發(fā)的MOBA手游《小米超神》的UWA測(cè)評(píng)報(bào)告分析。該游戲在不同配置的移動(dòng)終端設(shè)備上,無(wú)論是畫面表現(xiàn)力,還是性能開銷都非常優(yōu)異。在此,我們將對(duì)該款游戲的性能數(shù)據(jù)進(jìn)行深度剖析,希望通過(guò)這篇文章可以讓大家對(duì)移動(dòng)游戲各個(gè)模塊的運(yùn)行效率有更為深刻的認(rèn)知,并對(duì)大家的項(xiàng)目研發(fā)有所幫助。
一、CPU性能
該游戲在CPU占用方面的性能非常不錯(cuò),下圖為該游戲在紅米Note2設(shè)備上進(jìn)行一場(chǎng)5V5戰(zhàn)斗時(shí)的性能數(shù)據(jù)。
可以看出,在紅米Note2上運(yùn)行的19876幀中,超過(guò)33ms的幀數(shù)占比為13.9%,超過(guò)50ms的幀數(shù)占比為1.7%,并且從圖中可以看出,其CPU耗時(shí)較高處主要集中在5V5場(chǎng)景的資源加載階段。因此,該游戲在戰(zhàn)斗時(shí)的性能可以說(shuō)是非常優(yōu)秀,絕大多數(shù)時(shí)刻游戲運(yùn)行非常流暢。
同時(shí),通過(guò)進(jìn)一步統(tǒng)計(jì),該游戲的CPU性能超過(guò)了64%的同設(shè)備(紅米Note2)上測(cè)試的其他游戲,其能耗更是低于86%的同設(shè)備測(cè)試游戲。由于目前國(guó)內(nèi)的MOBA游戲較少,所以上述排名并不是在MOBA類型中的排名,而是在所有類型游戲中的排名。對(duì)于一款超重度的MOBA移動(dòng)游戲來(lái)說(shuō),該CPU性能和能耗排名可以說(shuō)是相當(dāng)出色。
其整體CPU性能的優(yōu)秀表現(xiàn)與其各個(gè)模塊的合理使用是分不開的。下面,我們就詳細(xì)講解其CPU性能方面的亮點(diǎn)之處。
1、渲染模塊
通過(guò)UWA性能測(cè)評(píng)報(bào)告,我們可以看到該游戲詳盡的渲染模塊性能開銷。該游戲在紅米Note2設(shè)備上運(yùn)行時(shí)的渲染模塊CPU開銷如下圖所示。通過(guò)統(tǒng)計(jì),半透明物體渲染的CPU消耗均值為1.7 ms,主要集中在0.8~3.0 ms范圍內(nèi)(5%~95%)。不透明物體渲染的CPU消耗均值為1.0 ms,主要集中在0.2~1.7 ms范圍內(nèi)(5%~95%)??梢钥闯觯谡麄€(gè)5V5戰(zhàn)斗過(guò)程中,無(wú)論是移動(dòng)、Farm、Gank還是團(tuán)戰(zhàn),甚至上高地時(shí),其渲染耗時(shí)都穩(wěn)定在一個(gè)較低的耗時(shí)區(qū)間。這得益于研發(fā)團(tuán)隊(duì)對(duì)于場(chǎng)景模型、蒙皮網(wǎng)格和UI的控制十分得當(dāng)。
Draw Call峰值為167,且主要集中在 45~130范圍內(nèi)(5%~95%),渲染三角形面片單幀峰值為64900,以上數(shù)值均處于合理范圍之內(nèi)。
2、UI模塊
該游戲在紅米Note2設(shè)備上運(yùn)行時(shí)的UI模塊CPU開銷如下圖所示。該游戲使用UGUI作為UI界面的解決方案。經(jīng)過(guò)統(tǒng)計(jì),UI模塊總體的CPU占用均值為1.5 ms,主要集中在0.1~3.5 ms(5%~95%),屬于合理范圍之內(nèi)。堆內(nèi)存累積分配為16000幀 2.4MB,平均每幀分配堆內(nèi)存155.4B,這說(shuō)明該游戲UI界面的制作及UI重建的影響范圍非常合理。目前,UWA推薦UGUI模塊中,平均每幀堆內(nèi)存分配盡可能控制在200B以下。
戰(zhàn)斗場(chǎng)景中,UI系統(tǒng)的性能耗時(shí)主要是由UI元素的狀態(tài)變化而導(dǎo)致的,比如血條、飄字等HUD的移動(dòng)、消隱等。這種操作稍不注意,就會(huì)帶來(lái)較高的UI網(wǎng)格重建開銷。所以,UI界面的研發(fā)看似直觀、簡(jiǎn)單,但是其對(duì)于制作時(shí)的層層考究和運(yùn)行時(shí)的耐心調(diào)優(yōu),則是一款產(chǎn)品是否“匠心”的試金石。以下則為《小米超神》這款產(chǎn)品在經(jīng)過(guò)幾輪優(yōu)化后的UI性能對(duì)比圖。
3、動(dòng)畫模塊
在UWA測(cè)評(píng)報(bào)告中,該游戲運(yùn)行時(shí)的動(dòng)畫模塊CPU開銷如下圖所示。可以看出,除進(jìn)入場(chǎng)景時(shí)出現(xiàn)CPU高值外,其在戰(zhàn)斗副本中的CPU開銷均控制在較低水平。Animator.Update的CPU均值為2.0 ms,主要集中在0.1~4.3ms區(qū)間內(nèi),對(duì)于MOBA項(xiàng)目5V5場(chǎng)景來(lái)說(shuō),基本上每幀均有90-130個(gè)物體在進(jìn)行運(yùn)動(dòng)(除英雄、小兵之外,還有信使寵物、野怪、塔、插眼等等),由于玩家可以隨意查看地圖上任何一個(gè)角落的特點(diǎn),其每幀的動(dòng)畫系統(tǒng)壓力要比常規(guī)的MMO游戲大上數(shù)倍。因此,《小米超神》可以將其控制在均值2.0ms的水平線上,已經(jīng)是非常優(yōu)秀的數(shù)據(jù)了。
同時(shí),經(jīng)過(guò)進(jìn)一步檢測(cè)發(fā)現(xiàn),動(dòng)畫模塊的耗時(shí)主要由Animators.ProcessAnimationsJob和Animators.FireAnimationEventsAndBehaviours導(dǎo)致,前者主要是持續(xù)的累積耗時(shí),而后者則是非連續(xù)的“尖刺”開銷。前者是動(dòng)畫系統(tǒng)對(duì)于AnimationClip的讀取和計(jì)算耗時(shí)所致,其耗時(shí)大小與當(dāng)前幀參與計(jì)算的骨骼節(jié)點(diǎn)數(shù)、動(dòng)畫曲線數(shù)、動(dòng)畫執(zhí)行狀態(tài)和Animator Controller的具體設(shè)置相關(guān),其具體說(shuō)明可參見《Unity中動(dòng)畫系統(tǒng)性能優(yōu)化方案回顧》;后者則是動(dòng)畫事件的具體耗時(shí),主要是項(xiàng)目邏輯代碼的性能開銷,此處研發(fā)團(tuán)隊(duì)可以通過(guò)性能堆棧來(lái)進(jìn)一步查看其邏輯代碼的開銷是否有進(jìn)一步的優(yōu)化空間。
4、GC 調(diào)用
該研發(fā)團(tuán)隊(duì)對(duì)于GC調(diào)用頻率控制得非常出眾,游戲在運(yùn)行過(guò)程中,GC調(diào)用頻率為1656幀/次,優(yōu)于目前93%的行業(yè)內(nèi)游戲。一般來(lái)說(shuō),我們建議一款項(xiàng)目的GC調(diào)用頻率可以控制在1000幀/次以上。
該游戲的GC調(diào)用頻率如此優(yōu)秀,主要得益于研發(fā)團(tuán)隊(duì)對(duì)于項(xiàng)目代碼堆內(nèi)存的控制。下圖為游戲運(yùn)行20000幀的代碼堆內(nèi)存具體分配情況,其Top10函數(shù)的堆內(nèi)存分配總和不超過(guò)80MB,足見該團(tuán)隊(duì)對(duì)于堆內(nèi)存分配的理解非常深刻。
當(dāng)前版本的堆內(nèi)存分配仍然有進(jìn)一步下降的空間,從堆棧信息中可以看到,其Log輸出仍然存在一定堆內(nèi)存分配,建議研發(fā)團(tuán)隊(duì)在Release版本中將非關(guān)鍵性Log進(jìn)行屏蔽。
二、內(nèi)存模塊
《小米超神》在內(nèi)存上的表現(xiàn)如下圖所示??們?nèi)存峰值達(dá)到297MB,Mono堆內(nèi)存峰值為48.9MB。297MB的總內(nèi)存分配相對(duì)來(lái)說(shuō)略高,研發(fā)團(tuán)隊(duì)可嘗試在低內(nèi)存機(jī)器上對(duì)資源進(jìn)行進(jìn)一步控制,從而降低低內(nèi)存機(jī)器上的內(nèi)存占用。
1、Mono堆內(nèi)存
從下圖可知,該游戲的總體Mono堆內(nèi)存控制得很好,在20000幀中,Mono的堆內(nèi)存峰值為48.9MB,該值略高(UWA建議《40MB)。從圖中看,是戰(zhàn)斗最后上高地時(shí)突然出現(xiàn)了較高的堆內(nèi)存分配,迫使Mono堆內(nèi)存上漲了8MB(如下圖紅框所示),對(duì)此,研發(fā)團(tuán)隊(duì)可以根據(jù)具體位置查看其堆內(nèi)存分配,即可定位其具體的堆內(nèi)存分配根源。
但是,從走勢(shì)上來(lái)看,其Used Mono堆內(nèi)存占用在5V5戰(zhàn)斗結(jié)束后,并未完全回落到場(chǎng)景之前(如藍(lán)框所示),這一點(diǎn)需要引起研發(fā)團(tuán)隊(duì)注意,確認(rèn)其是否為部分指定容器緩存所致,從而排查項(xiàng)目是否存在堆內(nèi)存泄露的隱患。
2、資源內(nèi)存
經(jīng)過(guò)統(tǒng)計(jì),該游戲運(yùn)行時(shí)的紋理資源數(shù)量峰值為1003個(gè),內(nèi)存占用峰值54.8MB。研發(fā)團(tuán)隊(duì)將紋理內(nèi)存占用控制得很低,目前僅高于30%的行業(yè)項(xiàng)目。經(jīng)過(guò)統(tǒng)計(jì),在內(nèi)存占用峰值處,ETC1和ETC2格式紋理占有835個(gè),RGBA32格式紋理共占有89個(gè),RGB24格式紋理占有5個(gè),其余為RGBA16格式紋理。
紋理資源在項(xiàng)目運(yùn)行期間的總體使用情況:
對(duì)于紋理資源的優(yōu)化,一般可分為以下幾種:
(1)使用更合適的紋理格式
從上圖中可以看到,在整個(gè)游戲一場(chǎng)5V5戰(zhàn)斗過(guò)程中,RGBA32格式紋理的使用數(shù)量較多,其使用總量已經(jīng)超過(guò)了91%的的行業(yè)項(xiàng)目。對(duì)此,我們建議在視覺效果可以保證的情況下,盡可能使用ETC1格式紋理(Android平臺(tái))進(jìn)行替換,不僅可以達(dá)到更小的內(nèi)存占用,同時(shí)可以獲得更快的加載效率。而對(duì)于無(wú)法進(jìn)行硬件壓縮的紋理,可以通過(guò)Dither方法嘗試將其轉(zhuǎn)換成RGBA16格式的紋理,具體做法可以參考Unity圖片優(yōu)化神器 - Dither算法進(jìn)階方案。
(2)使用更精準(zhǔn)的紋理分辨率
一般來(lái)說(shuō),為了讓模型看上去更加精美,除Mesh模型本身以外,其對(duì)應(yīng)的紋理都會(huì)選用較高的紋理尺寸,從而讓其看上去更加精致。但是,由于渲染物體在真正的游戲中相對(duì)于相機(jī)是有遠(yuǎn)近之分的,其顯卡底層往往沒有(或根本不需要)使用如此高的分辨率來(lái)進(jìn)行渲染,從而就造成了大量的資源浪費(fèi),這在我們深度優(yōu)化過(guò)的項(xiàng)目中比比皆是。因此,我們建議可以通過(guò)UWA線上測(cè)評(píng)報(bào)告中GPU性能的Mipmap功能頁(yè)面來(lái)直接查看游戲運(yùn)行時(shí),其底層的紋理分辨率使用情況,如下圖所示。
同時(shí),在深度優(yōu)化報(bào)告中,我們也會(huì)進(jìn)行更大量的測(cè)試和幾十億像素累積分析,從而來(lái)精準(zhǔn)指出到底哪些紋理資源的分辨率制作過(guò)高,可在不影響視覺效果的前提下,將其分辨率縮小4倍、16倍甚至更多?!缎∶壮瘛讽?xiàng)目通過(guò)這種方式不斷優(yōu)化,其5V5場(chǎng)景的紋理內(nèi)存已經(jīng)從之前的78MB降到了現(xiàn)在的52MB。
以上是紋理資源的使用情況,其他資源的內(nèi)存占用情況如下:
網(wǎng)格資源在項(xiàng)目運(yùn)行期間的總體使用情況:
Mesh資源的內(nèi)存占用較高,高于60%的行業(yè)項(xiàng)目。對(duì)于Mesh資源內(nèi)存的優(yōu)化,主要有以下幾種方法:
(1)控制網(wǎng)格頂點(diǎn)屬性的使用
詳細(xì)檢測(cè)網(wǎng)格模型中的Color數(shù)據(jù)和Tangent數(shù)據(jù),當(dāng)不需要時(shí)切記要將其進(jìn)行去除,否則會(huì)在場(chǎng)景模型拼合時(shí)產(chǎn)生大量的內(nèi)存浪費(fèi),具體詳細(xì)說(shuō)明可以參考《移動(dòng)游戲加載性能和內(nèi)存管理全解析》。
(2)控制網(wǎng)格頂點(diǎn)的數(shù)量
詳細(xì)檢測(cè)網(wǎng)格模型的頂點(diǎn)數(shù)(或面片數(shù))使用是否過(guò)大。這是一個(gè)說(shuō)起來(lái)容易但實(shí)施起來(lái)很難的問題,其難點(diǎn)在于如何定義一個(gè)Mesh網(wǎng)格的頂點(diǎn)數(shù)是否過(guò)大。在UWA測(cè)評(píng)報(bào)告中會(huì)有一個(gè)建議,即建議將Mesh網(wǎng)格頂點(diǎn)數(shù)控制在1500個(gè)以下。但實(shí)際上,這其實(shí)是一個(gè)“不科學(xué)”的規(guī)定,因?yàn)闆]有任何一個(gè)理論可以證明,其網(wǎng)格數(shù)量大于1500就是不合格,或則小于1500就一定合格。所以,我們這一年來(lái)花了大量的時(shí)間來(lái)尋求一種更為合理、科學(xué)的判斷規(guī)則。我們認(rèn)為判斷一個(gè)網(wǎng)格模型使用是否合規(guī)并不應(yīng)該是“靜態(tài)”檢測(cè),而應(yīng)該是一種“動(dòng)態(tài)”檢測(cè),與上述紋理資源的檢測(cè)一樣,我們應(yīng)該去看網(wǎng)格資源在底層渲染時(shí)到底占據(jù)了多少像素,從而以一種密度統(tǒng)計(jì)的方式來(lái)判斷其網(wǎng)格使用量是否合理。因此,我們提出了一種網(wǎng)格模型測(cè)量標(biāo)準(zhǔn),即“網(wǎng)格模型渲染密度”,其表示每單位數(shù)量(比如,1萬(wàn))像素中,其網(wǎng)格模型的渲染頂點(diǎn)數(shù)量。
下圖則為游戲運(yùn)行過(guò)程中的網(wǎng)格模型渲染密度統(tǒng)計(jì)值??梢钥闯?,雖然第一個(gè)模型“Mod_xyc_fz1001”的頂點(diǎn)數(shù)僅為1168,但其在游戲運(yùn)行時(shí)平均每幀的渲染像素量?jī)H為34.91個(gè),也就是說(shuō)平均每個(gè)像素要渲染33個(gè)網(wǎng)格頂點(diǎn),這顯然是一種浪費(fèi)。因此,通過(guò)“渲染密度”這一檢測(cè)方式,可以反映任何一個(gè)模型在游戲運(yùn)行時(shí)的使用情況。在我們來(lái)看,這是一個(gè)比單純?cè)O(shè)定1500更加合理的判斷規(guī)則。
AnimationClip資源在項(xiàng)目運(yùn)行期間的總體使用情況:
AnimationClip的內(nèi)存占用較高,高于76%的全類型游戲項(xiàng)目。對(duì)于一款MOBA項(xiàng)目來(lái)說(shuō),其內(nèi)存占用較高是可以理解的,因?yàn)槠鋺?zhàn)斗副本中擁有大量的動(dòng)畫模型,比如英雄、小兵、野怪、塔、基地等建筑等等。對(duì)此,僅能建議研發(fā)團(tuán)隊(duì)嘗試從數(shù)量上進(jìn)行進(jìn)一步地縮減,以降低其內(nèi)存的使用。同時(shí),對(duì)于動(dòng)畫片段內(nèi)存的一般優(yōu)化還有“縮減精度”、“使用Humanoid類型”等方法,其具體優(yōu)化方法可以參考《Unity中動(dòng)畫系統(tǒng)性能優(yōu)化方案回顧》。
三、資源管理
該游戲在資源實(shí)例化/銷毀、Active/Deactive等方面做的非常出色!在游戲運(yùn)行的20000幀中,Instantiate和Destroy調(diào)用次數(shù)分別為1653次和4019次,而Active和Deactive調(diào)用次數(shù)則分別為116次和1447次。同時(shí),對(duì)于Instantiate和Destroy操作來(lái)說(shuō),其主要調(diào)用均在進(jìn)出戰(zhàn)斗場(chǎng)景處,副本中雖有Instantiate調(diào)用,但無(wú)論是頻率還是CPU耗時(shí),均處于合理范圍之內(nèi),如下圖所示。
對(duì)于GameObject相關(guān)的資源管理,我們的建議如下:
(1)對(duì)項(xiàng)目中存在頻繁Instantiate/Destroy操作的GameObject一定要進(jìn)行大力徹查,下圖即為某一項(xiàng)目的Instantiate實(shí)例化詳情,我們建議對(duì)于紅框處高頻率和耗時(shí)的操作重點(diǎn)排查,因?yàn)槠錈o(wú)論是CPU還是堆內(nèi)存都對(duì)項(xiàng)目性能造成非常大的殺傷力!
(2)頻繁的Active/Deactive操作不僅會(huì)造成CPU的浪費(fèi),同時(shí),它還很可能間接造成更大的CPU耗時(shí),比如Animator.Initialize耗時(shí)。在此,我們不妨看下另一款游戲的Animator.Initialize調(diào)用情況,如下圖所示,其調(diào)用的頻率和耗時(shí)較高,這就是頻繁的Active/Deactive操作所造成的結(jié)果。因此,對(duì)于GameObject不必要的Active和Deactive操作進(jìn)行控制,是非常有必要的。更為詳細(xì)的資源加載性能優(yōu)化總結(jié),可參見《Unity移動(dòng)游戲加載性能和內(nèi)存管理全解析》。
(3)不斷檢測(cè)、不斷完善,優(yōu)化是一個(gè)需要不斷迭代、持之以恒的事情。下圖則為《小米超神》經(jīng)過(guò)幾輪優(yōu)化之后的資源管理變化情況。
以上則為《小米超神》游戲在CPU性能和內(nèi)存管理方面的具體使用情況。優(yōu)秀的CPU性能、非常少的堆內(nèi)存分配以及引擎模塊間的合理使用,足以看出該研發(fā)團(tuán)隊(duì)非常深厚的技術(shù)功底和對(duì)于引擎相當(dāng)優(yōu)秀的把控能力。
最后,非常感謝《小米超神》研發(fā)團(tuán)隊(duì)對(duì) UWA 的認(rèn)可和支持。感謝他們樂意將項(xiàng)目性能數(shù)據(jù)與大家一起分享,讓更多的研發(fā)團(tuán)隊(duì)了解到一款性能優(yōu)秀的MOBA手游在各個(gè)模塊上應(yīng)該做到怎樣的程度。同時(shí),也希望更多的開發(fā)團(tuán)隊(duì)可以與我們一起來(lái)分享他們的性能數(shù)據(jù),讓更多的游戲開發(fā)者受益!
關(guān)于UWA
由侑虎科技開發(fā)的游戲/VR應(yīng)用性能優(yōu)化平臺(tái),目前提供 三大工具,幫助開發(fā)者在短時(shí)間內(nèi)大幅度提升性能表現(xiàn);同時(shí)其搭建的知識(shí)分享的博客(blog.uwa4d.com)和答疑解惑的互動(dòng)平臺(tái)(answer.uwa4d.com)使廣大開發(fā)者收益,UWA以實(shí)力和態(tài)度詮釋對(duì)性能優(yōu)化的定義:?jiǎn)栴}的答案永遠(yuǎn)“在現(xiàn)場(chǎng)”,解決你的性能問題,才叫“優(yōu)化”。
評(píng)論