Perfetto官方文档教你看CPU Scheduling events部分

背景

在学习Perfetto/sf部分课程时候,经常分析一些问题时候会会涉及到线程的状态是running,sleep等情况。经常就需要看Perfetto的cpu部分的片段。
在这里插入图片描述那么cpu片段这块的信息到底如何看呢?今天带大家来看看官方文档是如何教我们看CPU Scheduling events部分内容的。

CPU Scheduling events

On Android and Linux Perfetto can gather scheduler traces via the Linux Kernel ftrace infrastructure.

This allows to get fine grained scheduling events such as:

Which threads were scheduled on which CPU core at any point in time, with nanosecond accuracy.

The reason why a running thread got descheduled (e.g. pre-emption, blocked on a mutex, blocking syscall or any other wait queue).

The point in time when a thread became eligible to be executed, even if it was not put immediately on any CPU run queue, together with the source thread that made it executable.

在 Android 和 Linux 上,Perfetto 可以通过 Linux 内核的 ftrace 基础设施收集调度器跟踪数据。

这允许我们获取细粒度的调度事件,例如:

a.在任何时间点,哪些线程被调度到了哪个 CPU 核心上运行,精度达到纳秒级。

b.正在运行的线程被取消调度(descheduled)的原因(例如,被抢占、在互斥锁上阻塞、阻塞式系统调用或任何其他等待队列)。

c.线程何时变得有资格执行(即使它没有立即被放入任何 CPU 运行队列),以及使其可执行的源线程(source thread)。

UI 展示

UI 将单个调度事件表示为切片(slices):
在这里插入图片描述Clicking on a CPU slice shows the relevant information in the details panel:

点击一个 CPU 切片会在详情面板中显示相关信息:
在这里插入图片描述
Scrolling down, when expanding individual processes, the scheduling events also create one track for each thread, which allows to follow the evolution of the state of individual threads:

向下滚动,在展开单个进程时,调度事件也会为每个线程创建一个轨道(track),从而可以跟踪单个线程状态的演变:
在这里插入图片描述

SQL

在 SQL 层面,调度数据暴露在 sched_slice
At the SQL level, the scheduling data is exposed in the sched_slice table.

select ts, dur, cpu, end_state, priority, process.name, thread.name
from sched_slice left join thread using(utid) left join process using(upid)

在这里插入图片描述

TraceConfig

To collect this data, include the following data sources:
要收集此数据,请在 TraceConfig 中包含以下数据源:

# Scheduling data from the kernel.
data_sources: {
  config {
    name: "linux.ftrace"
    ftrace_config {
      compact_sched: {
        enabled: true
      }
      ftrace_events: "sched/sched_switch"
      # optional: precise thread lifetime tracking:
      ftrace_events: "sched/sched_process_exit"
      ftrace_events: "sched/sched_process_free"
      ftrace_events: "task/task_newtask"
      ftrace_events: "task/task_rename"
    }
  }
}

# Adds full process names and thread<>process relationships:
data_sources: {
  config {
    name: "linux.process_stats"
  }
}

Scheduling wakeups and latency analysis

调度唤醒与延迟分析

By further enabling the following in the TraceConfig, the ftrace data source will record also scheduling wake up events:
通过在 TraceConfig 中进一步启用以下事件,ftrace 数据源还将记录调度唤醒事件:

  ftrace_events: "sched/sched_wakeup_new"
  ftrace_events: "sched/sched_waking"

While sched_switch events are emitted only when a thread is in the R(unnable) state AND is running on a CPU run queue, sched_waking events are emitted when any event causes a thread state to change.
sched_switch 事件仅在线程处于 R(可运行) 状态且正在 CPU 运行队列上运行时发出,而 sched_waking 事件则在任何导致线程状态改变的事件发生时发出。
Consider the following example:
考虑以下示例:

Thread A
condition_variable.wait()
                                     Thread B
                                     condition_variable.notify()

When Thread A suspends on the wait() it will enter the state S(sleeping) and get removed from the CPU run queue. When Thread B notifies the variable, the kernel will transition Thread A into the R(unnable) state. Thread A at that point is eligible to be put back on a run queue. However this might not happen for some time because, for instance:

All CPUs might be busy running some other thread, and Thread A needs to wait to get a run queue slot assigned (or the other threads have higher priority).

Some other CPUs other than the current one, but the scheduler load balancer might take some time to move the thread on another CPU.

Unless using real-time thread priorities, most Linux Kernel scheduler configurations are not strictly work-conserving. For instance the scheduler might prefer to wait some time in the hope that the thread running on the current CPU goes to idle, avoiding a cross-cpu migration which might be more costly both in terms of overhead and power.

NOTE: sched_waking and sched_wakeup provide nearly the same information. The difference lies in wakeup events across CPUs, which involve inter-processor interrupts. The former is always emitted on the source (wakee) CPU, the latter may be executed on either the source or the destination (waked) CPU depending on several factors. sched_waking is usually sufficient for latency analysis, unless you are looking into breaking down latency due to the scheduler’s wake up path, such as inter-processor signaling.

当线程 A 在 wait() 上挂起时,它将进入 S(睡眠) 状态并从 CPU 运行队列中移除。当线程 B 通知条件变量时,内核会将线程 A 转换到 R(可运行) 状态。此时线程 A 有资格被放回运行队列,但这可能不会立即发生,原因如下:

所有 CPU 可能正忙于运行其他线程,线程 A 需要等待获得运行队列位置(或其他线程具有更高优先级)

除了当前 CPU 外,调度器负载均衡器可能需要一些时间将线程迁移到其他 CPU

除非使用实时线程优先级,大多数 Linux 内核调度器配置并非严格的工作保守型。例如,调度器可能宁愿等待一段时间,希望当前 CPU 上运行的线程进入空闲状态,从而避免跨 CPU 迁移,这在开销和功耗方面可能代价更高

注意:sched_waking 和 sched_wakeup 提供几乎相同的信息。区别在于跨 CPU 的唤醒事件,这涉及处理器间中断。前者总是在源(唤醒者)CPU 上发出,后者可能根据多种因素在源或目标(被唤醒者)CPU 上执行。对于延迟分析,sched_waking 通常已足够,除非您正在研究调度器唤醒路径(如处理器间信令)导致的延迟分解。

When enabling sched_waking events, the following will appear in the UI when selecting a CPU slice:
当启用 sched_waking 事件后,在 UI 中选择 CPU 切片时将显示以下信息:
在这里插入图片描述

Decoding end_state(解读end_state)

The sched_slice table contains information on scheduling activity of the system:
sched_slice 表包含了系统的调度活动信息:

> select * from sched_slice limit 1
id  type        ts          dur    cpu utid end_state priority
0   sched_slice 70730062200 125364 0   1    S         130   

Each row of the table shows when a given thread (utid) began running (ts), on which core it ran (cpu), for how long it ran (dur), and why it stopped running: end_state.

end_state is encoded as one or more ascii characters. The UI uses the following translations to convert end_state into human readable text:

表中的每一行显示了特定线程(utid)开始运行的时间(ts)、在哪个核心上运行(cpu)、运行了多长时间(dur),以及它停止运行的原因:end_state。

end_state 编码为一个或多个 ASCII 字符。UI 使用以下转换规则将 end_state 转换为人类可读的文本:

在这里插入图片描述在这里插入图片描述

Not all combinations of characters are meaningful.

If we do not know when the scheduling ended (for example because the trace ended while the thread was still running) end_state will be NULL and dur will be -1.
并非所有的字符组合都具有实际意义。

如果我们无法确定调度何时结束(例如,由于跟踪结束时线程仍在运行),则 end_state 将为 NULL,且 dur 将为 -1。

官方文档地址:https://perfetto.dev/docs/data-sources/cpu-scheduling

<think> 我们正在讨论的是Perfetto UI中CPU Scheduling轨道组的位置问题。根据用户之前的提问和引用内容,我们需要指导用户在Perfetto UI中找到CPU Scheduling轨道组的具体位置。 步骤: 1. 打开Perfetto UI (https://ui.perfetto.dev/) 2. 加载一个trace文件(如果没有,可以录制一个新的或者上传一个已有的) 3. 在左侧的轨道列表中查找“CPU Scheduling”轨道组。 根据引用[1]和引用[2]的内容,我们知道Perfetto中确实有CPU Scheduling轨道组,并且它是分析CPU调度的重要工具。 具体位置: - 在Perfetto UI的左侧,有一个垂直的轨道列表(Track List),通常按类别分组。 - 首先,你可能会看到一些系统级别的轨道,如“CPU”、“GPU”、“内存”等。 - 在“CPU”类别下,通常会有一个名为“CPU Scheduling”的轨道组(可能被折叠)。 - 点击“CPU Scheduling”旁边的三角形图标可以展开它,看到每个CPU核心的调度详情。 注意:如果trace文件中没有捕获到CPU调度事件,那么这个轨道组可能不会出现。确保在录制trace时启用了sched_switch事件(如引用[1]所提到的)。 另外,引用[2]中提到,右上角的processes可以过滤进程,以及一些快捷操作(如放大、缩小、左右移动等)可以帮助查看。 操作步骤: 1. 打开Perfetto UI并加载trace文件。 2. 在左侧轨道列表中找到“CPU部分,然后找到“CPU Scheduling”轨道组(通常在CPU频率轨道下方)。 3. 如果找不到,可以尝试使用搜索框(在轨道列表上方)输入“CPU Scheduling”进行搜索。 如果用户还没有trace文件,可以参考引用[3]中提到的使用电脑连接设备录制trace的方法。 现在,我们按照要求生成回答,并注意数学公式的格式(但本问题可能不涉及数学公式,所以如果有公式则按格式,没有则不写)。同时,在末尾生成相关问题。 注意:引用标识放在引用内容的末尾,例如:[^1] </think>在 Perfetto UI 中查找 **CPU Scheduling 轨道组**的具体位置如下: ### 🔍 具体位置与操作步骤 1. **加载 Trace 文件后** - 在左侧 **垂直轨道列表**(Track List)中滚动查找 - 定位到 **`Scheduling` 类别**(通常位于列表中部或中上部) 2. **层级结构** ```mermaid graph LR A[Scheduling] --> B[CPU Scheduling] B --> C[CPU 0] B --> D[CPU 1] B --> E[...] B --> F[CPU N] ``` 3. **展开轨道组** - 点击 `CPU Scheduling` 左侧的 **▸ 三角图标** 展开核心列表 - 每个 CPU 核心会显示独立的调度轨道: - **彩色条带**:表示线程运行状态 - `绿色`:Running(正在执行) - `蓝色`:Runnable(可运行但未调度) - `白色`:休眠/阻塞状态 - **标签**:显示进程/线程名 ### 📌 定位技巧 1. **快速搜索** - 在轨道列表顶部的 **搜索框** 输入 `cpu_scheduling` 直接定位[^2] 2. **键盘导航** - 按 `F` 键自动聚焦到 CPU 使用率最高的核心轨道 - 按 `W/S` 键垂直滚动轨道列表 3. **视觉标识** - 该轨道组通常有 **芯片图标** 🖥️(不同版本可能略有差异) - 位于 `Power Management` 轨道组下方,`Irq Events` 轨道组上方 > ⚠️ 若未显示:需确保 trace 文件捕获了调度事件(配置时勾选 `sched/sched_switch` 事件)[^1] ### 🖼️ 界面示意图 ``` [Perfetto UI 左侧面板] ├─── Memory ├─── Power Management ├─── ▼ Scheduling <-- 目标父级分类 │ ├── CPU Scheduling <-- 目标轨道组(可展开) │ │ ├── CPU 0 │ │ ├── CPU 1 │ │ └── ... │ └── IRQ Events └─── GPU ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值