2、性能分析基础:核心指标与方法论
各位同学,欢迎来到性能分析的基础章节。说实话,很多车载工程师一上来就喜欢用 top、free 这些命令看两眼,觉得 CPU 没跑满就是没问题。嗯,我当年也这么干过,结果被一个内存泄漏问题折磨了整整两周。所以这一章,咱们把地基打牢。
2.1 四大核心指标:CPU / 内存 / IO / 网络
车载系统里,性能问题往往不是单一维度造成的。我个人习惯,拿到一台有问题的车机,先看这四类指标。咱们一个一个说。
2.1.1 CPU 指标
CPU 不只是看「使用率」。你想想看,使用率 100% 不代表系统真的在干活,可能是在空转。我重点关注这几个:
- 用户态使用率 (us):应用程序在跑,这个高是好事,说明业务在运转。
- 系统态使用率 (sy):内核在干活,比如系统调用、中断处理。这个如果持续超过 30%,你得小心了。
- 等待 IO (wa):CPU 在等磁盘或网络。这个值高,说明 IO 是瓶颈。
- 软中断 (si):网络收发包、定时器这些。车载场景下,CAN 总线中断处理不当,si 会飙升。
避坑指南:我曾经遇到一个项目,车机启动时 CPU 使用率只有 20%,但界面卡成 PPT。后来发现是某个后台服务在疯狂触发上下文切换,每秒切换次数超过 10 万次。所以,记得用 pidstat -w 看看上下文切换频率。
2.1.2 内存指标
内存这块,很多人只看「已用内存」。其实 Linux 的内存管理比你想象的要复杂。我建议你关注:
- 可用内存 (available):不是 free,是 available。它包含了可回收的缓存和缓冲区。
- Swap 使用量:车载设备一般不用 swap,但如果用了,说明物理内存真的不够了。
- OOM Killer 触发次数:这个一旦出现,系统会随机杀进程。导航被杀了,你想想看后果。
- 内存碎片化:长时间运行的车机,内存碎片会导致大块分配失败。用
/proc/buddyinfo可以看。
个人经验:我习惯在车机启动后,用 cat /proc/meminfo | grep -E "MemAvailable|MemFree|Cached" 记录基线。然后每隔 10 分钟采样一次,看内存是否在持续增长。如果可用内存每小时下降超过 5%,基本可以断定有内存泄漏。
2.1.3 IO 指标
车载的 IO 场景很特殊。不像服务器有 SSD 阵列,车机很多还在用 eMMC。IO 性能直接影响应用启动速度和数据读写。
- IOPS (每秒 IO 次数):小文件读写多,IOPS 比吞吐量更重要。
- 吞吐量 (Throughput):大文件读写,比如地图数据加载。
- IO 等待时间 (await):每次 IO 请求的平均等待时间。超过 100ms 就算异常。
- IO 队列深度 (avgqu-sz):队列深度超过 1,说明 IO 子系统已经饱和。
注意:车载 eMMC 的写入寿命有限。我曾经见过一个项目,日志系统每秒写 100 次,结果半年后 eMMC 就挂了。所以 IO 调优不只是为了性能,也是为了寿命。
2.1.4 网络指标
车联网场景下,网络性能越来越重要。但车载网络有个特点:不稳定。信号差、基站切换、隧道里没信号,这些都是常态。
- 延迟 (Latency):ping 的 RTT,超过 200ms 用户体验就会变差。
- 丢包率 (Packet Loss):超过 1% 就会明显影响 TCP 吞吐量。
- 重传率 (Retransmission):TCP 重传比例,超过 2% 说明网络质量堪忧。
- 带宽利用率:4G/5G 模组的实际吞吐量,别只看理论值。
2.2 性能基准测试方法论
基准测试,说白了就是给系统「称体重」。你得知道它正常时什么样,才能判断它是不是病了。我一般分三步走:
2.2.1 建立基线
在系统刚装好、没有任何负载时,先跑一轮测试。记录下 CPU 空闲时的使用率、内存占用、IO 延迟等。这个基线就是你的「健康标准」。
# 记录系统启动后的基线数据
echo "=== CPU 基线 ===" > baseline.txt
mpstat 1 3 >> baseline.txt
echo "=== 内存基线 ===" >> baseline.txt
free -h >> baseline.txt
echo "=== 磁盘 IO 基线 ===" >> baseline.txt
iostat -x 1 3 >> baseline.txt
2.2.2 压力测试
用工具模拟真实负载。车载场景下,我常用这些:
- stress-ng:模拟 CPU、内存、IO 压力。可以指定负载类型和持续时间。
- fio:磁盘性能测试。模拟地图加载、日志写入等场景。
- iperf3:网络带宽测试。模拟 OTA 升级、数据上传。
举个例子:模拟导航地图加载时的 IO 压力:
# 模拟 4KB 随机读,队列深度 4,持续 60 秒
fio --name=map-load --ioengine=libaio --rw=randread \
--bs=4k --iodepth=4 --size=1G --runtime=60 \
--time_based --filename=/data/test.img
2.2.3 对比分析
把压力测试的结果和基线对比。重点关注:
- CPU 使用率是否线性增长?还是突然跳变?
- 内存是否持续增长?回收是否及时?
- IO 延迟是否在可接受范围内?
- 网络吞吐量是否达到预期?
2.3 车载场景下的性能 SLA 定义
SLA,服务等级协议。说白了就是「系统必须达到什么水平」。车载场景和服务器完全不同。服务器 SLA 看的是 99.99% 可用性,车载看的是「用户感受」。
我参与过几个量产项目,总结了一套车载性能 SLA 的参考标准:
| 指标 | 优秀 | 合格 | 不合格 |
|---|---|---|---|
| 冷启动时间 (从上电到桌面) | < 8 秒 | 8-15 秒 | > 15 秒 |
| 应用启动时间 (导航) | < 2 秒 | 2-5 秒 | > 5 秒 |
| 界面滑动帧率 | > 55 FPS | 30-55 FPS | < 30 FPS |
| 内存泄漏率 | < 1 MB/小时 | 1-5 MB/小时 | > 5 MB/小时 |
| IO 延迟 (随机读 4KB) | < 5 ms | 5-15 ms | > 15 ms |
| 网络延迟 (4G) | < 50 ms | 50-150 ms | > 150 ms |
我的建议:SLA 不是拍脑袋定的。我习惯在项目初期,先跑一周的「长稳测试」——就是让车机连续运行 7 天,模拟用户的各种操作。然后取 P95(95 分位)的值作为合格线。这样定出来的 SLA,既合理又有数据支撑。
2.4 本章小结
这一章我们聊了四个核心指标、基准测试的方法论,还有车载场景下的 SLA 定义。说白了,性能分析就是「先知道正常什么样,再判断异常在哪」。下一章,我们会深入 Linux 内核,看看怎么用 ftrace 和 perf 这些工具做更细致的分析。
嗯,记得把今天讲的基线测试跑一遍。等你遇到性能问题时,就知道这些数据有多重要了。