编译优化
通常使用 -Ox 选项控制优化等级,x 可以是 0、1、2、3,数值越大优化程度越高。
优化等级
| 等级 | 说明 | 特点 |
|---|---|---|
-O0 | 无优化 | 代码生成快、调试友好;执行效率低、体积大 |
-O1 | 基本优化 | 去除未引用代码、常量折叠等;比 O0 更快更小 |
-O2 | 中等优化 | 在 O1 基础上加循环展开、函数内联等;效率更高、体积进一步降低 |
-O3 | 最高优化 | 在 O2 基础上加更激进的循环优化、向量化等;速度最快,但体积可能增大、编译时间变长 |
实际取舍
- 开发/调试阶段 →
-O0。开了优化后汇编变化大,代码行为容易与预期不符,单步执行有”跳跃感” - 项目稳定后 → 根据运行速度和固件大小权衡,逐步提高到
-O2或-O3 - 开了优化可能出现延时不准、程序崩溃等莫名其妙的问题
volatile 与编译优化
线程间共享的全局变量、主程序和 ISR 共享的全局变量,定义时应加 volatile,确保每次都从内存重新读取,而非使用寄存器缓存值。
不优化就不需要 volatile 了吗?
即使不开优化,以下场景仍需要 volatile:
- 多线程环境:编译器可能将变量缓存在寄存器中,导致线程 A 看不到线程 B 的修改
- 硬件/中断相关:变量可能被硬件或 ISR 修改,必须每次从内存读取最新值
没有优化的确能减少必须用 volatile 的场景,但上述情况加上 volatile 仍然是好的规范。