首页 理论教育Profiler工具的使用与资源消耗监控

Profiler工具的使用与资源消耗监控

【摘要】:1)程序性能的分析程序性能的分析主要是对Profiler的讲解。Profiler工具是Unity 3D提供的一套用于实时监控资源消耗的工具,通过使用该工具,可以直观地查看程序运行时各个方面资源的占用情况,并匀速找到影响程序性能的线程和函数,再针对性的优化。HandleUtility.SetViewInfo:仅用于Editor中,作用是将GUI在Editor中的显示看起来与发布版本上的显示一致。RenderTexture.GarbageCollectTemporary:存 在于RenderBuffer的垃 圾 回 收 中,清 除 临 时 的FreeTexture。3)GPUUsageDevice.Present:device.PresentFrame的耗时显示,该选项出现在发布版本中。

1)程序性能的分析

程序性能的分析主要是对Profiler的讲解。Profiler工具是Unity 3D提供的一套用于实时监控资源消耗的工具,通过使用该工具,可以直观地查看程序运行时各个方面资源的占用情况,并匀速找到影响程序性能的线程和函数,再针对性的优化。我们可以使用快捷键Ctrl+7快捷键或依次单击“Window→Profiler”命令来调出Profiler窗口。

接下来是Profiler工具中各项参数的意义。

2)CPUUsage

GC Alloc:记录了游戏运行时代码产生的堆内存分配。这会导致ManagedHeap增大,加速GC的到来。我们要尽可能避免不必要的堆内存分配,同时注意:①检测任何一次性内存分配大于2 kB的选项;②检测每帧都具有20 B以上内存分配的选项。

WaitForTargetFPS:VSync功能所致,即显示的是当前帧的CPU等待时间。

Overhead:表示Profiler总体时间,即所有单项的记录时间总和。用于记录尚不明确的时间消耗,以帮助进一步完善Profiler的统计(一般出现在移动设备,锯齿状为Vsync所致)。

Physics.Simulate:当前帧物理模拟的CPU占用量。

Camera.Render:相机渲染准备工作的CPU占用量。

RenderTexture.SetActive:设置RenderTexture操作。比对当前帧与前一帧的ColorSurface和DepthSurface,如果一致则不生成新的RT,否则生成新的RT,并设置与之对应的Viewport和空间转换矩阵

Monobehaviour.OnMouse:用于检测鼠标的输入消息接收和反馈,主要包括SendMouseEvents和DoSendMouseEvents。

HandleUtility.SetViewInfo:仅用于Editor中,作用是将GUI在Editor中的显示看起来与发布版本上的显示一致。

GUI.Repaint:GUI的重绘(尽可能避免使用Unity内建GUI)。

Event.Internal_MakeMasterEventCurrent:负责GUI的消息传送。

CleanupUnused Cached Data:清空无用的缓存数据,主要包括RenderBuffer的垃圾回收和TextRendering的垃圾回收。

RenderTexture.GarbageCollectTemporary:存 在 于RenderBuffer的 垃 圾 回 收 中,清 除 临 时 的FreeTexture。

TextRendering.Cleanup:TextMesh的垃圾回收操作。

Application.IntegrateAssets in Background:遍历预加载的线程队列并完成加载,同时完成纹理的加载、Substance的Update等。

Application.LoadLevelAsyncIntegrate:加载场景的CPU占用。

UnloadScene:卸载场景中的GameObjects、Component和GameManager,一般用在切换场景时。

CollectGameObjects:将场景中的GameObject和Component聚集到一个Array中。

Destroy:删除GameObject或Component的CPU占用。

AssetBundle.LoadAsyncIntegrate:多线程加载AwakeQueue中的内容,即多线程执行资源的AwakeFormLoad函数。

Loading.AwakeFormLoad:在资源被加载后调用,对每种资源进行与其对应的处理。

StackTraceUtility.PostprocessStacktrace()和StackTraceUtility.ExtractStackTrace():一般是由Debug.Log或类似API造成,游戏发布后需将Debug API进行屏蔽。

GC.Collect:系统启动的垃圾回收操作。当代码分配内存过量或一定时间间隔后触发,与现有的Garbage size及剩余内存使用粒度相关。

GarbageCollectAssetsProfile:引擎在执行UnloadUnusedAssets操作。

3)GPUUsage

Device.Present:device.PresentFrame的耗时显示,该选项出现在发布版本中。关于该参数有如下几个常见问题:①GPU的presentdevice确实非常耗时,一般出现在使用了非常复杂的Shader等;②GPU运行是非常快的,而由于Vsync的原因,使得它需要等待较长时间;③同样是Vsync的原因,若其他线程非常耗时,会导致该项等待时间很长,比如过量的AssetBundle加载时容易出现该问题。

Graphics.PresentAndSync:GPU上的显示和垂直同步耗时,该选项出现在发布版本中。Mesh.DrawVBO:GPU中关于Mesh的Vertex Buffer Object的渲染耗时。

Shader.Parse:资源加入后引擎对Shader的解析过程。

Shader.CreateGPUProgram:根据当前设备支持的图形库信息来建立GPU工程。(www.chuimin.cn)

4)Memory

GameObjects in Scene:当前帧场景中的GameObject数量。

TotalObjects in Scene:当前帧场景中的Object数量(除了GameObject外,还有Component等)。

TotalObject Count:Object数量+Asset数量。

SceneMemory:记录当前帧场景中各方面的内存占用情况,包括GameObject、所有资源、各种组件及GameManager等。

5)帧调试器(FrameDebugger)的应用

一个针对渲染的调试器。与其他的调试工具的复杂性相比,Unity原生的帧调试器非常的简单便捷。我们可以使用它来看到游戏图像的某一帧是如何一步步渲染出来的。需要使用帧调试器,首先需要在Window→Frame Debugger中打开帧调试器窗口。

6)GPU优化分为四个部分

(1)DrawCall:Unity每次再准备数据并通知GPU渲染的过程称为一次DrawCall。优化方案:批处理(接下来我们会做详细的讲解)。

(2)物理组件的使用。优化方案:①设置一个合适的FixedTimestep;②不要使用MeshCollider(从优化的角度上来说,我们尽量减少使用物理组建)。

(3)GC(Garbage Collection垃圾回收)。优化方案:减少对CPU的调用(稍后做讲解)。

(4)代码质量。

7)Unity中有两种批处理方式

(1)动态批处理。

好处:一切处理都是自动的,不需要我们自己做任何操作,而且物体是可以移动的。

坏处:限制很多,可能一不小心就会破坏这种机制,导致Unity无法批处理一些使用了相同材质的物体。

(2)静态批处理。

好处:自由度很高,限制很少。

坏处:可能会占用更多的内存,而且经过静态批处理后的所有物体都不可以再移动了。

8)GPU优化

(1)减少绘制的数目。解决方案:模型的LOD技术、遮挡剔除技术。

(2)优化显存的带宽。

9)模型的LOD技术

LOD(Level of Detail)技术的原理是,当另一个物体离摄像机很远时,模型上的很多细节是无法被察觉到的。因此,LOD允许当前对象逐渐远离摄像机,减少模型上的面片数量,从而提高性能。

在Unity中,我们可以使用LODGrounp组件来为一个物体构建一个LOD。我们需要为同一个对象准备多个包含不同细节程序的模型,然后把它们赋给LODGroup组件中的不同等级,Unity就会自动判断当前位置上需要使用哪个等级的模型。

同样它的缺点是需要占用更多的内存,而且如果没有调整好距离的话,可能会造成模拟的突变。

10)遮挡剔除技术

实际开发过程中,每一个场景往往伴随着大量的对象,其中相当一部分对象是不在摄像机拍摄范围内的,进行着一部分对象的绘制是完全没有必要的。强大的Unity 3D引擎提供了非常实用的遮挡剔除技术,使不被拍摄到的点或面不送入渲染管线绘制。

(1)Resource资源不用的要删除,如纹理、网格、音频等等。

(2)在CPU压力不是特别大的时候,重置GameObject、组件等占用的内存。

(3)在打包AssetBundle的时候,可以考虑bundle的压缩。