Perfetto实战:如何用SQL查询揪出CPU调度延迟的元凶(附完整查询模板)
当你的Android应用出现卡顿或系统响应迟缓时,CPU调度延迟往往是幕后黑手。本文将带你深入Perfetto的SQL分析能力,通过实战案例教你如何量化延迟分布、定位高延迟线程,并区分自愿与非自愿上下文切换。
1. 理解CPU调度延迟的核心指标
CPU调度延迟指的是线程从"可运行"状态到实际获得CPU执行权之间的时间差。这个看似简单的指标背后隐藏着复杂的系统行为:
- Runnable状态(R):线程已准备好执行,但尚未被调度器选中
- Running状态:线程正在CPU上执行指令
- Sleeping状态(S):线程主动放弃CPU(如等待I/O)
- Uninterruptible Sleep(D):线程因内核操作被阻塞
关键延迟类型:
-- 调度延迟 = 唤醒时间到实际运行时间的差值
SELECT
waking.ts AS wakeup_ts,
slice.ts AS schedule_ts,
(slice.ts - waking.ts) / 1e6 AS latency_ms
FROM sched_slice slice
JOIN sched_waking waking ON slice.utid = waking.utid
2. 配置Trace捕获关键调度事件
正确的Trace配置是分析的基础。以下配置可捕获完整的调度信息:
data_sources {
config {
name: "linux.ftrace"
ftrace_config {
compact_sched: { enabled: true }
ftrace_events: "sched/sched_switch"
ftrace_events: "sched/sched_waking"
ftrace_events: "sched/sched_wakeup"
}
}
}
data_sources {
config {
name: "linux.process_stats"
}
}
关键事件说明:
| 事件类型 | 触发条件 | 数据分析价值 |
|---|---|---|
| sched_switch | 线程被换出CPU时 | 查看线程执行时长和退出原因 |
| sched_waking | 线程被标记为可运行时 | 计算调度延迟的起点 |
| sched_wakeup | 线程被实际唤醒时 | 跨CPU唤醒分 |

1375

被折叠的 条评论
为什么被折叠?



