4. perf sched子命令概览
perf sched 是 perf 工具集中专用于进程调度延迟分析的子命令集合。它通过内核 tracepoint 捕获调度事件,提供从数据采集、延迟量化到可视化回放的全链路分析能力。本节将逐一介绍 perf sched record、latency、map、replay、diff 等核心子命令的功能定义、输出格式与典型适用场景。
4.1 子命令全景图
以下 SVG 展示了 perf sched 子命令的完整工作流与数据流向关系:
4.2 子命令功能详解
4.2.1 perf sched record — 调度事件采集
该子命令是调度分析的起点,通过启用调度器相关的 tracepoint 事件来记录进程的创建、唤醒、切换和迁移行为。默认采集的事件包括:
sched:sched_switch— 进程上下文切换sched:sched_wakeup/sched:sched_wakeup_new— 进程唤醒sched:sched_migrate_task— 进程跨 CPU 迁移sched:sched_process_fork/sched:sched_process_exit— 进程创建与退出
典型用法:
# 采集 10 秒调度事件,默认输出到 perf.data
perf sched record -- sleep 10
# 指定输出文件,便于后续对比
perf sched record -o sched_A.data -- stress --cpu 4 --timeout 5
适用场景:任何调度延迟分析的起点。建议在负载稳定后采集 30 秒以上数据,避免冷启动噪声。采集期间应避免
perf 自身被调度出去,可考虑绑定到隔离 CPU。
4.2.2 perf sched latency — 调度延迟统计
该子命令解析 perf.data,计算每个进程的调度延迟指标,并以表格形式输出。核心指标包括:
| 指标 | 含义 | 单位 |
|---|---|---|
| wait-time | 进程从被唤醒到获得 CPU 的平均等待时间 | ms |
| sch-delay | 调度器决策延迟(从唤醒到调度器选择该进程) | ms |
| run-delay | 进程就绪但未运行的时间(含等待队列排队) | ms |
| max-delay | 单次调度延迟最大值 | ms |
典型用法:
# 输出所有进程的调度延迟统计
perf sched latency
# 按延迟降序排列,快速定位异常进程
perf sched latency --sort max
输出解读要点:重点关注
wait-time 和 max-delay 偏高的进程。若某进程的 max-delay 超过 10ms,通常意味着存在调度延迟问题。结合 --sort max 可快速锁定最差进程。
4.2.3 perf sched map — 时间轴上下文切换可视化
该子命令将调度事件转换为基于时间轴的 ASCII 图表,展示每个 CPU 上运行的进程随时间的变化。每一列代表一个时间片,每一行代表一个 CPU 核心,字符表示在该时间片内运行的进程名称缩写。
典型用法:
# 生成上下文切换时间轴
perf sched map
# 指定时间窗口,聚焦问题区间
perf sched map --time 2.0,5.0
输出示例(示意):
*A0 A0 B1
*. . .
. *B1 B1 C2
. . . .
. . *C2 C2 A0
-------------------------------------------------
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7
适用场景:当
latency 报告显示某进程延迟异常时,使用 map 查看该进程在时间轴上的实际调度序列,判断是否存在 CPU 负载不均、频繁迁移或优先级反转。
4.2.4 perf sched replay — 调度过程模拟回放
该子命令将采集到的调度事件重新模拟执行,测量在理想条件下(无外部干扰)的调度延迟,并与实际采集的延迟进行对比。它通过重放调度序列来评估调度器本身的效率。
典型用法:
# 执行调度回放,输出模拟延迟
perf sched replay
# 指定回放次数,取平均结果
perf sched replay --repeat 3
输出关键字段:
| 字段 | 说明 |
|---|---|
| nr_run_events | 回放过程中处理的调度事件总数 |
| nr_sleep_events | 进程睡眠事件数 |
| nr_wakeup_events | 进程唤醒事件数 |
| target-less wakeups | 无明确目标 CPU 的唤醒次数(可能暗示负载均衡问题) |
| average delay | 回放模拟的平均调度延迟 |
注意事项:回放结果依赖于采集时的调度序列,如果系统负载在采集期间剧烈变化,回放结果可能与实际偏差较大。建议在稳定负载下采集数据,并多次回放取均值。
4.2.5 perf sched diff — 两次实验差异对比
该子命令对比两次 perf sched latency 的输出结果,生成差异报告。常用于验证调优措施的效果,例如对比调优前后的调度延迟变化。
典型用法:
# 对比调优前后的延迟数据
perf sched diff perf_before.data perf_after.data
# 只显示变化超过 5% 的进程
perf sched diff --percentage 5 perf_before.data perf_after.data
输出格式示例:
# wait-time (ms) sch-delay (ms) run-delay (ms)
# process before after diff before after diff before after diff
stress-1234 2.34 1.12 -52.1% 1.87 0.95 -49.2% 3.21 1.45 -54.8%
kworker-56 0.45 0.48 +6.7% 0.32 0.35 +9.4% 0.78 0.82 +5.1%
最佳实践:在进行内核参数调优(如
kernel.sched_min_granularity_ns、kernel.sched_wakeup_granularity_ns)前后各采集一次数据,使用 diff 子命令量化调优效果。重点关注 wait-time 和 max-delay 的变化百分比。
4.3 子命令适用场景速查表
| 子命令 | 核心输出 | 典型场景 |
|---|---|---|
| record | 原始调度事件数据文件 | 所有调度分析的起点;采集生产或测试负载的调度轨迹 |
| latency | 进程级调度延迟统计表 | 快速定位延迟异常的进程;量化平均/最大等待时间 |
| map | 时间轴上下文切换图 | 可视化分析 CPU 负载分布、进程迁移模式、优先级调度行为 |
| replay | 模拟回放延迟报告 | 评估调度器自身效率;排除外部干扰后的理想延迟测量 |
| diff | 两次实验的延迟差异对比 | 调优前后效果验证;内核版本或配置变更的影响评估 |
4.4 组合使用示例:从采集到定位
以下流程展示如何组合使用 perf sched 子命令完成一次完整的调度延迟分析:
- 采集基线数据:
perf sched record -o baseline.data -- sleep 30 - 生成延迟统计:
perf sched latency -i baseline.data --sort max,发现nginx-1234的max-delay达到 15ms。 - 可视化调度序列:
perf sched map -i baseline.data --time 5.0,10.0,观察到nginx-1234在 CPU2 和 CPU3 之间频繁迁移。 - 模拟回放验证:
perf sched replay -i baseline.data,确认模拟延迟仅为 2ms,说明延迟主要由外部因素(如中断、其他进程争抢)导致。 - 调优后对比:调整
kernel.sched_migration_cost_ns后再次采集perf sched record -o tuned.data -- sleep 30,执行perf sched diff baseline.data tuned.data验证改善效果。
效率提示:日常分析中,
latency 和 map 是最常用的组合。先通过 latency 锁定异常进程,再用 map 观察其调度行为,通常能快速定位 80% 的调度延迟问题。