嵌入式系統資源受限,性能優化往往決定產品成敗。遵循「二八原則」:20% 的代碼消耗 80% 運行時間,優化重點應集中在熱點路徑。本文總結五大優化技術。
宏展開無函數調用開銷,適合極簡操作。但宏非函數,需注意參數副作用與括號保護。
#define MIN(A,B) (A <= B ? A : B)
#define MIN(A,B) ((A) <= (B) ? (A) : (B))
least = MIN(*p++, b); // 展開為 ((*p++) <= (b) ? (*p++) : (b)) → p 可能自增兩次!
原則:絕不向宏傳遞有副作用的表達式(如 i++、函數調用)。
register 關鍵字建議編譯器將變量存入 CPU 寄存器,減少內存訪問。適用於循環計數器、頻繁讀寫的局部變量。
WORD Addition(BYTE n) {
register int i, s = 0;
for (i = 1; i <= n; i++) s += i;
return s;
}
限制:僅限局部自動變量與參數;register 只是建議,編譯器可能忽略;不能取地址(&var 非法)。
對時間極其敏感的代碼段(如中斷服務程序、DSP 運算),可用內嵌匯編手工優化指令流水線、利用特殊指令集。
int result;
void Add(long a, long *b) {
_asm {
MOV AX, a
MOV BX, b
ADD AX, [BX]
MOV result, AX
}
}
代價:開發調試難度大、可移植性差、維護成本高。僅在證實為瓶頸且高級語言無法滿足時使用。
位運算指令週期遠小於乘除法,可替換 2 的冪次乘除模運算。
/* 方法1:乘除 */
i = 879 / 16; // 除以 2^4
j = 562 % 32; // 模 2^5
/* 方法2:位運算 */
i = 879 >> 4; // 右移 4 位
j = 562 - (562 >> 5 << 5); // 或 j = 562 & 0x1F
#define INT_I2_MASK 0x0040
// 開中斷:清零該位
wTemp = inword(INT_MASK);
outword(INT_MASK, wTemp & ~INT_I2_MASK);
// 關中斷:置位該位
outword(INT_MASK, wTemp | INT_I2_MASK);
// 判斷中斷狀態
if (wTemp & INT_I2_MASK) { /* 中斷被屏蔽 */ }