3、监控数据采集基础:Linux系统下的性能数据源(/proc、/sys、perf、ftrace)
做座舱系统性能优化,第一步不是调参数,而是知道数据从哪来。
我经常跟团队里的新人说:你连CPU在干什么都不知道,怎么优化?
Linux系统下,性能数据的源头就那么几个——/proc、/sys、perf、ftrace。今天咱们就把它们挨个捋一遍。
3.1 /proc:进程与系统的实时快照
/proc是一个虚拟文件系统。它不存文件,存的是内核数据结构的实时映射。
说白了,你读一个文件,内核就给你返回当前的状态。我习惯把它叫做「内核的窗口」。
3.1.1 核心文件一览
| 文件路径 | 内容说明 | 我常用的场景 |
|---|---|---|
/proc/cpuinfo |
CPU型号、核数、频率 | 确认硬件是否降频 |
/proc/meminfo |
内存总量、可用量、缓存 | 排查内存泄漏 |
/proc/stat |
CPU时间片分布 | 计算CPU使用率 |
/proc/[pid]/status |
进程状态、内存、线程数 | 定位卡死的进程 |
/proc/[pid]/sched |
调度延迟、运行时间 | 分析高优先级线程是否被抢占 |
/proc/stat,自己算user/system/iowait/idle。这样采样间隔可控,精度更高。
3.1.2 实战:计算CPU使用率
# 读取两次 /proc/stat,间隔1秒
cat /proc/stat | grep "cpu " > /tmp/stat1
sleep 1
cat /proc/stat | grep "cpu " > /tmp/stat2
# 用awk算差值
awk 'NR==FNR{a=$2+$3+$4+$5+$6+$7+$8; next}
{b=$2+$3+$4+$5+$6+$7+$8; idle=$5}
END{printf "CPU使用率: %.2f%%\n", (1-(idle-b)/(b-a))*100}' /tmp/stat1 /tmp/stat2
嗯,这里要注意:/proc/stat里的数值是累计值,不是瞬时值。你得算差值。
3.2 /sys:内核参数的调优阵地
/sys比/proc更底层。它暴露的是内核的设备模型和可调参数。
你想想看,/proc是给你看的,/sys是给你改的。
3.2.1 座舱系统最常用的/sys路径
- CPU调频策略:
/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor - 中断亲和性:
/proc/irq/[irq_num]/smp_affinity(虽然路径在/proc,但属于/sys体系) - 内存大页:
/sys/kernel/mm/hugepages/ - CGroup控制组:
/sys/fs/cgroup/
/sys参数,结果重启后恢复默认。后来我才知道,/sys是运行时参数,不改init脚本的话,一断电就没了。
3.2.2 实战:锁定CPU频率
座舱系统里,有时候需要把某个核心锁在高频,保证UI渲染不卡顿。
# 查看当前策略
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# 设置为performance(最高频)
echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# 或者锁定到具体频率
echo 1800000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
注意:不是所有芯片都支持scaling_setspeed。高通平台和瑞萨平台的行为就不一样。我建议你先cat一下scaling_available_frequencies,看看有哪些档位。
3.3 perf:采样分析的神器
perf是内核自带的性能剖析工具。它利用硬件PMU(性能监控单元)来采样,开销极低。
我个人觉得,perf是座舱性能优化里性价比最高的工具。为什么?因为它不需要改代码,跑一下就能看到热点函数。
3.3.1 常用perf命令
| 命令 | 作用 | 我的使用频率 |
|---|---|---|
perf stat |
统计周期内的硬件事件 | ⭐⭐⭐⭐ |
perf record |
采样并记录到文件 | ⭐⭐⭐⭐⭐ |
perf report |
分析采样结果 | ⭐⭐⭐⭐⭐ |
perf top |
实时显示热点函数 | ⭐⭐⭐ |
3.3.2 实战:定位CPU热点
# 采样10秒,记录CPU周期事件
perf record -e cycles -a -g -- sleep 10
# 生成报告
perf report --stdio
# 只看某个进程
perf top -p $(pidof surfaceflinger)
-g参数开启调用链。没有调用链,你只知道哪个函数耗CPU,不知道是谁调了它。在座舱系统里,我经常发现是某个SurfaceFlinger的合成线程把CPU吃满了,顺着调用链一查,原来是某个第三方应用频繁刷新图层。
3.4 ftrace:内核事件的追踪利器
ftrace是内核内部的追踪器。它能记录函数调用、调度事件、中断响应等。
说实话,ftrace的学习曲线比perf陡。但一旦你掌握了,调试调度延迟、中断延迟这类问题,简直如虎添翼。
3.4.1 ftrace的核心概念
- tracer:追踪器类型(function、function_graph、irqsoff等)
- set_ftrace_filter:只追踪指定函数
- trace:输出缓冲区
- tracing_on:开关
3.4.2 实战:追踪调度延迟
座舱系统里,最怕的就是高优先级线程被低优先级线程抢占了CPU。用ftrace可以抓到「罪魁祸首」。
# 进入ftrace目录
cd /sys/kernel/debug/tracing
# 选择调度器追踪器
echo sched_switch > current_tracer
# 只追踪指定进程(比如surfaceflinger的PID是1234)
echo 1234 > set_ftrace_pid
# 开始追踪
echo 1 > tracing_on
# 等几秒,触发问题
sleep 5
# 停止
echo 0 > tracing_on
# 查看结果
cat trace
logd的线程抢占了。后来把logd的优先级调低,问题解决。这种问题,用perf是看不出来的,因为CPU使用率并不高。
3.5 四个数据源的选型建议
| 场景 | 推荐工具 | 原因 |
|---|---|---|
| 看CPU/内存使用率 | /proc | 轻量、实时、无侵入 |
| 调优内核参数 | /sys | 直接修改运行时行为 |
| 定位CPU热点函数 | perf | 采样精准、开销低 |
| 追踪调度/中断延迟 | ftrace | 内核级事件、粒度细 |
最后说一句:不要只依赖一个工具。我见过太多人只会用top,遇到性能问题就抓瞎。你想想看,top只能告诉你「谁在吃CPU」,但perf能告诉你「为什么吃CPU」,ftrace能告诉你「谁抢了CPU」。
把这四个数据源吃透了,座舱系统的性能问题,你至少能解决80%。