3、监控数据采集基础:Linux系统下的性能数据源(/proc、/sys、perf、ftrace)

做座舱系统性能优化,第一步不是调参数,而是知道数据从哪来。

我经常跟团队里的新人说:你连CPU在干什么都不知道,怎么优化?

Linux系统下,性能数据的源头就那么几个——/proc/sysperfftrace。今天咱们就把它们挨个捋一遍。

3.1 /proc:进程与系统的实时快照

/proc是一个虚拟文件系统。它不存文件,存的是内核数据结构的实时映射。

说白了,你读一个文件,内核就给你返回当前的状态。我习惯把它叫做「内核的窗口」。

3.1.1 核心文件一览

文件路径 内容说明 我常用的场景
/proc/cpuinfo CPU型号、核数、频率 确认硬件是否降频
/proc/meminfo 内存总量、可用量、缓存 排查内存泄漏
/proc/stat CPU时间片分布 计算CPU使用率
/proc/[pid]/status 进程状态、内存、线程数 定位卡死的进程
/proc/[pid]/sched 调度延迟、运行时间 分析高优先级线程是否被抢占
我的小技巧: 监控CPU使用率时,别只看top。我一般直接读/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
我的经验: 有一次客户反馈车载导航滑动卡顿。我用ftrace抓了调度事件,发现surfaceflinger线程每次被调度后,只跑了2ms就被一个名为logd的线程抢占了。后来把logd的优先级调低,问题解决。这种问题,用perf是看不出来的,因为CPU使用率并不高。

3.5 四个数据源的选型建议

场景 推荐工具 原因
看CPU/内存使用率 /proc 轻量、实时、无侵入
调优内核参数 /sys 直接修改运行时行为
定位CPU热点函数 perf 采样精准、开销低
追踪调度/中断延迟 ftrace 内核级事件、粒度细

最后说一句:不要只依赖一个工具。我见过太多人只会用top,遇到性能问题就抓瞎。你想想看,top只能告诉你「谁在吃CPU」,但perf能告诉你「为什么吃CPU」,ftrace能告诉你「谁抢了CPU」。

把这四个数据源吃透了,座舱系统的性能问题,你至少能解决80%。