www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > EDA > 電子設(shè)計自動化
[導(dǎo)讀]開發(fā)運(yùn)行在SoC內(nèi)的嵌入式處理器內(nèi)核的程序時,工程師有兩個主要目的:運(yùn)行得足夠快,使處理器運(yùn)行的頻率降到最低;消耗盡量少的內(nèi)存,使內(nèi)存開銷降到最小。對于不同的項目,有時候這兩個因素的重要性會不一樣。下面兩

開發(fā)運(yùn)行在SoC內(nèi)的嵌入式處理器內(nèi)核的程序時,工程師有兩個主要目的:運(yùn)行得足夠快,使處理器運(yùn)行的頻率降到最低;消耗盡量少的內(nèi)存,使內(nèi)存開銷降到最小。

對于不同的項目,有時候這兩個因素的重要性會不一樣。下面兩個關(guān)鍵因素極大地影響著設(shè)計團(tuán)隊滿足這些目標(biāo)的能力:開發(fā)源程序的編譯器對代碼的優(yōu)化效率以及用于開發(fā)源代碼的編程風(fēng)格。本文將深入地討論這兩種因素,并提出一些創(chuàng)建小而快的C程序的建議。

編譯器原理

編譯器通常是由前端和后端兩部分組成。前端通常是指語法和語義的處理過程,后端通常是指優(yōu)化、代碼生成,以及針對特定處理器的優(yōu)化過程。很多好的編譯器后端依賴于多層的中間表述(IR)。優(yōu)化和代碼生成從高層(類型輸入程序的句法)到低層逐級地傳遞中間表述。與處理器無關(guān)的優(yōu)化一般傾向于在編譯過程的早期在較高IR層上實現(xiàn),而針對特定處理器的優(yōu)化一般傾向于在編譯過程的后期在低層IR上來實現(xiàn)。信息通過不同IR層向下傳遞,這樣低層優(yōu)化可以充分利用編譯器早期處理得到的高層信息。

Tensilica針對其Xtensa可配置處理器和Diamond標(biāo)準(zhǔn)處理器的XCC/C++編譯器包含四個基本的優(yōu)化級,從-O0到-O3,對應(yīng)著不斷提高的優(yōu)化級別。表1描述了這些級別及其相對應(yīng)的代碼大小和內(nèi)部過程分析(IPA)。缺省情況下,XCC編譯器一次優(yōu)化一個文件,但是它也可以執(zhí)行內(nèi)部過程分析(通過加入IPA的編譯選項)。當(dāng)在多個原文件上優(yōu)化整個應(yīng)用程序時,優(yōu)化將會被延遲到鏈接的步驟之后進(jìn)行。表2描述了當(dāng)前編譯器(包括 XCC編譯器)支持的優(yōu)化內(nèi)容部分列表。

XCC編譯器還可以利用編譯產(chǎn)生的性能分析數(shù)據(jù)。性能分析的反饋可以幫助編譯器減輕分支跳轉(zhuǎn)的延遲。另外,反饋可以讓編譯器只是插入那些最常用的函數(shù)(inline),并且妥善處理常用代碼段中寄存器溢出的問題。因此,性能分析反饋允許XCC編譯器在所有地方進(jìn)行正常優(yōu)化的同時,還可以通過優(yōu)化應(yīng)用中的臨界部分進(jìn)行加速。

一些有用的C編碼規(guī)則

為了利用編譯器得到最好的性能,編程人員需要像編譯器一樣思考問題,并且理解C語言和目標(biāo)處理器之間的關(guān)系。下面的一些基本原則可以幫助所有嵌入式編程人員在不需很大努力的情況下獲得性能好很多的編譯代碼。

1. 觀察編譯得到的代碼

完全理解編譯器對全部代碼如何編譯是不可能的。如果XCC編譯器設(shè)置了—S或者-save-temps編譯選項,編譯將產(chǎn)生匯編輸出并且還有一些為了理解而添加的注釋。對于那些性能要求很高的代碼,你可以觀察編譯結(jié)果是否符合你的期望。如果不是,請考慮以下規(guī)則。

2. 了解混淆發(fā)生的情況

C語言允許任意地使用指針,這增加了混淆出現(xiàn)的機(jī)會,這允許程序用很多種方法去引用同一數(shù)據(jù)對象。如果全局變量的地址被作為子程序的參數(shù)傳遞,這個變量可以通過它的名字或者通過指針被引用。這就是一種混淆,編譯器必須保守地把這樣的數(shù)據(jù)對象保存在內(nèi)存中而不是寄存器中,并且仔細(xì)地保持代碼中可能引起混淆的變量的訪問順序??紤]下面的代碼:

void foo(int *a, int *b)

{

int i;

for (i=0; i<100; i++) {

*a += b[i];

}

}

您會設(shè)想編譯器應(yīng)該產(chǎn)生代碼是在循環(huán)開始前將*a保存到一個寄存器里面,并且在循環(huán)中把b[i]保存到一個寄存器里面然后將它加到*a所在的寄存器里。但事實上卻是,編譯器產(chǎn)生的結(jié)果是*a被放置在內(nèi)存里面,因為a和b可以產(chǎn)生混淆情況,*a也許是b數(shù)組的一個元素。雖然看起來在這個例子中不太可能出現(xiàn)這種混淆,但是編譯器是沒法確定這種情況是否會發(fā)生的。有幾個技巧可以針對混淆的情況,幫助編譯器能做到更好的編譯工作:你可以使用-IPA 編譯選項進(jìn)行編譯,你可以用全局變量代替參數(shù),你可以使用特殊編譯選項進(jìn)行編譯,或者可以在聲明變量中使用_restrict屬性。

3. 指針常常引起混淆

編譯器識別指針指向的目標(biāo)對象經(jīng)常會遇到問題。程序員可以通過使用本地變量幫助編譯器去避免混淆,具體方法是使用本地變量去存儲依據(jù)指針訪問獲得的值,因為不直接的操作和調(diào)用影響指針引用的值而不是本地變量的值。因此,編譯器會把本地變量放到寄存器里面去。

下面的例子顯示如何正確使用指針以避免混淆從而產(chǎn)生更好的編譯代碼。在這個例子里面,優(yōu)化者不知道*p++=0是否會修改len,所以它不能把len放到寄存器里面去獲得性能提升。相反每個循環(huán)中,len都被放到了內(nèi)存里面。

int len = 10;

void

zero(char *p)

{

int i;

for (i=0; i

}

通過使用本地變量而不是全局變量,可以避免混淆。

int len = 10;

void

zero(char *p)

{

int local_len = len;

int i;

for (i=0; i< local_len; i++) *p++ = 0;

}

4. 使用const和restrict限定詞

_restrict限定詞告訴編譯器可以假設(shè)有資格的指針是唯一訪問某內(nèi)存或數(shù)據(jù)對象的方式。通過這個指針的Load和Store操作不會引起與這個函數(shù)內(nèi)部其它Load和Store操作的混淆,除非通過這個指針的訪問。例如:

float x[ARRAY_SIZE];

float *c = x;

void f4_opt(int n, float * __restrict a, float * __restrict b)

{

int i;

/* No data dependence across iterations because of __restrict */

for (i = 0; i < n; i++)

a[i] = b[i] + c[i];

}

5. 使用本地變量替代全局變量

這是因為全局變量會在整個程序的生命周期里面保留數(shù)值。編譯器必須認(rèn)為全局變量可能通過指針被訪問??紤]下面的代碼:

int g;

void foo()

{

int i;

for (i=0; i<100; i++){

fred(i,g);

}

}

理想情況下,g在每次fred循環(huán)時被加載一次,并且它的值將被傳遞到一個寄存器里面給fred函數(shù)使用。但是,編譯器不知道fred是否會修改g 的值。如果fred不會修改g的值,你應(yīng)該像下面一樣,使用本地變量。這樣做可以避免每次調(diào)用fred函數(shù)時加載g到一個寄存器里面。

int g;

void foo()

{

int i, local_g=g;

for (i=0; i<100; i++){

fred(i,local_g);

}

}

6. 針對數(shù)據(jù)結(jié)構(gòu)使用正確的數(shù)據(jù)類型

C編程人員對于數(shù)據(jù)類型一般都會有他們習(xí)慣上的假設(shè),但是編譯器卻需要很謹(jǐn)慎地對待這些假設(shè)。比如,在幾乎所有現(xiàn)代的計算機(jī)架構(gòu)上,一個 unsigned char使用8位表示從0到255。一個C程序會假設(shè)對值為255的unsigned char加1會使其變?yōu)?。而實際上,現(xiàn)代32位處理器是不會執(zhí)行上述的那種8位加法,而是進(jìn)行32位數(shù)值的加法。因此,如果一個unsigned char的本地變量進(jìn)行加法,編譯器必須使用多條指令進(jìn)行運(yùn)算以保證加法后的符號擴(kuò)展。因此,針對各種變量尤其是循環(huán)索引的變量,應(yīng)該盡量多的在可以的地方使用int型變量。

另外,許多嵌入式處理器有16位乘法指令,而缺少32位乘法指令。在這種情況下,32位乘法將被仿效執(zhí)行,一般情況下都是很慢的。如果數(shù)據(jù)被執(zhí)行乘法操作并且計算結(jié)果不會超過16位的精度,那么就使用short或者unsigned short變量。

7. 不要用不直接的調(diào)用

這是通過包含傳遞參數(shù)的函數(shù)指針的調(diào)用,因為那會產(chǎn)生不可預(yù)知的邊際效應(yīng)(比如修改全局變量),使得優(yōu)化難以進(jìn)行。

8. 編寫返回數(shù)值的函數(shù)而不是返回指針的函數(shù)

9. 傳遞變量時使用數(shù)值而不是指針或者全局變量

傳遞大結(jié)構(gòu)的數(shù)據(jù)時,才使用指針。每個通過數(shù)值被傳遞的結(jié)構(gòu)都應(yīng)該在函數(shù)調(diào)用入口處被完全拷貝存儲過。

10. 使用變量的地址會使程序性能降低

因為本地變量的地址會引起混淆,這如同全局變量一樣。

11. 用const聲明指針參數(shù)

如果函數(shù)體內(nèi)不會修改到指針指向的對象,就要用const聲明指針參數(shù),這樣可以讓編譯器避免不必要的反面假設(shè)。

12. 使用數(shù)組而不是指針,考慮下面通過指針訪問數(shù)組的代碼

for (i=0; i<100; i++)

*p++ = ...

在每次循環(huán)中,*p被賦值。這種對指針對象的賦值會阻礙優(yōu)化。某些情況下,指針指向它自己,那么這種賦值就會修改指針本身的值,這就會強(qiáng)迫編譯器每次循環(huán)都重新加載該指針。還有,編譯器不能確定這個指針不會被循環(huán)體以外的使用,所以每次循環(huán)外都要依據(jù)增量的數(shù)值更新該指針。因此,最好使用下面的代碼:

for (i=0; i<100; i++)

p[i] = ...

13. 編寫簡單易懂的代碼

編譯器擅長創(chuàng)建復(fù)雜的優(yōu)化,比如函數(shù)嵌入和在適當(dāng)?shù)臅r候循環(huán)體展開。但編譯器不擅長簡化代碼,他們不會合并循環(huán)或者不用函數(shù)嵌入。在源程序中為了支持某些處理器架構(gòu)進(jìn)行的手工的循環(huán)體展開會降低程序的可移植性,因為這阻止了編譯器自動為其他的處理器架構(gòu)進(jìn)行正確的循環(huán)體展開和函數(shù)嵌入。

14. 避免編寫參數(shù)數(shù)量可變的函數(shù)

如果一定要這么做,使用ANSI標(biāo)準(zhǔn)方法:stdarg.h.。使用數(shù)據(jù)表替代if-then-else或者switch分支處理。比如考慮下面代碼:

typedef enum { BLUE, GREEN, RED, NCOLORS } COLOR;

替代

switch (c) {

case CASE0: x = 5; break;

case CASE1: x = 10; break;

case CASE2: x = 1; break;

}

使用

static int Mapping[NCOLORS] = { 5, 10, 1 };

...

x = Mapping[c];

15. 依靠libc函數(shù)庫(比如:strcpy、strlen、strcmp、bcopy、bzero、memset和memcpy)。這些函數(shù)是經(jīng)過精心優(yōu)化的。

表1:一些XCC C/C++編譯器優(yōu)化開關(guān)

本文小結(jié)

編譯器設(shè)計者已經(jīng)開發(fā)了很多復(fù)雜的優(yōu)化功能以使最新的處理器獲得最大的性能,并且他們還在繼續(xù)開發(fā)更智能的優(yōu)化算法。應(yīng)用程序開發(fā)人員可以通過使用恰當(dāng)?shù)?strong>編程規(guī)則來盡可能多地利用編譯器的這些優(yōu)化功能。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉