版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、第4章 TMS320C6000系列DSP程序開發(fā)4.14.24.34.44.54.6TMS320C6000系列DSP的C/C+語言特點TMS320C6000系列DSP的C/C+語言關(guān)鍵字pragma偽指令初始化靜態(tài)變量和全局變量TMS320C6000系列DSP的C/C+代碼優(yōu)化C/C+語言和匯編語言的混合編程第1頁,共49頁。4.1 TMS320C6000系列DSP的C/C+語言特點4.1.1 TMS320C6000系列DSP的C語言特點1標(biāo)識符和常量標(biāo)識符的所有字符都是有意義的并且區(qū)分大小寫,此特征適用于內(nèi)部和外部的所有標(biāo)識符;源(主機(jī))和執(zhí)行(目標(biāo))字符集為ASCII碼,不存在多字節(jié)字符;
2、字符常量或者字符串常量中的十六進(jìn)制或者八進(jìn)制轉(zhuǎn)義序列或者字符串常量具有高達(dá)32位的值;具有多個字符的字符常量按序列中的最后一個字符編碼,例如:abc=c。第2頁,共49頁。4.1.1 TMS320C6000系列DSP的C語言特點2數(shù)據(jù)類型表4-1列出了TMS320C6000編譯器中各種標(biāo)量數(shù)據(jù)類型、位數(shù)表示方式及取值范圍,許多取值范圍的值可以作為頭文件limits.h中的標(biāo)準(zhǔn)宏使用。類 型位 數(shù)表示方式取值范圍最小值最大值char,signed charunsigned charshortunsigned shortint,signed intunsigned intlong,signed l
3、ongunsigned longenumfloatdoublelong doublepointers,references,pointer to data members8 bits8 bits16 bits16 bits32 bits32 bits40 bits40 bits32 bits32 bits64 bits64 bits32 bitsASCIIASCII2s complementBinary2s complementBinary2s complementBinary2s complementIEEE 32-bitIEEE 64-biiIEEE 64-bitBinary-1280-3
4、2 7680-2 147 483 6480-549 755 813 8880-2 147 483 6481. 175 494e-382. 22 507 385e-3082. 22 507 385e-308012725532 76765 5352 147 483 6474 294 967 295549 755 813 8871 099 511 627 7752 147 483 6473.40 282 346e+381.79 769 313e+3081.79 769 313e+3080 xFFFFFFFF第3頁,共49頁。4.1.1 TMS320C6000系列DSP的C語言特點3數(shù)據(jù)轉(zhuǎn)換(1)浮點
5、類型到整型的轉(zhuǎn)換,截取0前面的整數(shù)部分。(2)指針類型和整數(shù)類型之間可以自由轉(zhuǎn)換。4表達(dá)式(1)當(dāng)兩個帶符號的整數(shù)相除時,如果其中有一個為負(fù),則商為負(fù),余數(shù)的符號與分子的符號相同。斜杠(/)用來求商,百分號(%)用來求余數(shù)。例如:10/-3=-3,-10/3=-310%-3=1,-10%3=-1(2)有符號數(shù)的右移為算術(shù)移位,即保留符號。第4頁,共49頁。4.1.1 TMS320C6000系列DSP的C語言特點5聲明(1)寄存器存儲類對所有的charsshortinteger和pointer類型有效。(2)結(jié)構(gòu)體成員被打包為字。(3)整數(shù)類型的位段帶有符號,位段被打包為從高位開始的字,并且不能
6、超越字的邊界。(4)中斷關(guān)鍵字interrupt只能用于沒有參數(shù)的void型函數(shù)。6預(yù)處理器預(yù)處理器忽略任何不支持的#pragma偽指令。第5頁,共49頁。4.1.2 TMS320C6000系列DSP的C+語言特點TMS320C6000系列DSP編譯器支持ISO標(biāo)準(zhǔn)的C+語言,但與標(biāo)準(zhǔn)的C+又存在不同的特點:(1)并不包括完整的C+標(biāo)準(zhǔn)庫支持,但是包括C子集和基本的語言支持。(2)支持C的庫工具(C library facilities)的頭文件不包括:,。(3)所包括的C+標(biāo)準(zhǔn)庫頭文件為和。(4)對bad_cast和bad_type_id的支持并不包括在typeinfo文件中。(5)不支持異
7、常事件的處理。(6)默認(rèn)情況下,禁止運行時類型的信息(RTTI)。RTTI允許在運行時確定各種類型的對象。它可以使用-rtti編譯選項來使能。(7)如果兩個類不相關(guān),reinterpret_cast類型指向其中一個類成員的指針,不允許這個指針再指向另一個類的成員。(8)不支持標(biāo)準(zhǔn)中tesp.res和temp.dep里描述的“在模板中綁定的二相名”。(9)不能實現(xiàn)模板參數(shù)。(10)不能實現(xiàn)模板的export關(guān)鍵字。(11)用typedef定義的函數(shù)類型不包括成員函數(shù)cv-qualifiers。(12)類成員模板的部分說明不能放在類定義的外部。第6頁,共49頁。4.2 TMS320C6000系列D
8、SP的C/C+語言關(guān)鍵字1const關(guān)鍵字(1)如果在一個對象定義的同時也指定了關(guān)鍵字volatile(如: volatile const int x),volatile關(guān)鍵字被分配到RAM(程序不會修改一個const volatile 的對象,但是程序外部的對象可能會被修改);(2)對象是auto存儲類型(在堆棧中分配)。在以上的兩種情況下,為對象分配存儲空間與不使用const關(guān)鍵字時是相同的。在一個定義中使用const關(guān)鍵字很重要,例如,下面代碼的第一句定義了常量指針p為一個整型的變量,第二句定義了一個變量指針q為一個整型常量:int *const p &x;const int*q &x;
9、使用const關(guān)鍵字,用戶可以定義大常量表并將他們分配到系統(tǒng)ROM中。例如,分配一個ROM表,可以使用如下的定義:far const int digits = 0,1,2,3,4,5,6,7,8,9;第7頁,共49頁。4.2 TMS320C6000系列DSP的C/C+語言關(guān)鍵字2cregister關(guān)鍵字當(dāng)對一個對象使用cregister關(guān)鍵字時,編譯器將比較對象名和TMS320C6000的標(biāo)準(zhǔn)控制寄存器列表,如果名字匹配,編譯器將參照控制寄存器產(chǎn)生相應(yīng)的代碼。如果不匹配,編譯器將產(chǎn)生一個錯誤??刂萍拇嫫髁斜硪姳?-2。寄 存 器描 述寄 存 器描 述AMRCSRFADCRFAUCRFMCRGF
10、PGFRICR尋址模式寄存器控制狀態(tài)寄存器(僅C6700)浮點加法器配置寄存器(僅C6700)浮點輔助配置寄存器(僅C6700)浮點乘法器配置寄存器(僅C6400)Galois域多項式產(chǎn)生函數(shù)寄存器中斷清除寄存器IERIFRIRPISRISTPNRP中斷使能寄存器中斷標(biāo)記寄存器中斷返回指針中斷設(shè)置寄存器中斷服務(wù)表指針不可屏蔽中斷返回指針第8頁,共49頁。4.2 TMS320C6000系列DSP的C/C+語言關(guān)鍵字一旦聲明該寄存器,用戶就能夠直接使用該寄存器名。下例為控制寄存器的聲明和使用:【例4.1】 定義和使用控制寄存器。extern cregister volatile unsigned
11、int AMR;extern cregister volatile unsigned int CSR;extern cregister volatile unsigned int IFR;extern cregister volatile unsigned int ISR;extern cregister volatile unsigned int ICR;extern cregister volatile unsigned int IER;extern cregister volatile unsigned int FADCR;extern cregister volatile unsign
12、ed int FAUCR;extern cregister volatile unsigned int FMCR;main() printf(”AMR = %xn”, AMR);第9頁,共49頁。4.2 TMS320C6000系列DSP的C/C+語言關(guān)鍵字3interrupt關(guān)鍵字當(dāng)用戶將interrupt關(guān)鍵字使用到函數(shù)的定義上時,編譯器會按照中斷函數(shù)要求的寄存器保存規(guī)則和中斷返回的特殊順序去保存寄存器,然后生成特殊的返回代碼序列。用戶可以將interrupt關(guān)鍵字和定義為void但沒有參數(shù)的函數(shù)一起使用。中斷函數(shù)體可以具有局部變量和自由的使用堆?;蛘呷肿兞?。如:interrupt voi
13、d int_handler()unsighed int flags;.第10頁,共49頁。4.2 TMS320C6000系列DSP的C/C+語言關(guān)鍵字4near和far關(guān)鍵字語法上,near和far關(guān)鍵字被看做存儲類別的變址數(shù)。它們出現(xiàn)在存儲類別說明符和類型的前、后和中間。這兩個存儲器類別的變址數(shù)不能用于一個定義中。正確的使用實例代碼如下:far static int x;static near int x;static int far x;far int foo();static far int foo();第11頁,共49頁。4.2 TMS320C6000系列DSP的C/C+語言關(guān)鍵字5r
14、estrict關(guān)鍵字【例4.2】 對指針使用關(guān)鍵字restrict。void func1(int* restrict a,int *restrict b) /*此處為函數(shù)func1()的代碼*/該例代碼中關(guān)鍵字restrict的使用告訴編譯器func1中的指針a和b指向的存儲器范圍不會交迭,即指針變量a和b對存儲器的訪問不會沖突,對一個指針變量的寫操作不會影響另一個指針變量的讀操作?!纠?.3】 對數(shù)組使用關(guān)鍵字restrict。void func2(int crestrict, int drestrict)int i ; for (i = 0 ;i 64;i +)/計算數(shù)組的累加和以及數(shù)組d
15、i的加1操作 ci += di;di += 1;第12頁,共49頁。4.2 TMS320C6000系列DSP的C/C+語言關(guān)鍵字6volatile關(guān)鍵字優(yōu)化器分析數(shù)據(jù)流,盡可能地避免存儲器的訪問。如果用戶將依賴于存儲器訪問的代碼寫在C/C+程序中,則必須使用volatile關(guān)鍵字以識別這種訪問。編譯器不會優(yōu)化任何對volatile變量的引用。下面的代碼中,循環(huán)等待一個讀為oxFF的單元:unsigned int *ctrl;while(*ctrl!=oxFF);該代碼中,*ctrl是一個循環(huán)不變的表達(dá)式,因此該循環(huán)被優(yōu)化為一個單存儲器讀。為了改正這些優(yōu)化,可以定義*ctrl為:volatile
16、 unsigned int * ctrl第13頁,共49頁。4.2 TMS320C6000系列DSP的C/C+語言關(guān)鍵字7asm語句TMS320C6000的C/C+編譯器可以將TMS320C6000匯編指令或者偽指令直接嵌入編譯器輸出的匯編語言文件。該功能是對C/C+語言的擴(kuò)展,即asm語句。asm語句提供了C/C+語言所不能提供的對硬件的訪問。asm語句類似于調(diào)用一個名為asm的函數(shù),該語句以一個字符串常數(shù)為參數(shù),具體語法格式:asm(“assembler text”);編譯器將參數(shù)直接復(fù)制到編譯器的輸出文件,匯編正文必須包含在雙引號內(nèi)。所有通常的字符串都保持它們原來的定義。例如,可插入一個
17、包含引號的.string偽指令:asm(“str: .string”abc“”);第14頁,共49頁。4.3 pragma偽指令pragma偽指令告訴編譯器如何處理特定的函數(shù)、對象或者代碼段。TMS320C6000的C/C+編譯器支持下面的偽指令:CODE_SECTIONDATA_ALIGNDATA_MEM_BANKDATA_SECTIONFUNC_CANNOT_INLINEFUNC_EXT_CALLEDFUNC_INTERRUPT_THRESHOLDFUNC_IS_PUREFUNC_IS_SYSTEMFUNC_NEVER_RETURNSFUNC_NO_GLOBAL_ASGFUNC_NO_IN
18、D_ASGINTERRUPTMUST_ITERATENMI_INTERRUPTPROB_ITERATESTRUCT_ALIGNUNROLL第15頁,共49頁。4.3 pragma偽指令1CODE_SECTION指令CODE_SECTION指令用于為命名段中的符號指定空間。該指令在C語言中的語法格式為:#pragma CODE_SECTION (symbol, ”section name”);該指令在C+語言中的語法格式為:#pragma CODE_SECTION (”section name”);【例4.4】 CODE_SECTION指令使用。C源文件:#pragma CODE_SECTION
19、(fn, ”my_sect”)int fn(int x)return x;第16頁,共49頁。4.3 pragma偽指令此例使用#pragma CODE_SECTION(fn,my_sect),產(chǎn)生my_sect段,并把fn函數(shù)指定到my_sect段。匯編源文件:.sect ”my_sect”.global _fn;*;* FUNCTION NAME: _fn *;* *;* Regs Modified : SP *;* Regs Used : A4,B3,SP *;* Local Frame Size : 0 Args + 4 Auto + 0 Save = 4 byte *;*_fn:;*
20、RET .S2 B3 ; |6|SUB .D2 SP,8,SP ; |4|STW .D2T1 A4,*+SP(4) ; |4|ADD .S2 8,SP,SP ; |6|NOP 2; BRANCH OCCURS ; |6|第17頁,共49頁。4.3 pragma偽指令2DATA_SECTION指令DATA_SECTION指令為命名的段中符號指定空間。該指令在C語言中的語法格式為:#pragma DATA_SECTION (symbol, “section name”);該指令在C+語言中的語法格式為:#pragma DATA_SECTION (“section name”);第18頁,共49頁。
21、4.3 pragma偽指令【例4.5】 DATA_SECTION指令的使用。C源文件:#pragma DATA_SECTION(bufferB, ”my_sect”)char bufferA512;char bufferB512;C+源文件:char bufferA512;#pragma DATA_SECTION(”my_sect”)char bufferB512;匯編源文件:.global _bufferA.bss _bufferA,512,4.global _bufferB_bufferB: .usect ”my_sect”,512,4第19頁,共49頁。4.3 pragma偽指令3DAT
22、A_ALIGN指令DATA_ALIGN指令把符號對齊到邊界。對齊的邊界是符號默認(rèn)的最大界值或常量,常量是2的整數(shù)次冪。該指令在C語言中的語法如下:#pragma DATA_ALIGN (symbol, constant);該指令在C+中的語法如下:#pragma DATA_ALIGN (constant);4FUNC_CANNOT_INLINE指令FUNC_CANNOT_INLINE指令通知編譯器,該命名的函數(shù)不能擴(kuò)展為直接插入。任何使用pragma命令的函數(shù)會忽略由其他方式指定的直接插入。該指令必須出現(xiàn)在對函數(shù)的任何聲明和引用之前。該指令在C語言中的語法格式為:#pragma FUNC_CA
23、NNOT_INLINE (func);該指令在C+語言中的語法格式為:#pragma FUNC_CANNOT_INLINE;第20頁,共49頁。4.3 pragma偽指令5FUNC_EXT_CALLED指令FUNC_EXT_CALLED指令指定優(yōu)化器保持這些C/C+函數(shù)或任何由這些C/C+函數(shù)調(diào)用的函數(shù)。這些函數(shù)充當(dāng)C/C+的入口點。該指令必須出現(xiàn)在對函數(shù)的任何聲明和引用之前。在C中,F(xiàn)UNC_EXT_CALLED指令的語法格式如下:#pragma FUNC_EXT_CALLED (func);在C+中,F(xiàn)UNC_EXT_CALLED指令的語法格式如下:#pragma FUNC_EXT_CAL
24、LED;第21頁,共49頁。4.3 pragma偽指令6FUNC_IS_PURE指令FUNC_IS_PURE指令通知優(yōu)化器,該指令命名的函數(shù)沒有負(fù)面效果,允許優(yōu)化做以下的工作:(1)如果函數(shù)的值不需要的話,刪除對函數(shù)的調(diào)用。(2)刪除重復(fù)的函數(shù)。該指令必須出現(xiàn)在對函數(shù)的任何聲明和應(yīng)用之前。在C中,該指令的語法格式為:#pragma FUNC_IS_PURE (func);在C+中,該指令的語法格式為:#pragma FUNC_IS_PURE;第22頁,共49頁。4.3 pragma偽指令7FUNC_IS_SYSTEM指令例如,它可以對多函數(shù)所使用的寄存器做出假定。不能在已經(jīng)修改過的ISO函數(shù)中
25、使用該指令。該指令必須出現(xiàn)在對函數(shù)的任何聲明和引用之前。在C語言中,該指令的語法格式為:#pragma FUNC_IS_SYSTEM (func);在C+語言中,該指令的語法格式為:#pragma FUNC_IS_SYSTEM;第23頁,共49頁。4.3 pragma偽指令8FUNC_NEVER_RETURNS指令FUNC_NEVER_RETURNS指令通知優(yōu)化器,在所有的情況下,函數(shù)不會返回到它的調(diào)用處。例如,一個無限循環(huán)的函數(shù)調(diào)用exit(),將不會返回到調(diào)用處。當(dāng)一個函數(shù)被該指令標(biāo)記后,編譯器不會產(chǎn)生一個函數(shù)的結(jié)束。該指令必須出現(xiàn)在對函數(shù)的任何聲明和引用之前。在C語言中,該指令的語法格式
26、為:#pragma FUNC_NEVER_RETURNS (func);在C+語言中,該指令的語法格式為:#pragma FUNC_NEVER_RETURNS;第24頁,共49頁。4.3 pragma偽指令9FUNC_NO_GLOBAL_ASG指令FUNC_NO_GLOBAL_ASG指令通知優(yōu)化器,該函數(shù)不會給已經(jīng)定義的全局變量賦值并且不會包含任何asm語句。該指令必須出現(xiàn)在對函數(shù)的任何聲明和引用之前。在C中該指令的語法格式如下:#pragma FUNC_NO_GLOBAL_ASG (func);在C中該指令的語法格式如下:#pragma FUNC_NO_GLOBAL_ASG;第25頁,共49
27、頁。4.3 pragma偽指令10FUNC_NO_IND_ASG指令FUNC_NO_IND_ASG指令通知優(yōu)化器函數(shù)不會通過指針進(jìn)行賦值且不包含任何asm語句。該指令必須出現(xiàn)在對函數(shù)的任何聲明和引用之前。在C語言中,該指令的語法格式如下:#pragma FUNC_NO_IND_ASG (func);在C+語言中,該指令的語法格式如下:#pragma FUNC_NO_IND_ASG;第26頁,共49頁。4.3 pragma偽指令11INTERRUPT指令I(lǐng)NTERRUPT指令允許用戶直接在C代碼中處理中斷。在C語言中,該指令的語法格式如下:#pragma INTERRUPT (func);在C+
28、語言中,該指令的語法格式如下:#pragma INTERRUPT;第27頁,共49頁。4.4 初始化靜態(tài)變量和全局變量如果加載器不預(yù)初始化變量,則可以使用連接器在目標(biāo)文件中將變量預(yù)初始化為0。例如,在鏈接命令文件中,在.bss段中填充0值,代碼如下:SECTIONS.bss: fill = 0 x00;第28頁,共49頁。4.4 初始化靜態(tài)變量和全局變量帶有常數(shù)類型限定詞const的靜態(tài)和全局變量的處理方法與其他類型的靜態(tài)變量和全局變量不同。沒有明確初始化const的靜態(tài)和全局變量與其他靜態(tài)和全局變量是類似的,因為它們沒有被預(yù)初始化為0,例如:const int zero;/*不一定初始化為0
29、*/然而,由于常量是在名為.const的段中進(jìn)行聲明和初始化的,因此常數(shù)、全局和靜態(tài)變量的初始化是不同的,例如:const int zero = 0;/*保證初始化為0*/對應(yīng)于.const段的入口:. .sect .const_zero. .word 0第29頁,共49頁。4.5 TMS320C6000系列DSP的C/C+代碼優(yōu)化4.5.1 C/C+代碼的編寫1數(shù)據(jù)類型當(dāng)編寫C代碼時,需要對數(shù)據(jù)類型的尺寸仔細(xì)的考慮。TMS320C6000編譯器的每種數(shù)據(jù)類型尺寸如下(包括有符號和無符號類型):(1)char(字符型):bit(2)short(短整型):16bit(3)int(整型):32bi
30、t(4)long(長整型):40bit(5)float(浮點型):32bit(6)double(雙精度型):64bit第30頁,共49頁。4.5.1 C/C+代碼的編寫基于每種數(shù)據(jù)類型的尺寸,在編寫C代碼時應(yīng)遵循以下的規(guī)則:(1)避免在代碼中將int和long類型作為相同的尺寸來處理,因為TMS320C6000編譯器對long類型的數(shù)據(jù)使用40位操作。(2)對于定點乘法輸入,應(yīng)盡可能使用short類型的數(shù)據(jù),因為該數(shù)據(jù)類型為TMS320C6000的16位乘法器提供最有效的使用。(3)對循環(huán)計數(shù)器使用int或者unsigned int數(shù)據(jù)類型,而不使用short或者unsigned short類
31、型,避免不必要的符號擴(kuò)展指令。第31頁,共49頁。4.5.1 C/C+代碼的編寫2分析C代碼的性能使用以下手段可以分析特定代碼段的性能:(1)代碼性能的主要衡量方法之一是代碼運行所占用的時間。使用C語言中clock()和printf()函數(shù)具有計時和顯示特定代碼的功能,為了達(dá)到這一目的,利用獨立的軟件模擬器運行這段代碼。(2)利用動態(tài)調(diào)試器(debugger)中的profile模式,可以得到一個關(guān)于代碼中特定代碼段執(zhí)行情況的統(tǒng)計表。(3)使用動態(tài)調(diào)試器中的中斷clk寄存器和RUNB命令可以跟蹤特定代碼段所占用的CPU時鐘周期數(shù)。(4)在代碼中影響性能的主要代碼段通常是循環(huán)。優(yōu)化一個循環(huán),最容易
32、的方法是抽出此循環(huán),使之成為一個單獨的可重新編寫編譯和運行的文件。第32頁,共49頁。4.5.2 編譯C/C+代碼編譯工具包括一個外殼程序(cl6x),用于編譯匯編優(yōu)化匯編和程序連接。要激活編譯外殼程序,輸入如下:cl6x options filenames z linker options object files(1)如果編譯器不能確定兩條指令是否獨立,假設(shè)它們相關(guān)并且順序安排這兩條指令。(2)如果編譯器能確定兩條指令是獨立的,將安排它們并行執(zhí)行。通常編譯器很難確定訪問存儲器的指令是否獨立,以下的方法可以幫助編譯器確定指令是否獨立。(3)使用關(guān)鍵字const標(biāo)識變量的存儲單元不會被函數(shù)改變
33、。const表示一個變量或者變量的存儲單元保持不變。盡可能使用const是編寫代碼的較好方法,因為它使用簡單且可以提高代碼的性能。(4)聯(lián)合使用-pm選項和-o3選項可確定程序級優(yōu)化,所有的源文件都被編譯成稱為模塊的中間文件。由于編譯器訪問到整個程序,因此它可以執(zhí)行幾個在文件級優(yōu)化中很少用的優(yōu)化手段。(5)使用-mt選項是向編譯器說明,在代碼中不存在存儲器相關(guān)性,即允許編譯器在無存儲器相關(guān)性的假設(shè)下改進(jìn)優(yōu)化。第33頁,共49頁。4.5.2 編譯C/C+代碼下面通過舉例說明存儲器相關(guān)性的概念。例4.6給出了基本矢量和C代碼,圖4-1給出了其相關(guān)圖。第34頁,共49頁。4.5.3 優(yōu)化C代碼1使用
34、內(nèi)嵌函數(shù)TMS320C6000提供的內(nèi)嵌函數(shù)是一種直接映射為內(nèi)嵌TMS320C6000匯編指令的特殊函數(shù),可以快速優(yōu)化C/C+代碼。內(nèi)嵌函數(shù)用下劃線(_)開頭,使用方法同調(diào)用普通函數(shù)一樣?!纠?.7】 沒有內(nèi)嵌函數(shù)的飽和加法。int sadd(int a, int b)int result;result = a + b;if (a b) & 0 x80000000) = 0)if (result a) & 0 x80000000)result = (a 0) ? 0 x80000000 : 0 x7fffffff;return (result);【例4.8】 使用內(nèi)嵌函數(shù)的飽和加法。resul
35、t = _sadd(a,b);第35頁,共49頁。4.5.3 優(yōu)化C代碼2軟件流水軟件用于安排循環(huán)指令,使循環(huán)的多次迭代以并行方式執(zhí)行。當(dāng)使用編譯器的-o2和-o3選項時,編譯器使用軟件流水優(yōu)化源代碼并且從程序中收集相關(guān)的優(yōu)化信息。圖4-2為循環(huán)的軟件流水示意圖。第36頁,共49頁。4.5.3 優(yōu)化C代碼(1)循環(huán)計數(shù)下例分別為優(yōu)化前后的代碼:原始代碼: for (i = 0; i N; i+) /* i = 循環(huán)計數(shù)變量, N = 循環(huán)次數(shù) */優(yōu)化后代碼:for (i = N; i != 0; i) /* 逆序計數(shù) */(2)消除冗余循環(huán)有時編譯器不能夠確定循環(huán)是否總是執(zhí)行大于最小循環(huán)次數(shù)
36、,因此,編譯器將會產(chǎn)出兩種版本的循環(huán): 如果循環(huán)計數(shù)值小于最小循環(huán)次數(shù),則執(zhí)行非軟件流水循環(huán)版本; 如果循環(huán)計數(shù)值等于或大于最小循環(huán)次數(shù),則執(zhí)行軟件流水的版本。激活編譯器時可以使用以下的選項將循環(huán)次數(shù)傳給編譯器:用-o3和-pm選項允許優(yōu)化器訪問整個程序或者部分,了解循環(huán)次數(shù)信息;使用-nassert內(nèi)核防止冗余循環(huán)的產(chǎn)生,或者允許編譯器(使用或者未使用-ms選項)軟件流水最內(nèi)層循環(huán)以減少代碼量。第37頁,共49頁。4.5.3 優(yōu)化C代碼(3)循環(huán)展開有3種循環(huán)展開的方式: 編譯器可以自動進(jìn)行循環(huán)展開; 可以通過UNROLL偽指令建議編譯器進(jìn)行循環(huán)展開; 可以自己循環(huán)展開C/C+代碼?!纠?.
37、9】 三個存儲器操作的矢量加運算。void vecsum2(short *restrict sum, const short *restrict in1, const short *restrictin2, unsigned int N) int i; for (i = 0; i N; i+) sumi = in1i + in2i;/循環(huán)計算in1i 與 in2i的矢量和第38頁,共49頁。4.5.3 優(yōu)化C代碼【例4.10】 字對齊矢量和。void vecsum4(short *restrict sum, const short *restrict in1,const short *rest
38、rict in2, unsigned int N) int i; #pragma MUST_ITERATE (10); for (i = 0; i (N/2); i+) _amem4(&sumi) = _add2(_amem4_const(&in1), _amem4_const(&in2i); 第39頁,共49頁。4.5.3 優(yōu)化C代碼(4)投機(jī)執(zhí)行(-mh選項)在循環(huán)嵌套中,只對內(nèi)層的循環(huán)進(jìn)行軟件流水。軟件流水的限制如下:軟件流水可以包含內(nèi)核函數(shù),不能包含函數(shù)的調(diào)用;循環(huán)中不能有條件中斷;循環(huán)中不能有遞增循環(huán)計數(shù)器;循環(huán)體內(nèi)不能修改循環(huán)計數(shù)器,因為在循環(huán)中修改循環(huán)計數(shù)器不能將其轉(zhuǎn)換為遞減計數(shù)
39、的循環(huán);循環(huán)代碼量不能過大,因為代碼量過大,需要的寄存器超過TMS320C6000的規(guī)定個數(shù)不能進(jìn)行軟件流水;寄存器的值生命周期不能太長,否則不能進(jìn)行軟件流水;循環(huán)中不能有復(fù)雜的條件代碼,如果過于復(fù)雜則循環(huán)不能進(jìn)行軟件流水。第40頁,共49頁。4.6 C/C+語言和匯編語言的混合編程4.6.1 在C/C+代碼中調(diào)用匯編語言模塊C/C+代碼可以訪問定義在匯編語言中的變量和調(diào)用函數(shù),并且匯編代碼可以訪問C/C+的變量和調(diào)用C/C+的函數(shù)。匯編語言和C/C+語言接口需遵循如下的規(guī)則:所有的函數(shù),無論是使用C/C+語言編寫還是匯編語言編寫,都必須遵循寄存器的規(guī)定。必須保存寄存器A10A15、B3和B1
40、0B15,同時還要保存A3。如果使用常規(guī)的堆棧,則不需要明確保存堆棧。換句話說,只要任何被壓入堆棧的值在函數(shù)返回之前被彈回,匯編函數(shù)就可以自由使用堆棧。任何其他寄存器都可以自由使用而無需首先保存它們。中斷程序必須保存它們使用的所有寄存器。當(dāng)從匯編語言中調(diào)用一個C/C+函數(shù)時,第一個參數(shù)必須保存到指定的寄存器,其他的參數(shù)置于堆棧中。記住,只有A10A15和B10B15被編譯器保存。C/C+函數(shù)能修改任何其他寄存器的內(nèi)容。第41頁,共49頁。4.6.1 在C/C+代碼中調(diào)用匯編語言模塊函數(shù)必須根據(jù)C/C+的聲明返回正確的值。整型和32位的浮點值返回到A4中。雙精度、長雙精度、長整型返回到A5:A4
41、中。結(jié)構(gòu)體的返回是將它們復(fù)制到A3的地址。除了全局變量的自動初始化外,匯編模塊不能使用.cinit段。在C/C+啟動程序假定.cinit段完全由初始化表組成。將其他的信息放入.cinit中將破壞表,并產(chǎn)生不可預(yù)料的結(jié)果。編譯器將連接名分配到所有的擴(kuò)展對象。因此,當(dāng)編寫匯編代碼時,必須使用編譯器分配的相同的連接名。任何在匯編語言中定義的在C/C+語言中訪問或者調(diào)用的對象或者函數(shù),都必須以.def或者.global偽指令聲明。這樣可以將符號定義為外部符號并允許連接器對它識別引用。第42頁,共49頁。4.6.1 在C/C+代碼中調(diào)用匯編語言模塊【例4.11】 C/C+語言調(diào)用匯編函數(shù)。C程序:extern ”C” extern int asmfunc(int a);/* 聲明外部函數(shù)*/ int gvar = 4; /* 定義全局變量 */void main() int i = 5; i = asmfun
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 產(chǎn)品售后服務(wù)合同協(xié)議
- 上海市租賃合同(新版)
- 臨時借調(diào)員工合同
- 運輸集裝箱合同協(xié)議書
- 上海市軟件外包服務(wù)合同示范文本(標(biāo)準(zhǔn)版)
- 專業(yè)技術(shù)培訓(xùn)合作合同范本
- 個人對個人借款合同模板其一
- 東部沿海地區(qū)采購代理合同
- 個人借款合同模板(無抵押)
- 個人門面租賃合同標(biāo)準(zhǔn)范文
- 五年級數(shù)學(xué)(小數(shù)乘除法)計算題專項練習(xí)及答案匯編
- 2024年蘇州農(nóng)業(yè)職業(yè)技術(shù)學(xué)院高職單招語文歷年參考題庫含答案解析
- 2025年北京生命科技研究院招聘筆試參考題庫含答案解析
- GB/T 27697-2024立式油壓千斤頂
- 《消防機(jī)器人相關(guān)技術(shù)研究》
- 游泳館安全隱患排查
- 《媒介社會學(xué)》課件
- 成人手術(shù)后疼痛評估與護(hù)理團(tuán)體標(biāo)準(zhǔn)
- zemax-優(yōu)化函數(shù)說明書
- 2021年《民法典擔(dān)保制度司法解釋》適用解讀之擔(dān)保解釋的歷程
- 第02講 導(dǎo)數(shù)與函數(shù)的單調(diào)性(學(xué)生版)-2025版高中數(shù)學(xué)一輪復(fù)習(xí)考點幫
評論
0/150
提交評論