编辑
2026-04-19
记录知识
0

目录

打开 Perfetto UI
调度全景图
Ftrace Events
调度关键指标
Runnable Thread Count(可运行线程数)
Uninterruptible Sleep Thread Count(不可中断睡眠线程数)
Active CPU Count(活跃 CPU 数)
Clock Snapshots
自定义data source
单一进程视角调度状态
快捷键介绍
导航操作
选择操作
分析操作
单事件选择
区域选择
SQL 查询
固定Track
总结
参考资料

之前详细的介绍了perfetto抓取日志的办法,这些办法都会获得一个pftrace的文件,我们只需要将这个文件在https://ui.perfetto.dev 加载即可显示。本文介绍可视化UI的一些基础使用办法

打开 Perfetto UI

image.png

默认界面如上,我们只需要点击 Open trace file 将perfetto/tracebox抓到的日志上传上去即可

调度全景图

以调度轨迹为例的一张视图如下,我们先看CPU Scheduling 这行,这是sched_switch的事件,代表整个系统上的调度情况。这些sched_switch的事件的组成就是 CPU 调度全景图

image.png

可以看到这里有16个核心,从粗的角度来看,CPU6,7,8,2,10,14,5几个CPU上运行的任务事件比较密集,我们大概知道当前系统环境的性能状态

Ftrace Events

Ftrace Events代表者ftrace提供的信息,这是原始ftrace ring buffer的信息,因为这份日志抓的是调度轨迹,所以我们只看到了sched_wakeup(蓝色)和sched_switch(黄色)的信息,也就是任务什么时候被唤醒,什么时候切换

image.png

调度关键指标

Scheduler行提供了调度的关键指标的折线图显示如下

image.png

Runnable Thread Count(可运行线程数)

当前有多少线程处于R状态,因为Linux不区分runable和running的状态标记,所以这是 所有 CPU 上正在跑的线程 + 等待被调度的就绪队列线程。

  • 值持续很高 → 线程太多,CPU 竞争激烈
  • 突然飙高 → 可能有大量线程被同时唤醒

在我这个例子里面,可以看到当前调度状态非常空闲,因为max是1

Uninterruptible Sleep Thread Count(不可中断睡眠线程数)

这是影响调度的关键指标,不可中断线程就是D状态的线程,也就是正在等待 I/O、磁盘、网络等不可中断的操作

通常为 磁盘IO/网络IO/锁

  • 值持续 > 0:说明系统有 I/O 瓶颈
  • 值突然升高:可能是某个线程在做大量 I/O
  • 值很高但 CPU idle:可能是磁盘满了或网络卡了

在这个例子里面,可以看到我后台有多个claude在运行,所以max是3,这个3大概率全是磁盘IO状态的线程

Active CPU Count(活跃 CPU 数)

所谓活跃的cpu计数,其实就是非 idle 的 CPU 核心数,在统计的时候非常简单,就是总CPU减去swapper即可

  • Active CPU = 总 CPU 数 - 运行 swapper/N 的 CPU 数

在我这个例子里面,max是14,说明这段时间最大调动了14个cpu工作,但绝大部分情况下是0,说明系统非常空闲

Clock Snapshots

这是 记录 trace 中不同data source 的时钟基准

image.png

我们之前提过,perfetto是生产者消费者模型,那么生产者可以多个,也就意味着时钟源也是多个,但是我们想要的是系统性分析性能问题,perfetto做了时钟同步规则,就是通过 Clock Snapshots 来实现

例如:

  • ftrace 的 sched_switch 事件:ts=1776586699190768428 (REALTIME)
  • trace_event 的 DrawGame 事件:ts=2398626394976745 (BOOTTIME)

通过 Clock Snapshots 中的对照关系,Perfetto 可以换算成统一的时间轴进行对比。

在我这个例子里面,是记录了BOOTTIME,perfetto默认支持如下几类事件

  • BOOTTIME: clock_gettime(CLOCK_BOOTTIME),包含睡眠时间
  • REALTIME: clock_gettime(CLOCK_REALTIME),墙上时间
  • TAI: 原子钟时间,不跳变
  • MONOTONIC: CLOCK_MONOTONIC,不含系统睡眠
  • SCHEDCLOCK: 内核 sched_clock,每个 CPU 不同
  • CGLAST: cgroup last-update 时钟

当然,也支持自定义的时间戳统一, 如果 trace 配置了 allow_all_kernel_clocks: true,Perfetto 会自动把不同数据源的时间转换到同一个时钟基准。

简单来说,我们不需要担心时间不统一的情况,perfetto ui 内部做好了对齐

自定义data source

通过sdk内嵌到程序代码的slice也可以一并查看,下面是自定义data source(实际复用了perfetto原生 trace event)的信息,每个长条都是一个slice块

image.png

单一进程视角调度状态

perfetto会抓取单一视角的调度状态,分为runable和running状态,下图是以claude本身的调度情况

image.png

如果我们放大,可以看到进程的详细状态信息,例如什么时刻出现了 Uninterruptible Sleep

image.png

如果我们点击空白处,就是进程sleep的时间

image.png

快捷键介绍

导航操作

快捷键功能说明
W放大沿时间轴放大
S缩小沿时间轴缩小
A左移向左平移时间线
D右移向右平移时间线
Shift + 拖拽鼠标平移按住 Shift 拖拽平移
Ctrl + 滚轮鼠标缩放滚轮放大缩小

选择操作

快捷键功能说明
点击选择事件点击 slice 查看详情
.下一个 slice跳到同一轨道的下一个事件
,上一个 slice跳到同一轨道的上一个事件
F聚焦选中事件将选中事件居中显示;再按 F 适配视口
R转为面积选择将当前选中事件转为面积选择
Escape清除选择取消所有选择

分析操作

上面都是简单粗略的查看了系统的性能状态,下面简单介绍一下如何初步分析

单事件选择

如果我点击任意的进程内的slice,可以详细的看到这个进程此时的信息,如下

点击任意 slice,底部 "Current Selection" 标签显示:

image.png

对于ftrace,可以获取ftrace的原始数据信息,这对调试内核的同学来说应该再熟悉不过了

image.png

区域选择

直接鼠标在上面拉框就可以看到一段区域的统计信息,如果当前模式不在选择模式,可以使用快捷键R转到面积选择

image.png

我选中了前7个核的2.68s时间,可以看到下面的统计 snap 在这7个核心上运行了87ms,平均运行时间是378.9us

如果我们要看整个声明周期的,按下ctrl+a可以统计,我们统计claude进程的进程状态如下

image.png

可以看到claude运行了353us,sleep了14.68ms,runable状态是34.17us。可以看到系统非常空闲

SQL 查询

Perfetto的精髓在于能够sql查询,这里先简单的演示如何快速sql。我们直接在顶部输入栏输入

: select * from slice

这会查找所有的slice

image.png

可以看到快速的找到了我自定义程序的slice片段

固定Track

根据上面描述的信息,我可以统计所有的running状态

: select * from thread_state where state like "%running%"

现在可以自定义一个Track proc_sum,如下

image.png

通过这个track可以获取到所有cpu的running状态的统计,如下

image.png

我们可以选择一个比较密集的状态,查看哪些cpu在运行,如下

image.png

总结

本文详细介绍了perfetto ui的使用办法,掌握这些技巧就可以初步的看到系统的性能状态,接下来详细介绍SQL进行trace分析

参考资料