Unity UI Profiling Tools
版本检查: 5.3 难度: 高级
The external tools provide method-level CPUprofiling with millisecond (or better) resolution, as well as detaileddraw-call and shader profiling.
Instructions for setting up and using theabove tools lie beyond the scope of this guide. Note that the XCode FrameDebugger and Instruments are only usable on IL2CPP builds for Apple platforms,and therefore can currently only be used to profile iOS builds.
Unity Profiler
The primary use for the Unity Profiler isto perform comparative profiling: enabling and disabling elements of a UI whilethe Unity Profiler is running can quickly narrow down the portions of a UIhierarchy that are most responsible for performance issues.

Canvas.BuildBatch is the native-code calculations thatperform the Canvas Batch Building process, as described above.
Also note that the categories can bere-ordered in the CPU profiler. Click and drag the names of the categoriesupwards or downwards to re-order them.
Unity Frame Debugger
The Unity Frame Debugger is a useful toolfor reducing the number of draw calls generated by a Unity UI. This built-intool can be accessed via the Window menu within the Unity Editor. When enabled,it will display all draw calls generated by Unity, including those generated byUnity UI.
Notably, the frame debugger will updateitself with the draw calls generated to display the Game View in the UnityEditor, and therefore can be used to try out different UI configurationswithout even entering Play Mode.
The location of the Unity UI draw callsdepends on the Render Mode selected on the Canvas component being drawn:

As Unity UI operates entirely in thetransparent queue, any quads that have unbatchable quads overlaid atop themmust be drawn before the unbatchable quads, and therefore cannot be batched with other quads placed atop the unbatchable quads.
Consider a case of three quads, A, B, andC. Assume all three quads overlap one another, and also assume quads A and Cuse the same material while quad B uses a separate material. Quad B thereforecannot be batched with A or C.
For further discussion of this issue, seethe Child order section of the Canvas chapter.
Instruments & VTune
Canvas::SendWillRenderCanvases is the C++ parent that calls the Canvas.SendWillRenderCanvases C#method and governs that line in the Unity Profiler. It will contain the codeused to run the Rebuild process, as described in the previous chapter.
Canvas
Canvas::UpdateBatches is identical to Canvas.BuildBatch,but includes additional boilerplate code not covered by the Unity Profilerlabel. It runs the actual Canvas Batch Building process, described above.
When used in conjunction with a Unity appbuilt via IL2CPP, these tools can be used to drill down deeper into thetranspiled C# code of Canvas::SendWillRenderCanvases. Of primary interest willbe the cost of the following methods. (Note: transpiled method namesare approximate.)
IndexedSet_Sort and CanvasUpdateRegistry_SortLayoutList areused to sort the list of dirty Layout components before the layouts arerecalculated. As described above, this involves calculating the number ofparent transforms above each Layout component.
ClipperRegistry.Cull calls all registered implementors ofthe IClipRegion interface. Built-in implementors includeRectMask2D, which uses the IClippableinterface.
During ClipperRegistry.Cull calls, RectMask2D componentsloop over all clippable elements contained within their hierarchy and asks themto update their culling information.
Graphic_Rebuild will contain the cost of actuallycalculating the meshes needed to represent Image, Text or other Graphic-derivedcomponents. Beneath this will be several other methods
like Graphic_UpdateGeometry and,most notably, Text_OnPopulateMesh.
Text_OnPopulateMesh is generally a hotspot when Best Fitis enabled. This is discussed in more detail later in this guide.
Xcode Frame Debugger & Intel GPA
Using the Xcode Frame Debugger
Note: On some versions of Xcode, it is necessary toselect the appropriate Graphics API in the Build Scheme in order to make thegraphics profiler work. To do this, go to the Product menu in Xcode, expand theScheme menu item, and choose Edit Scheme.... Select the Run target and go tothe Options tab. Change the GPU Frame Capture option to match the API used byyour project. Assuming the Unity project is set up to automatically select agraphics API, then most modern iPads will default to using Metal. If in doubt,start the project and look at the debug logs in Xcode. One of the early linesshould indicate which rendering path (Metal, GLES3 or GLES2) is beinginitialized.
Note: The above adjustments should not necessary as ofXcode 7.4, but is still occasionally observed to be necessary in Xcode 7.3.1and older.


file:///C:/Users/user/AppData/Local/Temp/msohtmlclip1/01/clip_image003.png

file:///C:/Users/user/AppData/Local/Temp/msohtmlclip1/01/clip_image004.png
Unity UI only generates quads and so thevertex shader is unlikely to stress the tiler pipeline of the GPU. Any problemsthat appear in this shader pass are likely due to fill-rate issues.
Analyzing profiler results
After gathering profiling data, severalconclusions might be drawn.
If Canvas.BuildBatch or Canvas::UpdateBatches seemsto be using an excessive amount of CPU time, then the likely problem is anexcessive number of Canvas Renderer components on a single Canvas. See the Splitting Canvasessection of the Canvas chapter.
If an excessive amount of time is spentdrawing the UI on the GPU, and the frame debugger indicates that the fragmentshader pipeline is the bottleneck, then the UI is likely exceeding the pixelfill rate which the GPU is capable of. The most likely cause is excessive UIoverdraw. See the Remediating fill-rate issues section ofthe Fill-rate, Canvases and input chapter.
If Graphic Rebuilds are using excessiveCPU, as seen by a large portion of CPU time going to Canvas.SendWillRenderCanvases or Canvas::SendWillRenderCanvases,then deeper analysis is needed. Some portion of the Graphic Rebuild process islikely responsible.
In the case that a large portion of WillRenderCanvas isspent inside IndexedSet_Sort orCanvasUpdateRegistry_SortLayoutList,then time is being spent sorting the list of dirty Layout components. Considerreducing the number of Layout components on the Canvas. See Replacing layouts with RectTransforms and Splitting Canvases sections for possibleremediations.
If excessive time seems to be spent in Text_OnPopulateMesh,then the culprit is simply the generation of text meshes. See the Best Fit and Disabling Canvas Renderers sections forpossible remediations, and consider the advice inside Splitting Canvases if much of the textbeing rebuilt is not actually having its underlying string data changed.
If time is spent inside Shadow_ModifyMesh or Outline_ModifyMesh (orany other implementation of ModifyMesh), then the problem isexcessive time spent calculating mesh modifiers. Consider removing thesecomponents and achieving their visual effect via static images.
If there is no particular hotspot within Canvas.SendWillRenderCanvases,or it appears to be running every frame, then the problem is likely thatdynamic elements have been grouped together with static elements and areforcing the entire Canvas to rebuild too frequently. See the Splitting Canvases section.
Endnotes
尾注