那曲檬骨新材料有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

嵌入式C代碼優化:實用技巧與經驗分享

電子電路開發學習 ? 來源:電子電路開發學習 ? 2024-03-28 10:53 ? 次閱讀

嵌入式代碼優化是一個復雜的過程,它不僅取決于代碼本身,還取決于目標硬件平臺、編譯器以及優化的目標(例如速度、內存使用、功耗等)。

不過,有一些通用的技巧可以在編寫嵌入式代碼時考慮到:

使用查表法

在內存空間較為充足的情況下,有時候可以犧牲一些空間來換取程序的運行速度。查表法就是 以空間換取時間 的典型例子。

比如:編寫程序統計一個4bit(0x0~0xF)數據中1的個數。

使用查表法:

staticinttable[16]={0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};
intget_digits_1_num(unsignedchardata)
{
intcnt=0;
unsignedchartemp=data&0xf;

cnt=table[temp];

returncnt;
}

優于:

intget_digits_1_num(unsignedchardata)
{
intcnt=0;
unsignedchartemp=data&0xf;

for(inti=0;i>=1;
}

returncnt;
}

查表法把0x0~0xF中的所有數據中每個數據的1的個數都記錄下來,存放到一個表中。這樣一來,數據數據中1的個數就建立起了一一對應關系,就可以通過數組索引來獲取得到結果。常規法使用for循環的方式來實現,缺點是占用了不少處理器的時間。

特別地,對于越復雜地運算,查表法較常規法更有優勢。另一方面,查表法的代碼往往比常規法要簡潔些。

使用柔性數組

C99中,結構體中的最后一個元素允許是未知大小的數組,這就叫作 柔性數組

254de50c-ec37-11ee-a297-92fbcf53809c.png

柔性數組的特點:

結構體中柔性數組成員前面必須至少有一個其他成員。

sizeof返回的這種結構大小不包括柔性數組的內存。

包含柔性數組成員的結構用malloc()函數進行內存的動態分配。

在C99標準環境中,使用柔性數組:

typedefstruct_protocol_format
{
uint16_thead;
uint8_tid;
uint8_ttype;
uint8_tlength;
uint8_tvalue[];
}protocol_format_t;

優于使用指針:

typedefstruct_protocol_format
{
uint16_thead;
uint8_tid;
uint8_ttype;
uint8_tlength;
uint8_t*value;
}protocol_format_t;

柔性數組的方式結構體占用較指針的方式少。

柔性數組的方式相對與指針的方式更為簡潔,給結構體申請空間的同時也給柔性數組申請空間,柔性數組的方式只需要申請一次空間,是一塊連續內存,連續的內存有益于提高訪問速度;而指針的方式,除了給結構體申請空間之外,還得給結構體里的指針成員申請空間。

使用指針的方式寫代碼會比柔性數組的方式會繁瑣一些,特別地,如果在釋放內存的時候把順序弄反了,則結構體里的指針成員所指向的內存就釋放不掉,會造成內存泄露。

使用位操作

1、使用位域

有些數據在存儲時并不需要占用一個完整的字節,只需要占用一個或幾個二進制位即可。

2558021c-ec37-11ee-a297-92fbcf53809c.png

比如:管理一些標志位。

使用位域:

struct{
unsignedcharflag1:1;
unsignedcharflag2:1;
unsignedcharflag3:1;
unsignedcharflag4:1;
unsignedcharflag5:1;
unsignedcharflag6:1;
unsignedcharflag7:1;
unsignedcharflag8:1;
}flags;

優于:

struct{
unsignedcharflag1;
unsignedcharflag2;
unsignedcharflag3;
unsignedcharflag4;
unsignedcharflag5;
unsignedcharflag6;
unsignedcharflag7;
unsignedcharflag8;
}flags;

2、使用位操作代替除法和乘法

使用位操作:

uint32_tval=1024;
uint32_tdoubled=val<>1;

優于:

uint32_tval=1024;
uint32_tdoubled=val*2
uint32_thalved=val/2

循環展開

有時候,可以犧牲一點代碼的簡潔度、減少循環控制語句的執行頻率以提高性能。

無依賴的循環展開:

process(array[0]);
process(array[1]);
process(array[2]);
process(array[3]);

優于:

for(inti=0;i

有依賴的循環展開:

longcalc_sum(int*a,int*b)
{
longsum0=0;
longsum1=0;
longsum2=0;
longsum3=0;

for(inti=0;i

優于:

longcalc_sum(int*a,int*b)
{
longsum=0;

for(inti=0;i

盡可能把長的有依賴的代碼鏈分解成幾個可以在流水線執行單元中并行執行的沒有依賴的代碼鏈,提高流水線的連續性。通常4次展開為最佳方式。

使用內聯函數

使用內聯函數替換重復的短代碼,一方面,可以避免函數的回調,加速了程序的執行,利用指令緩存,增強局部訪問性;另一方面,可以方便代碼管理。

如:翻轉led的操作。

staticinlinevoidtoggle_led(uint8_tpin)
{
PORT^=1<

使用合適的數據類型

首先使用合適的數據類型。

比如幾種數據類型都滿足需求的情況下,更小的可能并不是最合適的。

比如:素組索引的變量類型。

數組索引應盡量采用int類型。

inti;
for(i=0;i

優于:

chari;
for(i=0;i

定義為char類型,一般會有溢出的風險,因此編譯器需要使用多余的指令判斷是否溢出;而使用int類型,一般編譯器默認不會超過這么大的循環次數,從而減少了不必要的指令。

其它情況下,在滿足數據范圍的情況下,能夠使用字符型(char)定義的變量,就不要使用整型(int)變量來定義;能夠使用整型變量定義的變量就不要用長整型(long int),能不使用浮點型(float)變量就不要使用浮點型變量。

多重循環優化

長循環在最內層:

for(col=0;col

優于長循環在最外層:

for(row=0;row

在多重循環中,應當將最長的循環放在最內層, 最短的循環放在最外層,以減少 CPU 跨切循環層的次數。

盡早退出循環

通常,循環并不需要全部都執行。

例如,如果我們在從數組中查找一個特殊的值,一經找到,我們應該盡可能早的斷開循環。例如:如下循環從10000個整數中查找是否存在-99。

charfound=FALSE;
for(i=0;i

這段代碼無論我們是否查找得到,循環都會全部執行完。更好的方法是一旦找到我們查找的數字就終止繼續查詢。把程序修改為:

found=FALSE;
for(i=0;i

假如待查數據位于第23個位置上,程序便會執行23次,從而節省9977次循環。

結構體內存對齊

必要時,手動對齊結構體的內存排列。

比如:

typedefstructtest_struct
{
chara;
shortb;
charc;
intd;
chare;
}test_struct;

該結構體在32bit環境中,該結構體所占的字節數為16。

可以手動調整各成員的位置來進行空白字節填充以達到對齊的效果。如:

typedefstructtest_struct
{
chara;
charc;
shortb;
intd;
chare;
}test_struct;

則結構體變量test_s所占的字節數變為12字節,比原來的16字節省下了4個字節。

優化中斷處理

確保中斷處理快速且盡可能短。

//中斷例程應該盡量簡短
voidISR()
{
flag=true;
}

利用硬件特性

使用硬件模塊或特有指令來減輕CPU負擔。

//比如,直接使用DMA傳輸而不經由CPU
DMA_Config(&src,&dest,length);
DMA_Start();

以上就是本次的分享。一些優化可能會增加代碼的復雜性或降低可讀性或其它方面的影響,因此在決定應用優化時,需權衡不同方面的影響。

審核編輯:黃飛

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 嵌入式
    +關注

    關注

    5092

    文章

    19177

    瀏覽量

    307647
  • cpu
    cpu
    +關注

    關注

    68

    文章

    10902

    瀏覽量

    213000
  • 函數
    +關注

    關注

    3

    文章

    4346

    瀏覽量

    62968
  • 編譯器
    +關注

    關注

    1

    文章

    1642

    瀏覽量

    49283

原文標題:實用的嵌入式C代碼優化技巧與經驗

文章出處:【微信號:mcu149,微信公眾號:電子電路開發學習】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    嵌入式C語言代碼優化經驗與方法

    在本篇文章中,收集了很多經驗和方法。應用這些經驗和方法,可以幫助我們從執行速度和內存使用等方面來優化C語言代碼
    發表于 02-02 09:17 ?385次閱讀

    嵌入式C語言代碼優化經驗與方法

    在本篇文章中,收集了很多經驗和方法。應用這些經驗和方法,可以幫助我們從執行速度和內存使用等方面來優化C語言代碼
    發表于 03-08 13:27 ?306次閱讀

    嵌入式系統編程中代碼優化

    System)的廣泛使用,高級語言編程已是嵌入式系統設計的必然趨勢。但是 不排除一些軟件模塊仍用匯編語言來寫,這可以使程序更加有效。雖然C/C++編譯器對代碼進行了
    發表于 02-23 10:47

    嵌入式C語言優化小技巧是什么

    嵌入式C語言優化小技巧
    發表于 12-15 07:23

    嵌入式實時程序設計中C/C++代碼優化

    本文簡單介紹了嵌入式實時程序設計的特點和嵌入式系統設計中語言的選擇,著重介紹了以下幾種在嵌入式實時程序設計中優化 C/
    發表于 08-07 08:47 ?15次下載

    嵌入式程序設計中C/C++代碼優化

    本文介紹了在嵌入式程序設計中幾種提高C/C++代碼效率的方法,通過對例子的分析,探討了影響程序效率的原因。關鍵詞:c語言,
    發表于 08-14 08:53 ?25次下載

    大神教你:嵌入式系統C++代碼的變成技巧

    嵌入式軟件技術中,C++語言具有較高的編程效率。但是,要實現高效率,還有許多問題需要特別注意。首先,應該正確理解C++的工作原理,逐步利用它的各種強大功能,把專業經驗集成到對象中,并
    發表于 05-25 09:20 ?3618次閱讀

    如何將嵌入式代碼優化

    嵌入式代碼優化,除了最基本的函數實現細節算法優化外,還有一些細節的處理。
    發表于 09-25 09:34 ?1426次閱讀

    嵌入式系統C語言的特點及程序設計中代碼優化的技巧

    目前,在嵌入式系統開發中可使用的語言很多,其中 C語言應用得最廣泛。雖然用 C 語言編程具有許多優點,但基于嵌入式系統的C語言和標準
    的頭像 發表于 09-02 09:14 ?3020次閱讀

    嵌入式外中斷c語言代碼

    嵌入式外中斷c語言代碼(arm嵌入式開發實例)-嵌入式外中斷c語言
    發表于 07-30 11:29 ?4次下載
    <b class='flag-5'>嵌入式</b>外中斷<b class='flag-5'>c</b>語言<b class='flag-5'>代碼</b>

    嵌入式項目實戰經驗

    嵌入式項目實戰經驗分享,C/C++、Linux、STM32、51單片機、FPGA、IoT、OpenCV、數字圖像處理、通信、算法!
    發表于 11-03 12:36 ?23次下載
    <b class='flag-5'>嵌入式</b>項目實戰<b class='flag-5'>經驗</b>

    嵌入式C++編程

    編程特性來構建嵌入式系統您將了解如何將您的系統與外部外圍設備以及使用驅動程序的有效方式集成指導您測試和優化代碼以獲得更好的性能并實現有用的設計模式將了解如何使用 Qt,這是用于構建嵌入式
    發表于 11-04 10:36 ?10次下載
    <b class='flag-5'>嵌入式</b><b class='flag-5'>C</b>++編程

    嵌入式系統安全實用技巧

    嵌入式系統安全實用技巧
    的頭像 發表于 12-28 09:51 ?779次閱讀

    嵌入式代碼高效運行指南

    嵌入式C語言之所以經久不衰,在于它的運行效率很高,想要高效運行代碼,除了編譯器幫忙優化,關鍵還要靠自己“優化
    的頭像 發表于 01-06 15:32 ?936次閱讀

    嵌入式C語言代碼優化經驗與方法

    在本篇文章中,收集了很多經驗和方法。應用這些經驗和方法,可以幫助我們從執行速度和內存使用等方面來優化C語言代碼。 簡介 在最近的一個項目中,
    的頭像 發表于 02-09 01:21 ?679次閱讀
    威尼斯人娱乐城网上赌博| 九州百家乐官网娱乐城| 玩百家乐技巧巧| 百家乐官网不锈钢| 百家乐官网电投网址| 大家赢娱乐城| bet365注册会员| 大发888娱乐场是真是假| 百家乐怎样玩才会赢钱| 百家乐国际娱乐网| 百家乐怎打能赢| 百家乐官网统计工具| 百家乐官网现金网最好的系统哪里有可靠吗| 有关百家乐官网玩家论坛| 百家乐官网信誉平台开户| 圣淘沙百家乐官网游戏| 威尼斯人娱乐场xpjgw5xsjgw| 大发888皇冠娱乐城| 大发888在线娱乐百家乐| 全讯网即时线路| 大发888备用网址大发娱乐城| 百家乐是个什么样的游戏| 大发888娱乐城积分| 大发888体育官网| 娱乐城网| 德钦县| 墨竹工卡县| 顶尖百家乐官网开户| 澳门百家乐官网娱乐开户| 百家乐官网合理的投注法| 百家乐官网庄闲赢负表 | 百家乐官网磁力录| 虚拟百家乐官网游戏下载| 百家乐官网单跳双跳| 百家乐官网高手技巧| 百家乐官网智能系统| 百家乐单双打法| 百家乐官网技巧-澳门百家乐官网官方网址| 百家乐官网览| 百家乐官网看图赢钱| 怎么玩百家乐能赢钱|