1. 课程导入

各位同学,咱们今天聊聊性能调优。说实话,很多工程师觉得调优就是“跑分”,或者觉得是项目后期才该干的事。我见过太多项目,功能都调通了,一上压力测试就崩,然后整个团队通宵查问题。其实,调优这件事,应该从项目一开始就刻在脑子里。

这一章,我们先打好基础。把性能指标、调优目标、原则和方法论理清楚。后面二十几章,全是基于这套框架展开的实战。

1.1 性能指标定义

调优之前,你得知道“好”的标准是什么。嵌入式系统里,性能指标不是单一的。我习惯把它们分成三类:

类别 指标 典型关注点
时间维度 响应时间、延迟、吞吐量 中断响应、任务切换、数据流处理
资源维度 CPU占用率、内存占用、总线带宽 峰值 vs 均值、碎片化、争抢
实时维度 最差执行时间(WCET)、抖动(Jitter) 硬实时 vs 软实时、截止时间

关键认知: 性能调优不是追求单一指标极致,而是在多个指标间做权衡。比如,降低CPU占用率可能增加内存开销,减少延迟可能牺牲吞吐量。

举个例子。我在做一个工业控制项目时,客户要求中断响应时间小于10微秒。我们优化了中断服务程序,响应时间降到5微秒。但代价是CPU占用率从30%飙到了70%。后来跟客户沟通,其实50微秒以内都能接受。我们最终把响应时间调到15微秒,CPU占用率降到40%。这就是权衡。

1.2 调优目标与原则

调优目标不是拍脑袋定的。我建议按这个顺序来定义:

  1. 功能正确性优先 —— 跑得快但跑不对,毫无意义。
  2. 满足实时约束 —— 硬实时系统,错过截止时间就是事故。
  3. 资源利用率合理 —— 不是越低越好,是“够用且有余量”。
  4. 可维护性与可移植性 —— 别为了10%的性能提升,把代码写成天书。

调优原则,我总结成四个字:“稳、准、狠、省”。

  • 稳:性能波动要小,不能忽快忽慢。
  • 准:定位瓶颈要准,别瞎优化。
  • 狠:找到关键路径,下狠手优化。
  • 省:用最少的改动,换最大的收益。

避坑指南: 我曾经在一个项目中,花了两周优化一个很少被调用的函数,性能提升了50%。但系统整体性能只提升了0.1%。这就是典型的“局部最优,全局无效”。调优前,先问自己:这个瓶颈是系统真正的瓶颈吗?

1.3 调优方法论与流程

调优不是玄学,是有章可循的。我常用的方法论是 “测量-分析-优化-验证” 四步循环。说白了,就是PDCA在性能领域的落地。

下面这张图,是我每次做性能调优都会贴在白板上的流程:

嵌入式系统性能调优流程 1. 定义性能指标 响应时间/CPU/内存 2. 建立性能基线 当前状态量化 3. 定位瓶颈 工具+经验 4. 制定优化方案 算法/架构/配置 5. 实施优化 增量修改 6. 验证效果 对比基线 未达标?返回步骤3重新定位 输出:调优报告 基线对比 + 优化记录

这个流程看起来简单,但每个环节都有坑。我展开说说。

第一步:定义性能指标

指标要可测量、可对比。别用“系统要流畅”这种模糊描述。要写成“中断响应时间小于50微秒,CPU占用率低于60%”。

第二步:建立性能基线

没有基线,你根本不知道优化有没有效果。我习惯在项目初期就跑一遍基准测试,把数据存下来。后面每次优化,都拿这个基线对比。

小技巧: 基线数据最好包含多个负载场景。比如空闲态、典型负载、峰值负载。我曾经只测了典型负载,结果优化后峰值负载下系统直接挂了。

第三步:定位瓶颈

这是最考验经验的一步。常用的工具有:

  • 性能分析器(如 perf、Tracealyzer)—— 看CPU热点
  • 内存分析器(如 Valgrind)—— 看内存泄漏和碎片
  • 逻辑分析仪 —— 看时序和总线争抢
  • RTOS 跟踪工具 —— 看任务调度和阻塞

我个人习惯,先用性能分析器扫一遍,找到最耗CPU的前三个函数。然后看内存分配情况。最后用逻辑分析仪抓关键信号。三步下来,80%的瓶颈都能定位到。

第四步到第六步:优化、验证、循环

优化要“小步快跑”。每次只改一个点,改完立刻验证。验证通过后,更新基线。如果没达标,回到第三步重新定位。

为什么强调“一次只改一个点”?因为多个改动同时验证,你根本不知道哪个有效、哪个有副作用。我见过有人一次改了算法、换了编译器优化等级、还调了任务优先级。结果性能提升了,但系统不稳定了。最后查了三天,才发现是编译器优化等级导致一个volatile变量被优化掉了。

避坑指南: 我曾经在验证环节吃过亏。优化后性能提升明显,但没做长时间稳定性测试。结果系统跑了48小时后,内存碎片导致分配失败。从那以后,我的验证环节必须包含:功能测试、性能测试、长时间稳定性测试(至少72小时)。

1.4 调优工具链概览

工欲善其事,必先利其器。下面是我常用的工具链,按阶段分类:

阶段 工具 用途
测量 perf, gprof, Tracealyzer CPU热点、函数调用频率
分析 Valgrind, SystemView 内存问题、任务调度
优化 编译器选项、代码重构 算法优化、内存布局
验证 自动化测试框架、压力测试 回归测试、长时间稳定性

这些工具的具体用法,后面章节会逐个展开。现在你只需要知道:没有测量就没有优化,没有基线就没有判断。

1.5 本章小结

这一章,我们讲了性能调优的“道”。指标要量化,目标要明确,原则要坚守,流程要闭环。后面二十几章,全是“术”的层面。但如果你“道”没想清楚,再好的“术”也救不了你。

嗯,记住一句话:调优不是炫技,是系统性地解决问题。