包含此页的版本:
不含此页的版本:
Unity 的代码使用探查器标记放置在代码中,用于描述 CPU 或 GPU 事件,然后显示在 Unity 探查器窗口中。默认添加到 Unity 代码中,或者您可以使用 ProfilerMarker API 添加自己的自定义标记。更多信息
请参阅术语表这使您能够深入了解应用程序中占用时间的内容。下表包含一些内置标记的列表。
主线程基本标记清楚地区分了在应用程序上花费的时间和在 Unity 编辑器上花费的时间,以及分析器帮助您优化游戏的窗口。它显示了在游戏的各个领域花费了多少时间。例如,它可以报告渲染、动画制作或游戏逻辑所花费的时间百分比。更多信息
请参阅术语表活动。您还可以将这些标记与ProfilerRecorderAPI 来获取主线程上帧的时序,或FrameTimingManager用于运行时高级帧统计数据的 API。
您还可以使用分析器计数器使用 ProfilerCounter API 放置在代码中,以跟踪指标,例如游戏中生成的敌人数量。更多信息
请参阅术语表CPU 主线程帧时间、CPU 渲染线程帧时间和 CPU 总帧时间,以获取应用程序 CPU 使用率的高级计时。有关更多信息,请参阅渲染分析器计数器参考。
| 标记 | 描述 |
|---|---|
| 玩家循环 | 包含源自应用程序主循环的任何示例。如果当播放器在激活播放模式下在编辑器中运行时,你以编辑器而不是播放模式为目标,则 PlayerLoop 采样将嵌套在 EditorLoop 下。 |
|
EditorLoop (仅编辑器标记) |
包含源自编辑器主循环的任何样本。这仅在你在编辑器中分析玩家时才会出现。当你使用性能分析器以播放模式为目标时,EditorLoop示例会指示渲染和运行包含播放器的编辑器所花费的时间。 有关更多信息,请参阅播放模式和编辑模式示例。 |
|
Profiler.CollectEditorStats (仅编辑器标记) |
包含与收集不同活动探查器模块的统计信息相关的任何示例。 嵌套在 Profiler.CollectGlobalStats标记指示玩家在收集特定模块的统计信息时有多少开销。所有其他子样本仅反映其在编辑器中的效果。要消除特定模块的开销,请关闭模块的图表,或调用 Profiler.SetAreaEnabled.注意:使用内置计数器的自定义分析器模块会启用内置计数器的区域,即使它所属的模块已禁用。要防止性能分析器收集这些统计信息并产生收集开销,请确保禁用内置性能分析器模块和自定义性能分析器模块。 |
除非您使用的是作业系统,否则大多数脚本代码都嵌套在以下标记下。有关作业系统示例的信息,请参阅本页的多线程标记部分。
有关 Unity 更新循环的更多详细信息,请参阅有关事件函数执行顺序的文档。您可以使用以下命令将自己的回调插入到播放器循环中PlayerLoop.SetPlayerLoop.如果将回调直接插入主循环,则脚本更新示例会自行显示。如果将回调作为子系统插入,则样本将显示在相应的主 PlayerLoopSystem 标记下。
| 标记 | 描述 |
|---|---|
| 行为更新 | 包含所有样本MonoBehaviour.Update方法。 |
| 协程延迟调用 | 包含协程首次生成后的所有样本。 |
| 已修复行为更新 | 包含所有样本Monobehaviour.FixedUpdate方法。 |
| PreLateUpdate.ScriptRunBehaviourLateUpdate | 包含所有样本Monobehaviour.LateUpdate方法。 |
| Update.ScriptRunBehaviourUpdate (更新.ScriptRunBehaviour更新) | 包含所有样本MonoBehaviour.Update和协程。 |
这些标记包含 CPU 花费时间处理 GPU 数据的样本,或者它可能等待 GPU 完成的样本。如果 GPU Profiler 模块不可用,或者它增加了太多开销,则工具栏Unity 编辑器顶部的一排按钮和基本控件,允许您以各种方式(例如缩放、翻译)与编辑器交互。更多信息
请参阅术语表在探查器模块详细信息窗格中,不会显示此信息。这些标记下的示例可以让您很好地了解应用程序是受 CPU 限制还是受 GPU 限制。
| 标记 | 描述 |
|---|---|
| 等待目标FPS | 指示应用程序等待目标 FPS 所花费的时间Application.targetFrameRate指定。如果示例是 Gfx.WaitForPresentOnGfxThread 的子示例,则表示应用程序等待 GPU 所花费的时间量。例如,这可能是GPU等待下一个VSync所花费的时间(如果在QualitySettings.vSyncCount中配置了该VSync),或者如果在目标平台上强制实施了vSync。但是,如果 GPU 尚未完成帧计算,也会发出带有此标记的样本。 要确定导致具有此标记的样本使用大量时间的原因,请切换到 CPU Profiler 模块中的 Timeline 视图。在此视图中,您可以检查渲染线程上发生的情况,以及此示例在当前帧中结束与在周围帧中结束的相同示例之间经过了多长时间。 如果持续时间大于应用程序的帧时间(基于目标帧速率或 vSync),则帧渲染或计算所需的时间过长。如果是这种情况,请调查渲染线程,看看它在 Gfx.PresentFrame 上花费了多少时间,而不是它为准备和向 GPU 发出命令所做的其他工作。如果渲染线程在 Gfx.PresentFrame 中花费了大量时间,则渲染工作受 GPU 限制。如果渲染线程的时间花在准备命令上,则应用程序受 CPU 限制。 要了解要关注的内容,如果您的应用程序受 GPU 限制,请使用 Unity Profiler 或平台分析器对 GPU 进行分析。有关详细信息,请参阅有关如何优化图形性能的用户手册文档。 注意:编辑器不会在GPU上进行垂直同步,而是使用 WaitForTargetFPS 来模拟垂直同步的延迟。某些平台(尤其是 Android 和 iOS)强制执行 VSync 或默认帧速率上限为 30 或 60。 |
| Gfx.PresentFrame | 表示应用程序等待 GPU 呈现和呈现帧所花费的时间,其中包括等待 VSync。 主线程上带有 WaitForTargetFPS 标记的示例显示等待 VSync 所花费的时间。 |
| Gfx.Process命令 | 包含渲染线程上渲染命令的所有处理。您的应用程序可能已经花费了一些处理时间等待VSync垂直同步 (VSync) 是一种显示设置,用于限制游戏的帧速率以匹配显示器的刷新率,以防止图像撕裂。 请参阅术语表或来自主线程的新命令,你可以从其子示例 Gfx.WaitForPresentOnGfxThread 中看到。 |
| Gfx.WaitFor命令 | 指示呈现线程已准备好接受新命令。如果您看到此标记,则可能表示主线程上存在瓶颈。 |
<GraphicsAPIName>.WaitForLastPresent例如:GfxDeviceD3D11.WaitForLastPresent GfxDeviceD3D12.WaitForLastPresent GfxDeviceMetal.WaitForLastPresent |
当主线程等待 GPU 将帧号翻转到屏幕 (Time.frameCount - QualitySettings.maxQueuedFrames + 1).这意味着,如果 QualitySettings.maxQueuedFrames 大于 1,则此时间将用于等待 GPU 翻转应用程序请求在上一个主线程帧中呈现的帧。有关此示例的更多详细信息以及 Unity 帧管道的概述,请参阅 Unity 关于修复增量时间的博客文章。 |
| Gfx.WaitForPresentOnGfx线程 | 指示主线程已准备好开始呈现下一帧,但呈现线程尚未完成等待 GPU 呈现帧。这可能表明您的应用程序受 GPU 绑定。要检查渲染线程同时花费时间的内容,请检查 CPU 性能分析器模块的时间轴视图。 如果渲染线程在 Camera.Render 中花费时间,则您的应用程序受 CPU 限制,并且可能花费过多时间向 GPU 发送绘制调用或纹理。 如果渲染线程将时间花在 Gfx.PresentFrame,则应用程序受 GPU 绑定,或者可能正在等待 GPU 上的垂直同步。一个WaitForTargetFPS子样本Gfx.WaitForPresentOnGfxThread表示应用程序等待 VSync 所花费的当前阶段部分。“当前”阶段是 Unity 指示图形 API 交换缓冲区到完成此作之间的时间部分。 |
| Gfx.等待渲染线程 | 指示主线程正在等待呈现线程处理其命令流中的所有命令。具有此标记的示例仅显示在多线程渲染中。 |
示例突出显示单色或IL2CPP Unity 开发的脚本后端,在为某些平台构建项目时,可以将其用作 Mono 的替代方案。更多信息
请参阅术语表 脚本后端为Unity中的脚本提供支持的框架。Unity 支持三种不同的脚本后端,具体取决于目标平台:Mono、.NET 和 IL2CPP。但是,通用 Windows 平台仅支持两个:.NET 和 IL2CPP。更多信息
请参阅术语表活动,对于解决垃圾回收和分配问题非常有用。
| 标记 | 描述 |
|---|---|
| GC。分配 | 表示托管堆中的分配,其中包含受自动垃圾回收约束的托管分配。若要减少应用程序在自动垃圾回收上花费的时间,应尽量减少这些类型的示例。 |
| GC。收集 | 表示与垃圾回收相关的示例。每当 Unity 需要执行垃圾回收时,它都会停止运行您的程序代码,并且只有在垃圾回收器完成所有工作后才会恢复正常执行。注意:如果启用了增量垃圾回收,则垃圾回收器可能无法在单个帧中完成其工作。 这种中断可能会导致应用程序执行延迟,持续时间从不到一毫秒到数百毫秒不等。这取决于垃圾回收器需要处理多少内存以及应用程序运行的平台。有关详细信息,请参阅有关了解自动内存管理的文档。 |
|
Mono.JIT 仅单声道 |
包含与脚本方法的实时编译相关的示例。当函数第一次执行时,Mono 会编译它,Mono.JIT 表示此编译开销。 |
| 不安全实用程序.Malloc | 包含调用 UnsafeUtility.Malloc 以分配非托管内存的示例。虽然垃圾回收器不跟踪此内存,但分配内存可能会对性能产生重大影响,如本示例所示。若要调查此调用的源,可以启用调用堆栈在运行时调用的方法列表,组织为后进先出堆栈。 请参阅术语表在“性能分析器”窗口中记录此标记。 |
这些标记包含的示例不测量消耗的 CPU 周期,而是突出显示与线程同步和作业系统相关的信息。看到这些示例时,请使用 CPU 探查器模块的时间轴视图同时检查其他线程上发生的情况。
| 标记 | 描述 |
|---|---|
| 怠 | 包含指示工作线程处于非活动状态的时间长度的示例。工作线程在作业系统不使用它时处于非活动状态,它会进入等待模式,在信号量上等待。 当作业系统唤醒它们时,通常会出现空闲样本之间的小间隙,例如,计划新作业。较长的间隙可能表示尚未检测的本机作业正在线程上运行。 |
| 作业处理.完成 | 包含指示作业同步点何时发生的样本。同步点可能会对应用程序产生性能影响,并可能干扰多线程作业代码的执行。若要更轻松地查找同步点发生的确切位置,请为此示例启用调用堆栈录制。在 CPU 性能分析器模块的时间轴视图中,您可以启用流事件以确定此时已完成的作业。 |
| 信号量.等待信号 | 包含描述线程上同步点的示例。若要查找它正在等待的线程,请检查“时间线”视图中是否有在此示例之前不久结束的示例。 |
| 等待作业组 ID | 触发了 JobHandle 上的同步围栏。这可能会导致工作窃取,当工作人员完成工作,然后查看其他工作人员的工作以完成时,就会发生这种情况。这些显示为在此标记下执行的作业示例。被盗的工作不一定是正在等待的工作。 |
下表概述了一些高级物理性能分析器标记。FixedUpdate调用所有这些测量值。
| 标记 | 描述 |
|---|---|
| Physics.Fetch结果 | 包含从中收集物理模拟结果的样本物理引擎模拟物理系统各个方面的系统,使物体能够正确加速并受到碰撞、重力和其他力的影响。更多信息 请参阅术语表,例如联系人流、触发器重叠和关节允许刚体组件之间进行动态连接的物理组件,通常允许一定程度的移动,例如铰链。更多信息 请参阅术语表破损事件。 |
| 物理插值 | 包含测量Physics.Interpolation方法。此方法管理应用程序中所有物理对象的位置和旋转插值。 |
| 物理处理 | 包含花费时间在主线程上等待直到所有线程的物理模拟完成的示例。如果您的应用程序在Physics.Processing但只有少数与物理相关的游戏对象Unity 场景中的基本对象,可以表示角色、道具、风景、相机、航路点等。游戏对象的功能由附加到它的组件定义。更多信息请参阅术语表在场景场景包含游戏的环境和菜单。将每个唯一的场景文件视为一个独特的关卡。在每个场景中,你放置你的环境、障碍物和装饰品,基本上是将你的游戏设计和构建成碎片。更多信息 请参阅术语表,这可能表明工作线程由于作业窃取而拾取了其他系统任务并报告为物理。这是因为在等待时,主线程会从高优先级队列中拾取作业。 |
| 物理加工布料 | 包含测量Physics.ProcessingCloth方法。此方法处理所有布料物理作业。展开此示例以显示物理系统内部完成的工作的低级细节。 |
| 物理.过程报告 | 包含与通过回调(如)将物理数据转发到脚本所花费的时间相对应的示例OnTriggerEnter.注意:这些示例不会计算所需的数据,因为它们已在FetchResults.有四个不同的阶段:
|
| 物理模拟 | 包含用于测量处理先决条件所花费的时间的示例Physics.Simulate方法。此方法指示物理系统运行其模拟,从而更新当前物理场的状态。 |
| 物理.更新身体 | 包含更新所有物理形体位置和旋转的示例。对于每个具有刚体允许游戏对象受到模拟重力和其他力影响的组件。更多信息 请参阅术语表组件,带有此标记的样本从物理系统读取姿势并将其写入变换。 |
| Physics.UpdateCloth | 包含测量Physics.UpdateCloth方法。此方法处理与布料及其蒙皮网格体相关的更新。 |
有关脚本生命周期和脚本生命周期中的常规示例的更多信息,请参阅事件函数的执行顺序。
下表包含动画系统中的标记。有关动画系统性能的一般信息,请参阅 Mecanim 性能和优化页面。
在此阶段,将处理每个处于活动状态并已启用的动画师。无论剔除模式和可见性如何,都会处理活动动画师。
以Director.还可以覆盖Playables(可玩资源)一种API,通过在称为PlayableGraph的树状结构中组织和评估数据源,提供一种创建工具、效果或其他游戏机制的方法。更多信息
请参阅术语表和时间线。
| 标记 | 描述 |
|---|---|
| Director.PrepareFrame (导演)准备帧 | 设置、安排和等待Director.PrepareFrameJob工作。这些作业评估状态机Animator 控制器中角色或动画游戏对象可以处于的状态集,以及这些状态之间的一组转换和用于记住当前状态的变量。可用的状态取决于游戏的类型,但典型的状态包括空闲、行走、奔跑和跳跃等。更多信息请参阅术语表适用于所有活跃的Animator 组件模型上的一个组件,使用动画系统为该模型设置动画。该组件具有对控制动画的 Animator 控制器资源的引用。更多信息 请参阅术语表. |
| Director.PrepareFrameJob(作业) | 评估单个活动动画器的状态机。处理 Animator 所需的时间随着其状态机的复杂性(即状态、过渡、属性和图层的数量)而增加。 使用 StateMachineBehaviours实现OnStateMachineEnter或OnStateMachineExit侦听器将被限制在主线程中。 |
| 动画师.PrepareFirstPass | 为接下来的处理步骤做准备。 |
| 动画师.ProcessGraphJob | 构建、计划和等待结果Animator.ProcessGraph工作。 |
| Animators.ProcessGraph(作业) | 计算所有连接的动画剪辑中的所有属性。 通过将所有剪辑的根运动属性混合在一起来计算根运动位移。 收集当前 deltaTime.在评估 AnimationClips 的属性时,曲线段会在帧之间本地缓存,以避免从 AnimationClips 的内存中读取过多的必要内容。 |
| 动画师.FireAnimationEvents和行为 | 全部开火动画事件允许您向导入的剪辑添加数据,以确定何时应与动画同步发生某些作。例如,对于动画角色,你可能希望将事件添加到步行和跑步循环中,以指示何时应播放脚步声。更多信息 请参阅术语表消息 StateMachineBehaviours和 MonoBehaviours,但OnStateMachineEnter或OnStateMachineExit已经被解雇的听众Director.PrepareFrameJob. |
| 动画师.ApplyOn动画师移动 | 应用根运动(root motion) 角色根节点的运动,无论它是由动画本身控制还是外部控制。更多信息 请参阅术语表并触发 OnAnimatorMove关于 MonoBehaviours 的消息。 |
在此阶段,只有具有剔除模式的动画师Always Update和具有剔除模式的可见动画师UpdateTransform或Cull Completely被处理。动画师Cull Completely被根运动移出框架的对象不参与此阶段。由 StateMachineBehaviours 和 AnimationEvents 触发的用户代码禁用的动画师也不会
| 标记 | 功能 |
|---|---|
| 动画师.PrepareSecondPass | 设置后续处理步骤。这包括根据动画师的剔除模式和可见性状态过滤掉动画师。 |
| 动画师.排序写入作业 | 变换系统一次只允许单个线程修改变换层次结构。为了适应这个约束,Animators.SortWriteJob组Animators.WriteTransformsjobs 由他们的 Transform.root 组成。为了获得最佳性能,请避免在同一变换层次结构中使用多个动画师,以增加可以调度和并行化作业的粒度。 |
| 动画师.ProcessAnimationsJob | 构建、计划和等待结果Animators.ProcessAnimations工作。 |
| Animator.ProcessAnimations(作业) | 混合单个动画器当前活动动画剪辑上的所有属性,根运动除外。将它们应用于内部头像表示。 此标记的长度随动画和混合复杂性而变化。 |
| OnAnimatorIK | 设置动画IK。每个动画师控制器(Animator Controller) 通过动画层控制动画,包括动画状态机和动画混合树,由动画参数控制。具有 Animator 组件的多个模型可以引用同一个 Animator 控制器。更多信息 请参阅术语表启用了IK通道的图层。 |
| 动画师.WriteJob | 构建、计划和等待结果Animator.WriteTransform工作。这些作业从动画编写变换姿势头像用于将动画从一个绑定重定向到另一个绑定的界面。更多信息请参阅术语表到相关的游戏对象转换层次结构。 |
| Animators.WriteTransforms(作业) | 将所有动画转换从工作线程写入场景。 |
| Animator.Write属性 | 将任何不是变换姿势的动画属性写入目标对象。 |
CPU 性能分析器会检测一些常见的性能问题,并向您发出警告。这些显示在模块详细信息窗格中 CPU 探查器模块的层次结构视图的警告列中。
探查器会检测一些在性能关键型上下文中要避免的特定调用。它显示警告以及作影响性能的原因,如下所示:
| 警告 | 描述 |
|---|---|
|
Animation.DestroyAnimationClip Animation.AddClip Animation.RemoveClip Animation.Clone Animation.Deactivate |
指示已触发 RebuildInternalState。RebuildInternalState 是一种作,它遍历动画组件中每个剪辑的曲线列表,然后将每条曲线重新绑定到游戏对象上组件上的值。 这是一项资源密集型作,因此应尽可能避免在运行时调用这些方法。 |
| 资产包.asset/allAssets | 表示 Unity 在 AssetBundle 加载未完成时调用了 AssetBundleRequest.assets/allAssets API(AssetBundleRequest.isDone 为 false)。这会导致主线程停滞并等待加载作完成。 |
|
AsyncUploadManager.AsyncBufferResized AsyncUploadManager.AsyncBufferDelete |
指示用于将数据上传到 GPU 的内部缓冲区已调整大小,因为它不够大。这种调整大小很慢,会导致 CPU 活动激增。 如果可以节省内存以预先分配更大的大小,则可以避免此警告。 您可以使用质量设置中的异步上传缓冲区大小设置来设置默认大小。 这 AsyncUploadManager.AsyncBufferResizedmarker 表示新分配的大小,您可以将其用作默认缓冲区大小的指南。 |
| 刚体.Set运动学 | 为刚体重新创建非凸面网格碰撞体。 |