首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 代碼性能優化七大絕技:從 80/20 原則到嵌入式匯編實戰

     編輯:關於C語言

核心原則:二八定律

20% 的代碼消耗 80% 運行時間。優化重點應集中在熱點路徑,而非平均用力。

第一招:以空間換時間

// 方法 A:運行時構建字符串
#define LEN 32
char string1[LEN];
memset(string1, 0, LEN);
strcpy(string1, "This is a example!!");

// 方法 B:編譯期常量 + 指針引用
const char string2[LEN] = "This is a example!";
char *cp = string2;  // 直接使用,零開銷

適用場景:高頻調用、字符串內容固定、內存充裕。缺點:靈活性降低,需預存所有變體。

第二招:宏替換函數

// 函數版:有調用開銷(棧操作、現場保存)
int BIT_MASK(int __bf) {
    return ((1U << (bw ## __bf)) - 1) << (bs ## __bf);
}

// 宏版:零調用開銷,代碼內聯展開
#define BIT_MASK(__bf) \
    (((1U << (bw ## __bf)) - 1) << (bs ## __bf))

#define SET_BITS(__dst, __bf, __val) \
    ((__dst) = ((__dst) & ~(BIT_MASK(__bf))) | \
     (((__val) << (bs ## __bf)) & (BIT_MASK(__bf))))

ARM 官方源碼採用宏實現位操作,極致精簡。權衡:代碼膨脹 vs 調用開銷。

第三招:數學方法降維打擊

// 方法 E:循環累加 1~100
int sum = 0;
for (int i = 1; i <= 100; i++) sum += i;  // 100 次循環

// 方法 F:等差數列求和公式
int sum = (100 * (1 + 100)) / 2;  // 1 次乘法、1 次加法、1 次除法

核心思想:發掘數學規律,將 O(N) 降為 O(1)。編程前多思考:有無閉式解?

第四招:位運算替代乘除模

// 除以 2 的冪次 → 右移
int div8 = 257 / 8;      // 調用除法指令
int div8_opt = 257 >> 3; // 單條移位指令

// 模 2 的冪次 → 位與
int mod32 = 456 % 32;           // 調用取模指令
int mod32_opt = 456 & (32 - 1); // 456 & 0x1F,單條 AND 指令

// 通用技巧:x % (2^n) == x & (2^n - 1)

乘除指令週期通常遠大於移位/邏輯指令。嵌入式中位操作更是控制寄存器的基礎技能。

第五招:內聯匯編(必殺技,慎用)

// 數組拷貝:C 版 1024 次循環
for (int i = 0; i < 1024; i++) 
    string2[i] = string1[i];

// ARM 內聯匯編:128 次循環,每次 LDMIA/STMIA 傳 8 字
__asm {
    MOV R0, string1
    MOV R1, string2
    MOV R2, #0
loop:
    LDMIA R0!, {R3-R10}  // 批量加載 8 字
    STMIA R1!, {R3-R10}  // 批量存儲 8 字
    ADD R2, R2, #8
    CMP R2, #1024
    BNE loop
}

代價:喪失可移植性、違背軟件工程原則、維護極難。僅在極端性能敏感且無他法時使用。

第六招:寄存器變量

WORD Addition(BYTE n) {
    register int i, s = 0;  // 建議放入寄存器
    for (i = 1; i <= n; i++)
        s += i;
    return s;
}
  • 僅限局部自動變量和形參
  • register 是「建議」而非強制
  • 最佳候選:循環計數器、頻繁讀寫的局部變量
  • 現代編譯器優化極強,手動指定往往無效甚至有害

第七招:利用硬件特性

層級訪問速度優化策略
CPU 內部 RAM最快關鍵熱點數據放這裡
外部同步 RAM快代碼段拷貝至此運行
外部異步 RAM中等大數組、緩衝區
FLASH/ROM最慢啟動時拷貝代碼到 RAM
  • 代碼影子技術:啟動時將 FLASH 代碼拷貝到 RAM 執行
  • UART 中斷節流:設置接收 FIFO 滿/超時才中斷,避免逐字節中斷
  • DMA 替代中斷搬運:大塊數據傳輸用 DMA,釋放 CPU,提升並行度

總結:優化決策樹

  1. 定位熱點(Profiling)
  2. 算法優化(數學/數據結構) → 收益最大
  3. 數據結構/內存佈局優化
  4. 編譯器優化選項(-O2/-O3 -march=native)
  5. 關鍵路徑:宏/內聯/寄存器變量
  6. 極端情況:內聯匯編/DMA/硬件特性

記住:過早優化是萬惡之源。先寫正確、清晰的代碼,再針對瓶頸優化。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved