日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

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

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

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

編譯器原理

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

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

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

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

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

1. 觀察編譯得到的代碼

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

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

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

void foo(int *a, int *b)

{

int i;

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

*a += b[i];

}

}

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

3. 指針常常引起混淆

編譯器識(shí)別指針指向的目標(biāo)對(duì)象經(jīng)常會(huì)遇到問(wèn)題。程序員可以通過(guò)使用本地變量幫助編譯器去避免混淆,具體方法是使用本地變量去存儲(chǔ)依據(jù)指針訪(fǎng)問(wèn)獲得的值,因?yàn)椴恢苯拥牟僮骱驼{(diào)用影響指針引用的值而不是本地變量的值。因此,編譯器會(huì)把本地變量放到寄存器里面去。

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

int len = 10;

void

zero(char *p)

{

int i;

for (i=0; i

}

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

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è)有資格的指針是唯一訪(fǎng)問(wèn)某內(nèi)存或數(shù)據(jù)對(duì)象的方式。通過(guò)這個(gè)指針的Load和Store操作不會(huì)引起與這個(gè)函數(shù)內(nèi)部其它Load和Store操作的混淆,除非通過(guò)這個(gè)指針的訪(fǎng)問(wèn)。例如:

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. 使用本地變量替代全局變量

這是因?yàn)槿肿兞繒?huì)在整個(gè)程序的生命周期里面保留數(shù)值。編譯器必須認(rèn)為全局變量可能通過(guò)指針被訪(fǎng)問(wèn)。考慮下面的代碼:

int g;

void foo()

{

int i;

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

fred(i,g);

}

}

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

int g;

void foo()

{

int i, local_g=g;

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

fred(i,local_g);

}

}

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

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

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

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

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

8. 編寫(xiě)返回?cái)?shù)值的函數(shù)而不是返回指針的函數(shù)

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

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

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

因?yàn)楸镜刈兞康牡刂窌?huì)引起混淆,這如同全局變量一樣。

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

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

12. 使用數(shù)組而不是指針,考慮下面通過(guò)指針訪(fǎng)問(wèn)數(shù)組的代碼

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

*p++ = ...

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

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

p[i] = ...

13. 編寫(xiě)簡(jiǎn)單易懂的代碼

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

14. 避免編寫(xiě)參數(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ù)庫(kù)(比如:strcpy、strlen、strcmp、bcopy、bzero、memset和memcpy)。這些函數(shù)是經(jīng)過(guò)精心優(yōu)化的。

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

本文小結(jié)

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

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

毋須依賴(lài)實(shí)時(shí)操作系統(tǒng)(RTOS)的全新低功耗藍(lán)牙開(kāi)發(fā)軟件解決方案面世,旨在幫助開(kāi)發(fā)者從傳統(tǒng)nRF5 SDK和nRF52系列輕松遷移至新一代nRF54L系列

關(guān)鍵字: 低功耗藍(lán)牙 SoC SDK

本屆年會(huì)將在上海(11月13-14日)、北京(11月19-20日)和深圳(11月27-28日)舉行,面向嵌入式設(shè)計(jì)工程師推出25門(mén)技術(shù)課程

關(guān)鍵字: 嵌入式 MCU 模擬

上海2025年9月5日 /美通社/ -- 由紐倫堡會(huì)展(上海)有限公司舉辦的上海國(guó)際嵌入式會(huì)議將于 2025 年 10 月 16-17 日在上海世博展覽館舉辦。 此次會(huì)議將由三個(gè)版塊組成:嵌入式技術(shù)會(huì)議、汽...

關(guān)鍵字: 嵌入式 CE CHINA EMBEDDED

從外部看,電子系統(tǒng)仿佛一個(gè)統(tǒng)一的學(xué)科或設(shè)備,各組成部分協(xié)同工作,渾然一體。然而揭開(kāi)表象,其內(nèi)在卻是另一番景象:一個(gè)碎片化、多層次的世界——其中每一層都獨(dú)立且復(fù)雜,衍生出各自特有的工具、專(zhuān)家、工作流程,甚至哲學(xué)體系。

關(guān)鍵字: 嵌入式 電子系統(tǒng) 半導(dǎo)體

8位單片機(jī)在嵌入式設(shè)計(jì)領(lǐng)域已經(jīng)成為半個(gè)多世紀(jì)以來(lái)的主流選擇。盡管嵌入式系統(tǒng)市場(chǎng)日益復(fù)雜,8位單片機(jī)依然不斷發(fā)展,積極應(yīng)對(duì)新的挑戰(zhàn)和系統(tǒng)需求。如今,Microchip推出的8位PIC?和AVR?單片機(jī)系列,配備了先進(jìn)的獨(dú)立...

關(guān)鍵字: 單片機(jī) 嵌入式 CPU

深圳2025年8月28日 /美通社/ -- 8月26日,2025 ELEXCON深圳國(guó)際電子展盛大啟幕。本屆大會(huì)以"All for AI"為主題,深圳市德...

關(guān)鍵字: AI 工業(yè)級(jí) SSD 嵌入式

深圳2025年8月26日 /美通社/ -- 8月26日,由博聞創(chuàng)意會(huì)展主辦的 第22屆深圳國(guó)際電子展暨嵌入式展(elexcon2025)在深圳(福田)會(huì)展中心隆重開(kāi)幕。 作為中國(guó)電子與嵌入式技術(shù)領(lǐng)域的專(zhuān)業(yè)大展,本屆展會(huì)...

關(guān)鍵字: 嵌入式 電子 高通 AI

Puttshack 的 Trackaball 以 Nordic nRF54L15 系統(tǒng)級(jí)芯片 (SoC) 監(jiān)控傳感器并實(shí)現(xiàn)低功耗藍(lán)牙連接,并以nPM2100 電源管理集成電路(PMIC)節(jié)省耗電

關(guān)鍵字: SoC 傳感器 集成電路

2025年8月21日 – 專(zhuān)注于引入新品的全球電子元器件和工業(yè)自動(dòng)化產(chǎn)品授權(quán)代理商貿(mào)澤電子 (Mouser Electronics) 即日起開(kāi)售Silicon Labs全新xG26系列無(wú)線(xiàn)SoC和MCU。xG26片上系統(tǒng)...

關(guān)鍵字: SoC 微控制器 物聯(lián)網(wǎng)

模塊化設(shè)計(jì)作為一種將系統(tǒng)拆分為獨(dú)立、可復(fù)用組件的方法,能夠在低代碼平臺(tái)中實(shí)現(xiàn)功能的靈活組合,并最大限度地提升系統(tǒng)性能。本文將探討如何通過(guò)模塊化設(shè)計(jì),使得低代碼平臺(tái)既能快速適應(yīng)變化,又能保持高效穩(wěn)定的運(yùn)行。

關(guān)鍵字: 模塊化設(shè)計(jì) 嵌入式
關(guān)閉