1. 程式人生 > >Unity Profile相關

Unity Profile相關

效能分析 Profiling Ports that the Unity profiler uses: Unity分析器使用的埠如下:     MulticastPort : 54998                        組播埠:54998     ListenPorts : 55000 - 55511                    監聽埠:55000 - 55511     Multicast(unittests) : 55512 - 56023        多路廣播(單元測試):55512 - 56023 They should be accessible from within the network node. That is, the devices that you're trying to profile on should be able to see these ports on the machine with the Unity Editor with the Profiler on. 它們應當在網路節點內部是可訪問的。也就是說,當設定Unity Editor的分析器為開啟時,在你嘗試進行分析的裝置應當是可以看到這些埠的。 First steps 第一步 Unity relies on the CPU (heavily optimized for the SIMD part of it, like SSE on x86 or NEON on ARM) for skinning, batching, physics, user scripts, particles, etc. Unity依靠CPU(對於它的SIMD部分已被巨大的優化了,就像x86上的SSE或是ARM上的NEON一樣)來進行蒙皮、批處理、物理模擬、使用者指令碼、粒子等工作。 The GPU is used for shaders, drawcalls, image effects. GPU則被用於shaders,drawcalls和影象效果。 CPU or GPU bound (CPU 或 GPU限制) Use the internal profiler to detect the CPU and GPU ms 使用內建分析器來檢測CPU和GPU ms Pareto analysis 帕累託分析法 A large majority of problems (80%) are produced by a few key causes (20%). 很大一部分問題(80%)是由於一小部分關鍵原因(20%)引起的。 1.Use the Editor profiler to get the most problematic function calls and optimize them first. 使用編輯器分析器來得到最有問題的函式呼叫,並且在第一時間優化它們。 2.Make sure the scripts run only when necessary. 確保指令碼只在必要時才會執行。 1.Use OnBecameVisible/OnBecameInvisible to disable inactive objects. 使用OnBecameVisible/OnBecameInvisible 來禁用非活躍物件。 2.Use coroutines if you don't need some scripts to run every frame. 如果一些指令碼不需要在每一幀都執行,就使用協同函式。 // Do some stuff every frame: // 在每一幀做一些事情:情: void Update () { } //Do some stuff every 0.2 seconds: // 每0.2秒做一些事情: IEnumerator Start ()_ {    while (true) {       yield return new WaitForSeconds (0.2f);    } } 1.Use the .NET System.Threading.Thread class to put heavy calculations to the other thread. This allows you to run on multiple cores, but Unity API is not thread-safe. So buffer inputs and results and read and assign them on the main thread. 使用 .NET System.Threading.Thread 類來將繁重的運算放到其他執行緒裡。這允許你在多個核心上執行,但是Unity API不是執行緒安全的。因此緩衝區在主執行緒中對它們進行輸入、輸出、讀取、賦值。 CPU Profiling(CPU分析) Profile user code 分析使用者程式碼 Not all of the user code is shown in the Profiler. But you can use Profiler.BeginSample and Profiler.EndSample to make the required user code appear in the profiler. 不是所有的使用者程式碼都被顯示在分析器中。但是你可以使用 Profiler.BeginSample 和 Profiler.EndSample 來使得需要的使用者程式碼出現在分析器中。 GPU Profiling (GPU分析) The Unity Editor profiler cannot show GPU data as of now. We're working with hardware manufacturers to make it happen with the Tegra devices being the first to appear in the Editor profiler. Unity編輯器分析器目前還不可以顯示GPU資料。我們正在硬體製造商合作來使得它可以發生在英偉達圖睿(Tegra)裝置上,這將是第一個出現在編輯器分析器上的GPU。  iOS Tools for iOS (iOS的工具) Unity internal profiler (not the Editor profiler). This shows the GPU time for the whole scene. Unity內部分析器(不是編輯器分析器)。這顯示了整個場景的GPU時間。 PowerVR PVRUniSCo shader analyzer. See below. PowerVR PVRUniSCo著色分析器。見下文。 iOS: Xcode OpenGL ES Driver Instruments can show only high-level info: iOS:Xcode OpenGL ES驅動儀器僅可以顯示上層資訊: o'Device Utilization %' - GPU time spent on rendering in total. >95% means the app is GPU bound. 裝置利用率:GPU在渲染上花費的所有時間。>95%意味著該應用程式是GPU繫結的。 o'Renderer Utilization %' - GPU time spent drawing pixels. 渲染利用率:GPU在繪製畫素上花費的時間。 o'Tiler Utilization %' - GPU time spent processing vertices. Tiler利用率從:GPU在處理頂點上花費的時間。 o'Split count' - the number of frame splits, where the vertex data didn't fit into allocated buffers. 分割次數:幀分割的數量,頂點資訊無法使用分配的緩衝區。 PowerVR is tile based deferred renderer, so it’s impossible to get GPU timings per draw call. However you can get GPU times for the whole scene using Unity's built-in profiler (the one that prints results to Xcode output). Apple's tools currently can only tell you how busy the GPU and its parts are, but do not give times in milliseconds. PowerVR是基於平鋪的延遲渲染器,因此在每一個draw call時得到GPU計時是不可能的。但是,你可以使用Unity內建的分析器(列印Xcode輸出的那一個)得到整個場景的GPU時間。目前,Apple的工具只可以告訴你GPU和它的元件有多繁忙,但是不會給出毫秒單位的時間。 PVRUniSCo gives cycles for the whole shader, and approximate cycles for each line in the shader code. Windows & Mac! But it won't match what Apple's drivers are doing exactly anyway. Still, a good ballpark measure. PVRUniSCo為整個著色器提供迴圈,以及為著色器中的每一行提供一個近似的迴圈。Windows和Mac!但是它不會精確匹配Apple的裝置正在做些什麼。但是,它仍然是一個不錯的估量方法。  Android Tools for Android 安卓的工具 Adreno (Qualcomm) 高通 NVPerfHUD (NVIDIA) 英偉達 PVRTune, PVRUniSCo (PowerVR) 德州儀器 On Tegra, NVIDIA provides excellent performance tools which does everything you want - GPU time per draw call, Cycles per shader, Force 2x2 texture, Null view rectangle, runs on Windows, OSX, Linux. PerfHUD ES does not easily work with consumer devices, you need the development board from NVIDIA. 在圖睿上,英偉達提供了非常棒的效能工具,它們可以做到你想要實現的任何事——每個draw call時的GPU時間,每個著色器的週期數,Force 2x2 貼圖,Null檢視矩形,它們可以執行在Windows,OSX,Linux。PerfHUD ES不那麼容易和使用者裝置一起工作,你需要英偉達的開發板。 Qualcomm provides excellent Adreno Profiler (Windows only) which is Windows only, but works with consumer devices! It features Timeline graphs, frame capture, Frame debug, API calls, Shader analyzer, live editing. 高通提供了傑出的Adreno分析器(只適用於Windows),它僅在Windows上工作,但是可以和使用者裝置一起工作!它的特點有時間軸圖形,幀捕捉,幀除錯,API呼叫,著色器分析器,現場編輯等。 Graphics related CPU profiling (CPU有關的圖形分析) The internal profiler gives a good overview per module: 內建的分析器對於每個模組提供了一個很好的概述: time spent in OpenGL ES API 在OpenGL ES API中花費的時間 batching efficiency 批處理效率 skinning, animations, particles 蒙皮,動畫,粒子系統 Memory 記憶體 There is Unity memory and mono memory. 這裡講述了Unity記憶體和mono記憶體。 Mono memory (Mono記憶體) Mono memory handles script objects, wrappers for Unity objects (game objects, assets, components, etc). Garbage Collector cleans up when the allocation does not fit in the available memory or on a System.GC.Collect() call. Mono記憶體為Unity物件(遊戲物件,資源,元件等等)控制指令碼物件和封裝器。當資源分配和可用記憶體不相配或者在呼叫 System.GC.Collect()時,清理器就會清理空間。 Memory is allocated in heap blocks. More can allocated if it cannot fit the data into the allocated block. Heap blocks will be kept in Mono until the app is closed. In other words, Mono does not release any memory used to the OS (Unity 3.x). Once you allocate a certain amount of memory, it is reserved for mono and not available for the OS. Even when you release it, it will become available internally for Mono only and not for the OS. The heap memory value in the Profiler will only increase, never decrease. 記憶體被分配在堆塊中。如果要分配的資源和已分配塊不相符時,就會分配更多的記憶體。堆塊將會保留在Mono裡,直到app關閉。也就是說,Mono不會釋放任何OS使用的記憶體(Unity 3.x)。一旦你分配了一定數量的記憶體,它就會被mono保留,並對於OS來說不再是可用的。即使當你釋放它,它也僅僅變為是對Mono可用的,而不是對於OS可用。分析器中的堆記憶體值僅會增加,而永遠不會減少。 If the system cannot fit new data into the allocated heap block, the Mono calls a "GC" and can allocate a new heap block (for example, due to fragmentation). 如果系統不能將新的資料分配到已分配的堆塊,Mono就會呼叫一個“GC”,然後可以分配一個新的堆塊(例如,根據儲存碎片)。 'Too many heap sections' means you've run out of Mono memory (because of fragmentation or heavy usage). 過多的堆片段意味著你已經耗盡了Mono記憶體(因為儲存碎片或者繁重的使用)。 Use System.GC.GetTotalMemory to get the total used Mono memory. 使用System.GC.GetTotalMemory來得到已使用的所有Mono記憶體的數量。 The general advice is, use as small an allocation as possible. 通常的裝置應當使用越小的分配越好。 Unity memory (Unity記憶體) Unity memory handles Asset data (Textures, Meshes, Audio, Animation, etc), Game objects, Engine internals (Rendering, Particles, Physics, etc). Use Profiler.usedHeapSize to get the total used Unity memory. Unity記憶體控制資源資料(貼圖,網格,音訊,動畫等等),遊戲物件,引擎內部(渲染,粒子系統,物理等等)。使用Profiler.usedHeapSize來得到已使用的所有Unity記憶體的數量。 Memory map 記憶體對映 No tools yet but you can use the following. 目前還沒有任何工具,但是你可以使用下面的方法。 Unity Profiler - not perfect, skips stuff, but you can get an overview. It works on the device! Unity分析器——不完美,跳過了一些東西,但是你可以得到一個概覽。它在裝置上工作! Internal profiler 內建分析器 oShows Used heap and allocated heap - see mono memory. 顯示已使用的堆和已分配的堆——詳見mono記憶體。 oShows the number of mono allocations per frame. 顯示每一幀時mono資源分配的數目 Xcode tools - iOS oXcode Instruments Activity Monitor - Real Memory column. Xcode儀器活動監視器——Real Memory列。 oXcode Instruments Allocations - net allocations for created and living objects. 儀器分配——對已建立而且活躍的物件的淨分配。 oVM Tracker (VM跟蹤器) textures usually get allocated with IOKit label. 貼圖通常使用IOKit標籤得到分配。 meshes usually go into VM Allocate. 網格通常進入VM分配。 Make your own tool 製作你自己的工具。 oFindObjectsOfTypeAll (type : Type) : Object[] oFindObjectsOfType (type : Type): Object[] oGetRuntimeMemorySize (o : Object) : int oGetMonoHeapSize oGetMonoUsedSize oProfiler.BeginSample/EndSample - profile your own code oUnloadUnusedAssets () : AsyncOperation oSystem.GC.GetTotalMemory/Profiler.usedHeapSize References to the loaded objects - There is no way to figure this out. A workaround is to 'Find references in scene' for public variables. 對已載入物件的引用——沒有方法可以得到它。一個變通的方案是找到場景為公有變數在場景中找到引用。 Memory hiccups 記憶體小資訊 Garbage collector 垃圾回收器 oThis fires when the system cannot fit new data into the allocated heap block. 當系統無法把新的資料分配到已分配的堆塊中,就會開始工作。 oDon't use OnGUI on mobiles 不要在移動裝置上使用OnGUI It shoots several times per frame 它在每一幀時都會被呼叫若干次。 It completely redraws the view. 它完全重繪檢視。 It creates tons of memory allocation calls that require Garbage Collection to be invoked. 它會建立大量的記憶體分配呼叫,並需要垃圾回收器來清理。 oCreating/removing too many objects too quickly? 過快地建立/移除過多的物件? This may lead to fragmentation. 這可能會導致碎片。 Use the Editor profiler to track the memory activity. 使用編輯器分析器來跟蹤記憶體活動。 The internal profiler can be used to track the mono memory activity. 內建分析器可以被用於跟蹤mono記憶體活動。 oSystem.GC.Collect() You can use this .Net function when it's ok to have a hiccup. 當它可以有一個間隔時,你可以使用System.GC.Collect() 這個.Net函式。 New memory allocations 新的記憶體分配。 oAllocation hiccups 分配間隔 Use lists of preallocated, reusable class instances to implement your own memory management scheme. 使用預分配列表,可重用類例項來實現你自己的記憶體管理計劃。 Don't make huge allocations per frame, cache, preallocate instead 不要在每一幀時執行大量的分配,使用快取、預分配來代替。 oProblems with fragmentation? 碎片的問題? Preallocate the memory pool. 預分配記憶體池。 Keep a List of inactive GameObjects and reuse them instead of Instantiating and Destroying them. 儲存一個非活躍遊戲物件列表,然後重用它們而不是例項化再銷燬它們。 oOut of mono memory 耗盡mono記憶體 Profile memory activity - when does the first memory page fill up? 分析記憶體活動——第一張記憶體頁面什麼時候填滿的? Do you really need so many gameobjects that a single memory page is not enough? 你真的需要這麼多遊戲物件以至於一個單獨的記憶體頁面還不夠? oUse structs instead of classes for local data. Classes are stored on the heap; structs on the stack. 對於區域性資料,使用結構體而不是類。類被儲存在堆;而結構體被儲存在棧。 class MyClass {    public int a, b, c; } struct MyStruct {    public int a, b, c; } void Update () {    //BAD   //不好的做法    // allocated on the heap, will be garbage collected later!    //被分配到堆中,隨後將會被垃圾回收!    MyClass c = new MyClass();    //GOOD   // 好的做法    //allocated on the stack, no GC going to happen!     //被分配到棧中,垃圾清理器不會發生!    MyStruct s = new MyStruct(); } Read the relevant section in the manual Link to 閱讀手冊中的相關單元連結http://docs.unity3d.com/Documentation/Manual/UnderstandingAutomaticMemoryManagement.html Out of memory crashes 記憶體不足崩潰 At some points a game may crash with "out of memory" though it in theory it should fit in fine. When this happens compare your normal game memory footprint and the allocated memory size when the crash happens. If the numbers are not similar, then there is a memory spike. This might be due to: 在某些時刻,一個遊戲可能由於“記憶體不足”而崩潰。儘管理論上它最後應當是合適的。當這個問題發生而引發崩潰時,對比你的正規的遊戲記憶體軌跡和已分配記憶體大小。如果得到的數字不是類似的,那麼這就發生了一個記憶體峰值。這可能是由於: Two big scenes being loaded at the same time - use an empty scene between two bigger ones to fix this. 兩個大場景被同時載入——為了解決它,在兩個更大的場景中間使用一個空的場景。 Additive scene loading - remove unused parts to maintain the memory size. 附加的場景載入——移除沒有用到的部分來維護記憶體大小。 Huge asset bundles loaded to the memory 巨大的資源包被載入到記憶體 Loading via WWW or instantiating (a huge amount of) big objects like: 通過WWW載入或是例項化(大量的例項化)龐大的物件,例如: oTextures without proper compression (a no go for mobiles). 沒有合適壓縮的貼圖(對於移動裝置是無效的)。 oTextures having Get/Set pixels enabled. This requires an uncompressed copy of the texture in memory. 被啟用了 獲取/設定畫素 的貼圖。這需要在記憶體中建立一個貼圖的未壓縮的複製品。 oTextures loaded from JPEG/PNGs at runtime are essentially uncompressed. 動態地從JPEG/PNGs載入的貼圖沒有基本上被壓縮。 oBig mp3 files marked as decompress on loading. 在載入時,巨大的mp3檔案被標記為解壓縮。 Keeping unused assets in weird caches like static monobehavior fields, which are not cleared when changing scenes. 在怪異的快取中(像靜態monobehavior區域,當變換場景時它不會被清理)保留了未使用的資源。