国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

嵌入式軟件優(yōu)化的認(rèn)識(shí)與實(shí)踐

2010-08-14 08:03張喜俊唐云凱
關(guān)鍵詞:編譯器程序員存儲(chǔ)器

張喜俊,唐云凱

(1.中國(guó)電子科技集團(tuán)公司 第四十一研究所,青島266555; 2.西北核技術(shù)研究所)

張喜俊(工程師),研究方向?yàn)闇y(cè)試測(cè)量?jī)x器軟件。

1 自動(dòng)優(yōu)化

C編譯器是嵌入式系統(tǒng)程序員的基本工具,正是它將程序員的思想和算法轉(zhuǎn)換成處理器可以執(zhí)行的機(jī)器碼。所有的C編譯器都能夠執(zhí)行各種類型的優(yōu)化。以gcc編譯器為例,除了常見(jiàn)的-O1、-O2、-O3優(yōu)化選項(xiàng)以外,還可以根據(jù)需要打開(kāi)其他優(yōu)化開(kāi)關(guān),它們的含義如表1所列。

表1 gcc編譯器優(yōu)化選項(xiàng)含義

在編碼過(guò)程中,程序員還應(yīng)該盡可能地為編譯器提供更多的信息,協(xié)助編譯器更好地進(jìn)行優(yōu)化。程序員與編譯器主要通過(guò)C語(yǔ)言關(guān)鍵字進(jìn)行交流。以C標(biāo)準(zhǔn)庫(kù)函數(shù)strcpy為例,它的原型為“char*strcpy(char*dst,const char*src);” ,而不是“char*strcpy(char*dst,char*src);”。雖然它們只是相差一個(gè)const關(guān)鍵字,但在編譯器看來(lái)卻相差甚遠(yuǎn)。如果使用const修飾src,表明src指向一個(gè)常量字符串,編譯器可直接從寄存器或者高速緩存中訪問(wèn)它們,而不必每次都從存儲(chǔ)器中讀出它們的內(nèi)容。這樣不僅提高了執(zhí)行速度,且編譯器也可捕獲對(duì)src指向的字符串的修改,并提示程序員不應(yīng)該修改常量字符串。

2 手動(dòng)優(yōu)化

由于現(xiàn)代編譯器已經(jīng)能夠出色地自動(dòng)完成大多數(shù)優(yōu)化工作,因此切忌盲目手動(dòng)優(yōu)化。在進(jìn)行實(shí)際的優(yōu)化之前,可以借助代碼剖析工具進(jìn)行代碼分析,找出關(guān)鍵代碼片段,然后再進(jìn)行手動(dòng)優(yōu)化。使用gcov或者gprof之類的剖析器,可以找出一些有關(guān)代碼的基本性能統(tǒng)計(jì)數(shù)據(jù),例如每行代碼的調(diào)用次數(shù)、代碼覆蓋率和各部分代碼耗費(fèi)的CPU時(shí)間等。了解這些基本信息之后,就知道了應(yīng)該對(duì)哪些代碼進(jìn)行優(yōu)化。

2.1 計(jì)算密集型優(yōu)化

計(jì)算密集型應(yīng)用指的是那些進(jìn)行大量計(jì)算的應(yīng)用,特別是與數(shù)字信號(hào)處理相關(guān)的應(yīng)用。算法和數(shù)據(jù)結(jié)構(gòu)的選擇至關(guān)重要,它們應(yīng)該是優(yōu)化工作的重點(diǎn)。除了算法優(yōu)化,在編碼過(guò)程中程序員還應(yīng)該盡可能地對(duì)基本運(yùn)算進(jìn)行優(yōu)化。例如:

①如果b>0并且b×c不會(huì)飽和,那么可以使用乘法代替除法,將(a/b)>c替換為a>(c×b)。

②如果乘法運(yùn)算中的乘數(shù)或者除法運(yùn)算中的分母為2的倍數(shù),那么可以使用移位操作代替乘除法。

③加法要快于乘法,如可使用(a+a+a)替換a×3。

2.2 以空間換效率

以空間換效率,即以犧牲代碼尺寸為代價(jià)換取運(yùn)行效率。常見(jiàn)的優(yōu)化策略包括循環(huán)展開(kāi)、查找表、數(shù)組索引和內(nèi)聯(lián)函數(shù)等。

編者注:有關(guān)循環(huán)展開(kāi)、查找表等內(nèi)容的詳細(xì)介紹請(qǐng)見(jiàn)本刊網(wǎng)站www.mesnet.com.cn。

2.3 減少存儲(chǔ)器訪問(wèn)次數(shù)

2.3.1盡可能少使用全局變量

由于全局變量是全局可見(jiàn)的,可以在多個(gè)地方對(duì)其進(jìn)行修改,因此編譯器不能在寄存器中緩存全局變量的值。這樣,讀或者寫(xiě)全局全局變量時(shí),都必須訪問(wèn)存儲(chǔ)器以裝載或存儲(chǔ)它們;而且在訪問(wèn)全局變量時(shí),為了保證其完整性必須確保操作是原子的,這又會(huì)增加開(kāi)銷。

2.3.2減小函數(shù)參數(shù)傳遞的開(kāi)銷

以ARM處理器為例,如果函數(shù)只包含4個(gè)參數(shù)或更少,每個(gè)參數(shù)的大小為一個(gè)字或更小,那么可以通過(guò)寄存器R0~R3來(lái)傳遞所有的參數(shù)。相反,如果參數(shù)個(gè)數(shù)大于4,那么其他的參數(shù)只能通過(guò)位于片內(nèi) RAM或者速度更慢的SDRAM中的堆棧來(lái)傳遞,與寄存器相比,它們的訪問(wèn)速度要慢很多。注意,在C++中非靜態(tài)成員總是有一個(gè)this指針參數(shù),一般通過(guò)寄存器R0傳遞,這樣只剩下R1~R3三個(gè)寄存器可以傳遞其他參數(shù)。

如果某個(gè)函數(shù)參數(shù)為一個(gè)大型的結(jié)構(gòu)體,那么最好將其改為傳遞指向這個(gè)結(jié)構(gòu)體的指針。這是因?yàn)?C語(yǔ)言中的函數(shù)調(diào)用默認(rèn)情況下是傳值調(diào)用,編譯器會(huì)將結(jié)構(gòu)體復(fù)制到堆棧。如果傳遞一個(gè)結(jié)構(gòu)體指針,那么只需要復(fù)制這個(gè)4字節(jié)的指針到寄存器。

2.3.3合理安排運(yùn)行時(shí)代碼和數(shù)據(jù)的位置

嵌入式系統(tǒng)中往往存在多種類型的存儲(chǔ)器(如片內(nèi)Flash、片內(nèi) SRAM 以及擴(kuò)展的 SDRAM、Flash和EEPROM等),它們的訪問(wèn)速度相差甚遠(yuǎn)。同時(shí),應(yīng)用程序代碼不同部分的執(zhí)行頻率也相差很大。以ARM嵌入式系統(tǒng)為例,異常向量表和中斷處理器的執(zhí)行最為頻繁。為了獲得最佳性能,可以將它們復(fù)制到片內(nèi)SRAM中,然后執(zhí)行存儲(chǔ)器重映射將異常向量表定位到0地址。其他關(guān)鍵代碼片段也可以利用分散加載描述文件(用于RealView工具鏈,gnu工具鏈?zhǔn)褂?lds文件)通知鏈接器和加載器,將它們裝載到指定的存儲(chǔ)器地址。

3 局部性原理

優(yōu)秀的代碼傾向于展示良好的局部性,它包含兩個(gè)方面的含義:其一,傾向于在極短的時(shí)間間隔內(nèi),多次引用同一存儲(chǔ)器位置;其二,傾向于在極短的時(shí)間間隔內(nèi),引用當(dāng)前訪問(wèn)的數(shù)據(jù)項(xiàng)附近的數(shù)據(jù)項(xiàng)。

具有良好局部性的代碼之所以具有較高的運(yùn)行效率,這是因?yàn)橛?jì)算機(jī)的存儲(chǔ)器系統(tǒng)是一個(gè)具有不同容量、成本和訪問(wèn)時(shí)間的存儲(chǔ)設(shè)備的層次結(jié)構(gòu)。嵌入式系統(tǒng)的存儲(chǔ)器層次結(jié)構(gòu)一般可以分為寄存器、高速緩存、主存和Flash,它們的訪問(wèn)時(shí)間逐步上升。層次結(jié)構(gòu)中的每一層都緩存來(lái)自較低一層的數(shù)據(jù)對(duì)象,如果需要訪問(wèn)的數(shù)據(jù)沒(méi)有位于高速緩存中(即緩存不命中),那么不得不耗費(fèi)數(shù)十倍的時(shí)間從主存中獲得,極大地降低了運(yùn)行效率。

比較下面2種二維數(shù)組求和方法。由于C語(yǔ)言以行優(yōu)先順序存儲(chǔ)數(shù)組,因此行優(yōu)先累加方法的局部性要優(yōu)于列優(yōu)先累加方法。

[1]Sloss Andrew N,Symes Dominic,Wright Chris.ARM嵌入式系統(tǒng)開(kāi)發(fā):軟件設(shè)計(jì)與優(yōu)化[M].沈建華,譯.北京:北京航空航天大學(xué)出版社,2005.

[2]Bryant Randal E,O'Hallaron David.深入理解計(jì)算機(jī)系統(tǒng)(修訂版)[M].龔奕利,雷迎春,譯.北京:中國(guó)電力出版社,2004.

[3]M Richard.Using the GNU Compiler Collection:For GCC version 4.4.1[EB/OL].[2009-10].http://gcc.gnu.org/onlinedocs/gcc-4.4.1/gcc.pdf.

[4]Ghosh Koushik.Writing Efficient C andC Code Optimization[EB/OL].(2004-2-26)[2009-10].http://www.codeproject.com/KB/cpp/C_Code_Optimization.aspx.

猜你喜歡
編譯器程序員存儲(chǔ)器
為了讓媽媽看懂地圖,一位“野生程序員”做了個(gè)小程序
靜態(tài)隨機(jī)存儲(chǔ)器在軌自檢算法
怎樣成為一名優(yōu)秀程序員
基于相異編譯器的安全計(jì)算機(jī)平臺(tái)交叉編譯環(huán)境設(shè)計(jì)
程序員之子
加班
存儲(chǔ)器——安格爾(墨西哥)▲
通用NC代碼編譯器的設(shè)計(jì)與實(shí)現(xiàn)
基于Nand Flash的高速存儲(chǔ)器結(jié)構(gòu)設(shè)計(jì)
編譯器無(wú)關(guān)性編碼在微控制器中的優(yōu)勢(shì)
兰考县| 枣庄市| 乌兰县| 绥棱县| 教育| 合山市| 辽阳市| 沾益县| 化德县| 南漳县| 双辽市| 惠东县| 达日县| 正蓝旗| 临汾市| 永定县| 临洮县| 景东| 望奎县| 金湖县| 崇礼县| 海宁市| 滦南县| 楚雄市| 青神县| 余干县| 包头市| 财经| 万源市| 兰考县| 中超| 缙云县| 马尔康县| 林州市| 湟源县| 双桥区| 公主岭市| 徐闻县| 犍为县| 石门县| 年辖:市辖区|