【Unity优化】Profiler性能分析器

【总结,来自Unity Documentation】

本文导图:

点击查看原图

点击查看原图

Profiler概述

Profiler窗口可以帮助我们分析和优化游戏。在这个窗口上有游戏的不同部分所消耗的时间,例如显示渲染、动画和游戏逻辑分别消耗的时间。可以用来分析GPU、CPU、内存、渲染、音频的性能。

Profiler会对性能有一点影响,但是这个影响很小,不会影响到游戏的帧率。

可以对比代码更改前后的性能指标来进行优化分析。

Profiler窗口

Window > Analysis > Profiler 来打开窗口。

控制栏

窗口顶部右侧的传输控件,当游戏运行并收集数据时,单击其中任何一项会暂停游戏。可以分别查看上一帧、下一帧、记录的第一帧、最后一步的帧。

但是Profiler不记录所有的帧数据。Current会显示实时信息。Active Profiler会允许可以在编辑器或单独设备中进行分析。Save以及将记录的帧数据保存成文件,Load可以读取之前保存的。如果在按下shift按钮时单击”Load”,文件内容将附加到内存中的当前概要文件帧。

Deep Profiling

打开后会分析每一个脚本,记录每一个函数的调用。深度分析会产生更大的开销,游戏运行速度会明显变慢。如果脚本代码过于复杂,就根本无法执行深度分析。

手动分析脚本代码块的开销要比使用深度分析小。使用Profiler.BeginSample 和 Profiler.EndSample脚本函数来启用和禁用对代码块的分析。

Color Blind Mode

色盲模式。

View SyncTime

以固定帧率或者垂直空白间隔的同步运行时,Unity在”Wait for Target FPS”中记录等待时间。Profiler中默认不显示。如果要查看就打开View SyncTime。

Profiler Timeline


Profiler窗口的上部显示随时间变化的性能数据。运行游戏时每一帧的数据都会被记录并显示最近的几百帧的数据。单击左侧的特定框架将在窗口的下方显示其详细信息。时间线上的纵轴的比例会自动调整。时间轴由几个区域组成:CPU使用、渲染和内存。如果要获得更多关于CPU使用区域的细节,可以删除内存和渲染区域。注意,标签区域中的彩色方块可以控制是否显示该数据相关的时间轴,点击方块变灰,就会在图中隐藏。

WebGL

区别是不能附加到WebGL中正在运行的播放器上,并且目前无法分析WebGL的DrawCall。

Remote Profiling

远程分析

可以分析在另一台设备上运行的游戏,要将Unity编辑器连接到另一台设备。

iOS

ios启动远程分析的步骤:

  1. 将ios设备连接到同一WiFi网络,或者将设备通过数据线连接。
  2. File > Build Settings选中Autoconnect Profiler。
  3. 选择Build & Run。
  4. 当应用在设备上运行起来的时候启动Profiler窗口。

有时无法自动连接,在Profiler窗口活动Profiler下拉菜单选择适当的设备启动Profiler连接。

Android

WiFi或ADB

使用WiFi:

  1. 禁用Android设备上的移动数据。
  2. 将Android设备连接到本地WiFi网络。
  3. 用数据线连接设备。
  4. 选中Unity的Build Settings对话框中的Development Build和Autoconnect Profiler,然后单击Build & Run
  5. 当应用程序在设备上启动时,在Unity编辑器中打开Profiler窗口。

如果无法自动连接,在Profiler窗口活动Profiler下拉菜单选择适当的设备启动Profiler连接。

ADB:

  1. 数据线连接设备并确保ABD识别到设备。
  2. 选中Unity的Build Settings对话框中的Development Build和Autoconnect Profiler,然后单击Build & Run,会自动创建一个ABD通道
  3. 当应用程序在设备上启动时,在Unity编辑器中打开Profiler窗口。
  4. 从Profiler窗口Active Profiler下拉菜单中选择AndroidProfiler

如果要配置另一个应用程序或重启adb服务器,必须手动设置此通道。

注意:下拉菜单中的条目只有在选择的目标为Android时才可见。如果正在使用防火墙,需要确保端口54998到55511在防火墙的出站规则中是打开的,Unity用于远程分析的端口。

CPU Usage Profiler

CPU使用分析器

CPU使用情况分析器显示时间都被用在了游戏的哪些地方。

被选中时,下面的窗格显示所选帧的分级时间数据。有两种模式。Hierarchy mode,显示分级时间数据。Group Hierarchy mode,将时间数据分组为逻辑组(如呈现、物理、脚本)。因为任何组的子组也可以位于不同的组中,所以组时间的百分比通常加起来超过100%。上下拖动图表标签可以重新排列CPU图表的排列方式。

选择个别项目

选中项目的细节信息会显示在右侧窗口。

左侧的Self列指的是在特定函数中花费的时间,不包括调用子函数的时间。Total是总计。Time ms和Self ms列显示相同的信息,但单位是毫秒。GC Alloc列显示了在当前帧中分配了多少内存,该帧稍后由垃圾收集器(Garbage Collection)收集,将此值保持为零,以防止垃圾收集器在帧之间引起停顿。

Others记录的是所有不属于呈现、脚本、物理、Garbage Collection或VSync的区域的总数,括动画、AI、音频、粒子、网络、加载和PlayerLoop。

Physics markers

物理标记

各种高级物理分析器标记的含义。

  • Physics.Simulate: 从FixedUpdate调用。通过指示物理引擎(PhysX)运行其模拟来更新物理的当前状态。
  • Physics.Processing: 从FixedUpdate调用。这是所有非布料物理工作处理的地方。展开此标记可以显示物理引擎内部正在进行的工作的底层细节。
  • Physics.ProcessingCloth: 从FixedUpdate调用。所有的布料物理工作都在这里进行。扩展此标记将显示物理引擎内部正在进行的工作的低层细节。
  • Physics.FetchResults: 从FixedUpdate调用。从物理引擎中收集物理模拟结果。
  • Physics.UpdateBodies: 从FixedUpdate调用。这是所有物理实体更新它们的位置旋转的地方,也是传递这些更新的消息的地方。
  • Physics.ProcessReports: 从FixedUpdate调用。此阶段在物理FixedUpdate结束后运行,在此阶段处理响应模拟结果的所有不同阶段。Joint中断、Contacts和Triggers在这里更新和发送消息。有四个不同的子阶段:
    • Physics.TriggerEnterExits: 从FixedUpdate调用。处理OnTriggerEnter和OnTriggerExit事件。
    • Physics.TriggerStays: 从FixedUpdate调用。处理OnTriggerStay事件。
    • Physics.Contacts: 从FixedUpdate调用。处理OnCollisionEnter、OnCollisionExit和OnCollisionStay事件。
    • Physics.JointBreaks: 从FixedUpdate调用。处理与正在断开的连接相关的更新和消息。
  • Physics.UpdateCloth:从Update调用。有关布料和它们的皮肤网格的更新。
  • Physics.Interpolation: 从Update调用。这个阶段处理所有物理对象的位置和旋转的插值。

Performance warnings

性能警告

CPU分析器能够检测并警告一些常见的性能问题。出现在下面的窗格的警告列中。

分析器可以检测到的具体问题:

  • Rigidbody.SetKinematic [Re-create non-convex MeshCollider for Rigidbody]
  • Animation.DestroyAnimationClip [Triggers RebuildInternalState]
  • Animation.AddClip [Triggers RebuildInternalState]
  • Animation.RemoveClip [Triggers RebuildInternalState]
  • Animation.Clone [Triggers RebuildInternalState]
  • Animation.Deactivate [Triggers RebuildInternalState]

CPU Profiler Timeline

CPU分析器时间线

Mem Record: Native memory performance profiling

Mem记录:本地内存性能分析

本机内存性能分析允许分析Unity本机内存管理系统中的活动,并评估它如何影响运行时性能。在Unity内存管理中搜索不需要的或资源密集型的分配模式时十分有用。

要使用此项需要手动记录。Window > Analysis > Profiler选择CPU Usage Profiler然后点击Timeline再选择Mem Record,然后选择记录模式:

选项 功能 对性能的影响
None 模式禁用。这是默认选择。 不存在
Sample only 记录内存分配、re-allocations, de-allocations、活动类型和系统。
Callstack (fast) 具有与Sample相同的功能,而且还记录了一个。实际上callstack从本机分配站点到callstack从本机符号转换为脚本符号的地方,我们只能看到callstack到最深的脚本符号。 中等
Callstack (full) 具有与Sample相同的功能,还记录了具有完整的脚本到本机和本机到脚本转换的callstack。

注意:当active Profiler只连接到独立播放器时,只支持低影响的Sample only模式。

所记录的内存分配示例以鲜红色显示在Profiler窗口中。

单击Mem Record旁边的High Detail按钮以启用High Detail模式。选择一个示例来显示分配类型和系统。如果为所选分配示例记录了callstack,则还将解析并显示关联的callstack符号:

High Detail view of Timeline

时间轴的高细节视图

Window > Analysis > Profiler选择CPU Usage Profiler然后选择底部的菜单点击Timeline再点击High Detail。

该模式给每次样本记录至少一个像素的宽度。可以全面查看框架中的所有活动,包括短期活动,如线程同步或内存分配。

两种模式的比较:

高细节视图

标准视图:

Rendering Profiler

渲染分析器

时间轴显示所Batches、SetPass Calls、Draw Calls、三角形和顶点的数量。下面的窗格显示了更多的渲染统计信息,与GameView呈现Rendering Statistics窗口中显示的统计信息匹配。

Memory Profiler

内存分析器

两种模式:

简单:

显示了内存是如何在每帧的基础上实时地在Unity中使用的。

Unity为分配预留内存池,以避免过于频繁地向操作系统请求内存。这将显示一个预留大小,以及使用了多少。

包含的内容有:

  • Unity 在本地Unity代码中被分配追踪的内存容量
  • Mono使用的总的堆的大小,还有管理代码使用的堆大小。这个内存是garbage-collected
  • GfxDriver 驱动程序在纹理、渲染目标、着色器和网格数据上使用的内存估计量
  • FMOD 音频驱动程序的估计内存使用量
  • Profiler 用于分析器数据的内存

显示的数字与任务管理器或活动监视器不同,因为内存分析器无法跟踪某些使用情况。这包括一些驱动程序使用的内存,以及可执行代码使用的内存。

内存统计数据显示了一些最常见的Asset/object类型:

  • Textures
  • Meshes
  • Materials
  • Animations
  • Audio
  • Object Count 创建的对象的总数

Detailed

细节

允许获取当前状态的快照。获取这些数据需要一些时间,因此细节视图很难提供实时的详细信息。在获取一个示例之后,Profiler窗口将更新为一个树状视图。

显示单个Assets和GameObject内存使用情况,还显示了GameObject存在内存中的原因。常见的原因有:

  • Assets: 从用户或本机代码引用的Asset
  • Built-in Resources: Unity Editor 资源或 Unity 默认资源
  • Not Saved: 被标记为 DontSave的GameObjects
  • Scene Memory: GameObject 和附加的 components
  • Other: GameObjects 未在上述类别中标记

Audio Profiler

音频分析器

监视音频系统的重要性能,如总负载和声音计数。

  • Playing Sources 特定帧在场景中总的播放中的资源。监视音频是否超载。
  • Paused Sources 特定帧在场景中总的暂停的资源。
  • Audio Voice 实际使用的音频(FMOD通道)声音数量。 PlayOneShot 是在 Playing Sources没有显示的声音。
  • Audio Memory 是被音频引擎总共使用的RAM。

Channel view

通道视图

当单击一行时,首先突出显示AudioClipAsset,然后在层次结构中显示被播放的AudioSource。

Channels and groups view

通道和组视图


Physics Profiler

物理分析器

物理分析器显示物理引擎处理过的关于物理的统计信息。

性能

功能

Active Dynamic

处于活跃状态的non-Kinematic Rigidbody 数量

Active Kinematic 活跃的 Kinematic Rigidbody 数量。 注意带有joints的 Kinematic Rigidbody 组件在一帧中可能会处理多次。 当 MovePosition 或者 MoveRotation在一帧中调用的时候,Kinematic Rigidbody 处于活跃状态, 并且在下一帧继续保持活跃。
Static Colliders 在自身或者其父GameObject没有附加Rigidbody组件但附加了Colllider组件的GameObject的数量。

如果一个GameObject 或者其父对象有Rigidbody组件,则不会计数在Static Coliders。

Rigidbody

物理引擎处理的Rigidbody组件数量, 与其是否是休眠状态无关。

Trigger Overlaps

重叠触发器的数量(成对计算)。

Active Constraints

物理引擎处理的primitive constraint 数量。Constraints被用作关节和碰撞响应的构建块。

Contacts

场景中所有对撞机之间的接触对的总数,包括触发器重叠对的数量。注意,一旦碰撞器对之间的距离低于某个用户可配置的限制,就会为每个碰撞器对创建接触对,因此可能会看到为尚未接触或重叠的刚体组件生成的接触。

注意:

这些数字可能与场景中带有物理组件的游戏对象的确切数量不相符。这是因为一些物理组件的处理速度不同,这取决于其他组件对其的影响(例如,附加的关节组件)。物理分析器没有显示睡眠Rigidbody组件的数量。这些组件不参与物理引擎,因此不被物理分析器处理。

使用物理分析器来理解性能问题

物理模拟运行在一个独立的固定频率更新周期从主逻辑的更新循环,并每次只能通过一个提前时间调用Time.fixedDeltaTime。这类似于Update和FixedUpdate之间的区别。

GPU Profiler

GPU分析器

显示了游戏中GPU时间都用在了哪里。

注意,当Graphics Jobs (Experimental)Player设置中启用的时候GPU分析会被禁用。

远程分析支持

平台

图形API

状态

Windows D3D9,D3D11,D3D12, OpenGL core, OpenGL ES 2.0, OpenGL ES 3.x, Vulkan 支持
Mac OS X OpenGL core 支持
Metal 不可用。 使用 XCode’s GPU Frame Debugger UI代替。
Linux OpenGL core, Vulkan 支持
PlayStation 4 libgnm 支持
Xbox One
D3D11 支持
WebGL
WebGL 1.0 and WebGL 2.0 不可用
Android OpenGL ES 2.0, OpenGL ES 3.x 只支持运行NVIDIA或Intel GPUs的设备。
Vulkan 支持
iOS, tvOS Metal, OpenGL ES 2.0, OpenGL ES 3.0 不可用。使用XCode’s GPU Frame Debugger UI 代替。
Tizen

OpenGL ES 2.0

不可用

在Unity编辑器中进行概要分析

编辑器只支持使用Direct3D 9和Direct3D 11 api在Windows上进行概要分析。它便于快速分析,因为这不需要构建播放器。但是,分析器受到运行Unity编辑器的开销的影响,会降低分析结果的准确性。

Global Illumination Profiler

全局光照分析器

名称

描述

Total CPU Time

所有线程的Enlighten CPU总时间。

Probe Update Time

更新 Light Probes的时间。

Setup Time

Setup 阶段花费的时间。

Environment Time

处理环境光照花费的时间。

Input Lighting Time

用于处理输入照明的时间。

Systems Time

用于更新系统的时间。

Solve Tasks Time

用于运行辐射求解器任务的时间。

Dynamic Objects Time

用于更新Dynamic GameObjects 的时间。

Time Between Updates

更新Global Illumination之间的时间

Other Commands Time

用于处理其他命令的时间。

Blocked Command Write Time

在阻塞状态下等待命令缓冲区的时间。

Blocked Buffer Writes

正在阻塞的命令缓冲区的写入数。

Total Light Probes

场景中Light Probes的总数。

Solved Light Probes

自上次更新以来已解决的Light Probes数量。

Probe Sets

场景中设置的Light Probes数量。

Systems

场景中Enlighten Systems的数量。

Pending Material GPU Renders

在GPU上排队渲染的Albedo/Emission渲染数。

Pending Material Updates

等待处理的材料更新数量。

UI Profiler

UI 处理器

专门用于游戏内UI的模块。

通过Profiler窗口的菜单访问:Add Profiler > UI and UI Details

UI Details图表有一个可切换的标记组,类似于CPU图表提供的标记组。在预览面板中,有一个按钮分离和两个下拉菜单。

  • 标记切换在UI详细信息图表上显示或隐藏事件标记。
  • Detach 会在一个单独的窗口中弹出预览。
  • 两个下拉菜单选择预览背景。