本节将深入探讨Unity中各个分析工具和调试工具的功能。
以下是分析工具、调试工具和静态分析工具之间的差异:
- 分析工具对代码执行情况进行仪表化显示并收集时间数据。
- 调试工具允许逐步执行程序,暂停和检查值,并提供许多其他高级功能。例如,Frame Debugger可以逐步执行帧渲染,检查着色器值等。
- 静态分析器可以将源代码或其他资源作为输入,并使用内置规则对输入进行“正确性”推理,而无需运行项目。
分析工具
Unity Profiler 可以在运行时分析性能瓶颈,并更好地了解特定帧或时间点所发生的情况。
Unity Profiler可以提供大量的分析标记数据。请注意,在Editor中直接进行分析会增加额外开销并影响结果。
只启用关注的Profiler模块或使用Standalone Profiler,以提供更纯净的分析数据,降低分析开销。按照经验,启用 CPU、Memory 和 Renderer 模块总是有用的;然后根据需要启用其他 Profiler 模块,例如Audio和Physics。
开始Unity性能分析
按照以下步骤开始使用 Unity Profiler:
- 在进行分析时,必须使用开发版本。File > Build Settings > Development Build。
- 勾选Autoconnect Profile(可选)。
- 注意:Autoconnect Profile会增加初始启动时间。如果不启用Autoconnect Profiler,可以随时手动连接正在运行的开发版本。
- 针对目标平台进行构建。
- 通过 Window > Analysis > Profiler 打开 Unity Profiler。
- 禁用不关注的Profiler模块。每个启用的分析模块都会带来性能开销。(可以使用Profiler.CollectGlobalStats标记观察一些开销。)
- 禁用设备的移动网络,保持 WiFi 开启。
- 在目标设备上运行构建版本。
- 如果选择Autoconnect Profiler,那么构建版本中将会嵌入Editor所在机器的 IP 地址。启动应用时,它将尝试直接连接到此 IP 的Profiler。Profiler 将自动连接并开始显示帧和分析信息。
- 没有选择Autoconnect Profiler,则需要使用“Target Selection”下拉菜单手动连接。
Profiler与目标设备自动连接时
为了节省构建时间(牺牲部分准确性),对Editor中运行的应用程序直接分析。在Profiler窗口中,从Attach to Player下拉菜单中选择Playmode。
使用Profiler分析Playmode下运行的游戏
分析提示
在CPU Usage中禁用VSync
CPU主线程在等待VSync时处于空闲状态。但是隐藏标记有时会使人难以理解其他类别时间的组成,甚至无法理解当前帧总时间的组成。
考虑到这一点,重新排序显示列表,使VSync标记位于顶部。这样可以降低VSync标记的干扰降,使整体画面更清晰。
在构建中禁用VSync
通过Edit > Project Settings,然后选择Quality ,设置VSync Count为Don't Sync。
发布development版本,并连接到Profiler。游戏不再等待下一个VBlank,而是在一帧完成后立即开始下一帧。禁用VSync可能会在某些平台上产生视觉撕裂(这种情况下,为release版本重新启用VSync)。
什么时候在Playmode或Editor下分析
使用Profiler时,可以选择Playmode、Editor、远程或附加设备作为目标。将Editor下分析,对分析的准确性有很大影响。因为Profiler实际上也递归地对分析了自己本身。
然而当Editor的性能变差时,分析Editor就非常就有价值了,可以后续分析影响Editor性能的脚本和扩展。
分析Editor的一些示例
- 按下Play按钮后进入Play模式需要很长时间
- Editor变得缓慢或无响应
- 项目打开需要很长时间。文章Tips for working more effectively with the Asset Database介绍了如何使用 -profiler-enable命令行。
使用Standalone Profiler
当在Editor下分析时,Standalone Profiler将作为一个新的进程启动。这避免了Profiler UI和Editor对时间统计的影响,以获得更干净的分析数据。
在Editor中分析并快速迭代
如果在构建包中发现性能问题,可以先在Editor中验证是否存在相同问题。如果存在问题,在Editor中定位并快速解决。一旦问题解决,再去目标设备上运行以验证解决方案。
这种优化过工作流程,可以不必先花费时间构建部署,而是先在Editor中快速迭代,再使用分析工具验证优化结果。
Frame Debugger
Frame Debugger在运行时允许暂停在指定帧,以查看渲染该帧的draw call信息。与其他帧调试工具相比,Frame Debugger的一个优势是,如果draw call对应于某个 GameObject ,则该对象在Hierarchy面板中会突出显示。Frame Debugger也可以用于测试overdraw。
使用Frame Debugger分析overdraw
从Window > Analysis > Frame Debugger菜单中打开Frame Debugge。 在编辑器中或设备上运行应用程序时,单击Enable。应用程序将会暂停,并在帧调试窗口的左侧按顺序列出当前帧的所有draw call。还包括如帧缓冲清除事件等详细信息。
Frame Debugger在左侧列出draw call和event,并提供一个滑块,可以逐帧显示。
右侧的面板提供了draw call的详细信息,例如几何细节和shader。其他信息还包括draw call无法与之前合批的原因,以及输入到shader的属性值。
选中一个draw call,详细信息区域中显示shader,不能合批的原因,shader属性值。
除了shader属性值,ShaderProperties部分还会显示它在哪些阶段中被使用(例如vertex, fragment, geometry,hull, domain)。
着色器阶段会在ShaderProperties详细信息区域中显示
远程到Frame Debug
在支持的平台上(WebGL不支持),可以远程连接到Frame Debug。
设置远程帧调试:
- 创建目标平台的标准构建。
- 运行播放器。
- 从Editor中打开Frame Debugger。
- 单击Player下拉列表,选择正在运行的目标。
- 单击Enable。
Frame Debugger窗口远程连接到构建
Render target显示选项
Frame Debug窗口有一个工具栏,可以独立显示Game视图的R、G、B、A通道。使用channel按钮右侧的Levels滑块,按照亮度级别显示。当存在多个渲染目标时,可以使用RenderTarget下拉列表选择在Game视图中显示的渲染目标。
下拉列表还有一个Depth选项,用于显示深度缓冲区的内容。
显示深度缓冲区内容
5个常见染优化技巧
首先定位性能瓶颈。主流平台都提供了分析CPU和GPU性能的工具。例如,Arm/Mali GPU,可以使用Arm Mobile Studio;Microsoft Xbox,可以使用PIX;Sony PlayStation,可以使用Razor;Apple iOS,可以使用Xcode Instruments。
1.draw call优化
降低draw call批次的技术包括:遮挡剔除;GPU实例化;SRP合批
2.减少overdraw,优化填充率
overdraw表明应用程序试图在每帧内绘制比GPU处理能力更多的像素。这不仅会影响性能,还会影响移动设备的热量和电池寿命。可以通过了解Unity在渲染对象之前如何对它们进行排序来解决过度绘制问题。
内置渲染管线根据对象的Rendering Mode和renderQueue进行排序。每个对象的着色器将其放入一个渲染队列中,通常决定其绘制顺序。
相互重叠的对象会产生过度绘制。如果正在使用内置渲染管线,请使用Scene viewcontrol来可视化overdraw。将绘制模式切换为Overdraw。
亮色像素表示对象重叠绘制,而暗色像素表示重叠绘制较少
标准视图
Overdraw视图
3.检查消耗性能的着色器
4.渲染的多线程优化
5.分析后处理效果
Profile Analyzer
Unity Profiler可以进行单帧分析,但是Profile Analyzer可以聚合显示一组Unity Profiler帧捕获的分析标记数据。
开始使用Profile Analyzer:通过Window> Package Manager 安装Profile Analyzer包。
在使用Profile Analyzer时,一个好的方法是保存分析会话,在性能优化工作之前和之后进行比较。
Profile Analyzer会提取在Unity Profiler中捕获的一组帧,对它们进行统计分析。然后显示这些数据,为每个函数生成性能时间信息,例如最小值、最大值、平均值和中位数时间。 在开发过程中,它可以帮助解决和优化问题。将其用于游戏场景的A/B测试以查看性能差异,在较重构和优化代码前后分析数据,以及升级新功能或Unity版本前后使用。
在Profile Analyzer 的 Single view中使用总计数据也可以找到随时间变化的性能问题。
Profile Analyzer主窗口视图
Profile Analyzer 具有多种视图和分析性能数据的方式,它提供不同的面板用于选择、排序、查看和比较一组性能分析数据。
Frame Control 面板用于选择一帧或一组帧。选择后,Marker Details 面板将更新,以显示所选范围的数据,包含统计信息的排序列表。Marker Summary 面板显示选定标记的详细信息。列表中的每个标记都是该标记在所选帧范围内,跨所有筛选线程实例的聚合。
Marker Summary 面板显示 Marker Details 面板中选择的每个 Marker 集合的详细信息。
使用Name Filter,或Thread进行筛选。当查看 Time 或 Count 统计值的范围选择时,这非常有用。
按线程或标记名称进行筛选,以便在 Marker details 面板中关注特定的性能数据。
调整Filters时,Marker details面板可以自定义地显示分析数据的不同信息集。使用Marker column下拉菜单选择预设选项,或自定义选项。
使用Marker column的预设选项自定义Marker details面板显示的统计信息。
这些预设选项包括:
- Time and count:显示markers平均计时和调用次数的信息
- Time:显示markers的平均计时信息
- Totals: 显示markers对整个数据集所需的总时间信息
- Time with totals:同时显示markers的平均计时和总时间信息
- Count totals: 显示markers被调用的总次数信息
- Count per frame:显示markers每帧被调用的平均总次数信息
- Depths:显示markers在层次结构中的位置信息
- Threads: 显示markers所在的线程名称信息。
Profile Analyzer视图
Single视图
Single视图显示单个捕获数据集的信息。使用它来分析每一帧profile markers的执行情况。该视图分为几个面板,其中包含每帧、每个线程和每个标记的计时信息(最小值、最大值、中位值、平均值)。
Single视图显示单个或一组帧的profile marker统计信息和计时信息
Profile Analyzer使用提示
- 通过选择Depth level为4,可以深入到用户脚本中(忽略Unity Engine API)。在Unity Profiler timeline模式下查看,您可以对调用堆栈深度进行相关分析: Monobehaviour脚本将以蓝色出现,并在第四个级别下。
- 以同样的方式过滤Unity其他部分,例如animators或engine physics。
- 在Frame Summary部分的右侧,可以找到突出显示的方法性能范围直方图。将鼠标悬停在最耗时帧上,获取可以点击的链接,从而查看Unity Profiler中的帧选择。使用此视图来分析导致该帧消耗时间的因素。
Compare视图
Compare视图是Profile Analyzer真正发挥作用的地方。在此视图中,您可以加载两个数据集,Profile Analyzer将以两种不同的颜色分别显示两个数据集。
通过“拉取数据”方法将配置文件会话数据加载到Profile Analyzer中:
- 通过Window > Analysis > Profile Analyzer 打开Profile Analyzer。
- 使用Unity Profiler捕获数据。
- 在Profile Analyzer中,切换到对比页签,然后单击第一个“Pull Data”按钮加载来自Profiler的捕获数据。
- 在代码和性能改进之后,使用Unity Profiler再次捕获数据。
- 单击第二个“Pull Data”按钮加载新的捕获数据。
注意:如果选择加载选项,则数据必须采用Profile Analyzer的.pdata文件格式。如果拥有Profiler的.data格式的文件,请先在Profiler中打开它,然后单击Profile Analyzer中的Pull Data按钮。(确保在拉取数据之前保存Profiler的.data文件)
使用Marker Comparison查看第一组和第二组数据集(左侧和右侧)之间的计时差异。
调整Marker Columns filter会相应地更改要进行比较的值。
比较Median Frame和Longest Frame
在单个捕获数据中比较Median Frame和Longest Frame,找到在Longest Frame中出现,在Median Frame中没出现的事情,或查看哪些操作超过了平均完成时长。
打开Profile Analyzer的Compare视图,在左右两侧加载同一个数据集。也可以在Single视图中加载数据集,然后切换到Compare视图。
右键点击上侧的Frame Control图,选择Select Median Frame。右键点击下侧Frame Control图,选择Select Longest Frame。
Profile Analyzer的Marker比较面板将更新显示差异。
比较单个捕获数据中的Median Frame和Longest Frame
一个技巧是,在比较数据时将Frame Control图按帧时间排序(右键单击>Order By Frame Duration),然后在每个集合中选择一个范围来进行比较。
按照持续时间排序并选择范围