UPA深度效能報告解讀
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瓶頸識別做個總結: