Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

CPU Usage

一、什么是CPU Usage

CPU Usage(使用率)
是 Unity Profiler 中最重要的性能分析模块之一用于展示 每一帧 CPU 所花费的时间,按类别详细划分不同系统的消耗情况,帮助开发者诊断性能瓶颈

游戏开发中会造成CPU开销的主要有:

  1. 脚本逻辑(我们编写的C#代码逻辑)
  2. 物理系统(unity内置的物理引擎
  3. 动画计算(unity中的动画状态机、骨骼动画相关的混合采样计算等等 )
  4. 渲染准备(计算物体是否可见、是否剔除、构建绘制命令,渲染命令提交工作等),资源管理和加载(加载 AssetBundle、场景、纹理、网格、材质等元数据 等)
  5. Gc(垃圾回收)
  6. UI系统(GUI、UGUI中UI 布局计算、事件派发、渲染数据的准备等)
  7. 导航与寻路
  8. 音频处理
  9. 输入检测
  10. 网络通讯
  11. 屏幕后处理C#部分

一般项目出现卡顿、掉帧问题可以着重排查此处

二、各个参数功能及其含义

1.分析窗口

分析窗口

在这里通过不同模块不同颜色表达,我们可以直观的看到每一个模块对CPU的使用情况

  • Rendering: 花费多少时间准备渲染命令,如Camera.Render、DrawCalls 生成阶段
  • Scripts: 花费多少时间执行 C# 脚本(如 Update、Start、协程)
  • Physics: 花费多少时间进行物理计算,包括碰撞检测、刚体模拟(2D/3D)
  • Animation: 花费多少时间处理动画相关,比如带有蒙皮网格渲染器(Skinned MeshRenderers)、Animation、Animator等等和动画相关的组件
  • GarbageCollector: 花费多少时间处理GC(垃圾回收),即GC垃圾回收造成的性能抖动
  • VSync: 花费多少时间等待垂直同步完成(可能会造成卡帧)
  • Global lLLumination: 花费多少时间来处理实时全局光照
  • UI: 花费多少时间来处理U相关,比如Canvas 更新、重建、批处理等 U 绘制任务
  • Others: 花费多少时间来处理不属于上述模块的其他任务,比如Unity编辑器本身的消耗或未分类的任务或引擎底层消耗

其中的竖线中的数值用不同颜色表示各部分耗时, 用于帮助你直观的看到当前帧消耗是否超过了目标帧率允许的上限
其中的横线 - 66ms(15FPS) - 33ms(30FPS) - 16ms(60FPS)

2.详细数据的四种视图

详细数据的四种视图

注意点: - TimeLine在视图中可以显示所有线程的性能分析数据 - Hierarchy只能在视图中显示一个线程的性能分析数据,需要我们手动切换线程

1.)TimeLine

TimeLine(时间线视图): 显示特定帧的时间细分信息,以及该帧长度的时间轴, - 显示方式
横向时间轴,按线程显示每个函数的开始与持续时间,精确到每个调用片段。 - 结构
一个横轴 = 一帧时间,纵轴 = 不同线程(Main Thread、 Render Thread 等) - 用途
看每个函数调用在时间上所占的位置和长度清楚显示函数调用之间是否并发/串行非常适合排查 主线程阻塞、线程切换耗时 等问题

具体参数介绍 具体参数介绍

  • Main Thread:
    主线程,运行大部分游戏逻辑,包括脚本、物理、染提交等
  • Render Thread:
    渲染线程,负责将染命令提交给 GPU(通常异步进行)
  • Job:Unity Job System
    调度的多线程任务(用于并行计算)
  • Loading:
    资源加载线程,例如异步读取纹理、场景、AssetBundle等
  • Scripting Threads:
    非主线程的 C# 脚本线程(例如自定义后台线程)等等

主要构成: - Live :
开启后可在模块详细信息面板中显示有关当前帧或选定帧的信息,关闭后,只有选择一时才会显示 - 彩色横条块: 1. 每个条代表一个采样事件(采样函数/操作) 2. 宽度表示执行耗时,颜色表示模块类别(Scripts、Rendering 等) 3. 悬浮时显示名称和耗时,如 Profiler.Flushcounters(0.046ms) - Show Full Scripting Method Names:
显示完整的脚本方法名称 - Show Flow Events:
显示线程间异步任务的调用路径(比如 Job 与 Main Thread 的联系线)

使用建议: 1. 多线程性能分析(例如:Job 执行耗时) 2. 追踪跨线程任务顺序(例如:资源加载 → 渲染) 3. 视觉化查看整帧分布结构

2.)Hierarchy

Hierarchy(层级视图): 按时间数据的内部层级结构对这些数据分组 - 显示方式:
以调用栈的方式展示函数调用结构,从根函数一路展开 - 结构:
每一行是一个函数调用,子函数缩进在其下方 - 用途:
快速发现“树顶函数”调用最多的分支定位哪一个函数调用下挂着最多性能开销

具体参数介绍 Hierarchy

  • Live:
    开启后可在模块详细信息面板中显示有关当前帧或选定帧的信息,关闭后,只有选择一帧时才会显示
  • Main Thread:
    主线程,可以在此处切换检测的线程
  • Total:
    占该帧总时间的百分比,表示当前函数(含其所有子函数)总耗时占该帧总耗时的百分比。通常用来判断“这一支调用链是否值得深挖"
  • Self:
    占该帧总时间的百分比,不包含Unity调用子函数所花费的时间
    比如:某个函数花费大量时间去执行。但是是因为它调用了大量的系统的 绘制 和 剔除 函数。但是,当您排除它调用的函数的样本时,只有 0.2% 的时间花在该函数本身上可用于判断函数本身是否耗时大
  • Calls:
    在此帧中该函数的调用次数
    高调用频率可能是性能瓶颈的来源
  • GC Alloc:
    此函数在该帧中触发的 GC 内存分配量(单位:Byte),过高可能导致频繁 GC
  • Time ms:
    当前函数(含子函数)在该帧的总耗时,单位是毫秒。
  • Self ms:
    在该帧中自身花费的总时间,不包含Unity调用子函数所花费的时间
  • EditorLoop:
    Unity编辑器运行时的主循环(非Play模式下),编辑器中的各面板更新,UI重绘资源导入,编译,插件逻辑等等都会在该循环中执行
  • PlayerLoop:
    游戏运行时的主循环,几乎所有的游戏逻辑、染、物理、输入、协程、动画等等都在这个循环中执行,展开后,就是在该次循环中执行的函数相关信息

观察建议: 1. 总耗时高但 Self ms 低;说明慢在子函数里,应该点开看下层函数 2. Self ms 高;当前函数本身有问题,如密集计算或阻塞 3. Calls 很高;是否有不必要的循环调用?应考虑合并或缓存 4. GC Alloc 明显;是否频繁 new 对象或字符串拼接?可能造成 GC

详细信息视图 详细信息视图

  • No Details:
    无详细信息 不显示任何额外信息,仅显示左侧的函数调用树及其时间、GC、调用次数等
  • Related Data:
    相关数据;显示与当前选中函数相关的上下文信息、内联事件(Markers)、线程关联、调用位置的上下文,这个对分析线程间协作和事件调度有帮助,但使用较少
  • Calls:
    “调用”视图显示了所选示例的调用来源以及它调用的其他函数。用于分析该函数是在哪个逻辑路径下被调用的,可以帮助你定位谁在调用它,尤其在频繁调用的函数追溯调用源时很实用

使用建议: 1. 只关心函数耗时,使用No Details即可 2. 想找出某函数是被谁调用,使用Calls 3. 想看函数在不同线程或上下文的分布,,使用Related Data

3.)Inverted Hierarchy

Inverted Hierarchy(倒置层级视图): 按分析器标记对样本进行分组,并用倒置的样本堆栈显示它们。 - 显示方式:
将调用树倒过来看,从最底层函数反推“是哪些函数调用了它” - 用途:
用于分析一个具体函数被 谁频繁调用常用于调试“这个慢函数为什么会被频繁触发”的问题和 Hierarchy(层级视图)是互补关系

4.Raw Hierarchy

Raw Hierarchy(原始层级)以类似于发生计时的调用栈的层级结构显示时间数据 - 显示方式:
不做任何聚合和折叠处理,展示 完整原始采样数据 - 用途:
查看完整调用链更贴近采样器采集的真实结构,但可能非常几长复杂

三、CPU Usage的使用意义

  1. 找CPU性能瓶颈
    查看每帧中哪个模块耗时异常(颜色块明显突起)快速定位卡顿来源,哪帧卡了、哪个模块卡了
  2. 找性能抖动
    检査 GC 是否频繁(黄色峰值)
    还是某个帧的脚本逻辑执行消耗过大(蓝色占比高)
  3. 找优化依据
    明确是脚本、渲染、物理还是 vSync(垂直同步)等模块引起的卡顿
  4. 帧率诊断
    对比 16ms(60FPS)/33ms(30FPS)标尺,判断是否达标

四、垂直同步为什么会影响帧率,如何设置

显示器通常以固定的频率刷新画面(如 60Hz 表示每秒刷新 60 次,,每帧 16.67ms)而显卡渲染图像的速度通常不固定,有时快于显示器刷新,有时慢于

垂直同步(vsync)会强制显卡处理 1. 等显示器准备好再提交新帧(即等一次“垂直回扫”信号),避免屏幕撕裂 2. 如果显卡渲染太快,它要等一等 3. 如果渲染太慢,它只能跳过一帧,延后一轮提交

影响帧率主要有两种情况 1. 帧率略高于刷新率 → 强制等待
比如显卡渲染能力是 90FPS,而显示器是 60Hz;VSync 开启后,GPU 只能 每 16.67ms 渲一帧 → 被“卡”在60FPS 2. 帧率低于刷新率 → 被“降档”处理
比如显卡当前只能 50FPS,VSync 要求必须整除刷新频率,于是 GPU 被“降档”到 30FPS(60Hz/2)这会造成严重卡顿或掉帧感

何时开关

  • 开发调试时:通常关闭 vsync 观察真实的 GPU 性能瓶颈
  • 低端机运行卡顿时:关闭 vsync 可减少帧率锁死卡顿
  • 正式发包时:一般开启 vsync 防止撕裂(尤其是主机或高帧率设备)
  • 交给玩家在设置中进行设置

如何设置

  1. 代码控制 QualitySettings.vSyncCount = 0;
    • 0:关闭垂直同步
    • 1:每帧同步
    • 2:隔一帧同步
  2. 编辑器中设置
    Edit > Project Settings > Quality
    • Ddn'tsync(0)即:可关闭
    • VSyncEveryV Blank(1):每次垂直同步(默认)
    • Every Second V Blank(2):隔一帧同步(更低帧率)

评论