




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、ARM編程技巧,Agenda,ARM 編譯器優(yōu)化 C/C+和匯編混合模式編程 使用ARM編譯器編碼 局部和全局?jǐn)?shù)據(jù)討論,優(yōu)化級別,使用的編譯器優(yōu)化級別是可選擇的 -O0-DEBUG 關(guān)閉大多數(shù)優(yōu)化. 最好的調(diào)試信息,最少的優(yōu)化 -O1-DEBUGREL 多數(shù)優(yōu)化選項許可 給一個滿意的調(diào)試,好的代碼密度 -O2-RELEASE (default) 完全的優(yōu)化 有限的調(diào)試信息,最好的代碼密度 為代碼大小或運行速度的優(yōu)化,可選擇: -Ospace (默認(rèn)的)或 -Otime. 使用-g 選像可包含源碼級調(diào)試信息,ADS 編譯器在所有級別中執(zhí)行一些簡單的優(yōu)化 i.e. -O0, -O1, -O2 下面
2、是一個例子:即使用-O0,多余的表達(dá)式也被清除了: ATPCS標(biāo)準(zhǔn)中子程序結(jié)果返回規(guī)則 結(jié)果為32位整數(shù),R0返回 結(jié)果為64位整數(shù),R0,R1返回 位數(shù)更多時,用內(nèi)存來傳遞 ,自動優(yōu)化,int f(int *p) return (*p = = *p); ,armcc -c -O0,f MOV r1, r0 MOV r0, #1 MOV pc, lr,注意:在這種情況下,可使用C的關(guān)鍵字volatile 強制使用這些變量,使用 “volatile”,int f(volatile int *p) return (*p = = *p); ,armcc -c,f LDR r1,r0 LDR r0,r
3、0 CMP r1,r0 MOVNE r0,#0 MOVEQ r0,#1 MOV pc,lr,int f(int *p) return (*p = = *p); ,f MOV r0,#1 MOV pc,lr,armcc -c,這個代碼用的編譯級別是:-o2,下面是一個冗余代碼清除的例子,他只用了-o1的優(yōu)化選項:,冗余代碼的清除,int dummy() int a=10, b=20; int c; c=a+b; return 0; ,armcc -c -O1,dummy MOV r0, #0 MOV pc, lr,指令編排,指令編排在高級優(yōu)化選項中是有效的(-O1, -O2). 指令的重新編排是
4、為了使要運行的代碼更適合對應(yīng)的核 為arm9和以后的處理器提高吞吐量(一般可達(dá)到4%),并防止互鎖(interlock) 選擇處理器可決定使用的運算法則,在默認(rèn)情況下,使用針對ARM9的優(yōu)化方案 (對ARM7的運行沒有影響) 例如: int f(int *p, int x) return *p + x * 3; 沒用指令編排 (-O0)使用指令編排 (-O1,-O2) ADD r1,r1,r1,LSL #1LDR r0,r0,#0LDR r0,r0,#0ADD r1,r1,r1,LSL #1ADD r0,r0,r1; interlock on ARM9ADD r0,r0,r1MOV pc,lr
5、MOV pc,lr,armcc cpu arm7tdmi,armcc cpu arm9tdmi,Tail-call Optimization,嵌套優(yōu)化可避免在函數(shù)級里的不必要的返回 在可能的情況下BL 譯碼成B 在高級優(yōu)化里有效(-O1, -O2).,int main()int x = f();:,int f()int y = g();return y;,int g()return 10;,嵌套優(yōu)化,內(nèi)嵌函數(shù)(inline),內(nèi)嵌可通過刪除子函數(shù)調(diào)用的開銷來提高性能 這個 inline 關(guān)鍵字顯示哪個函數(shù)將被內(nèi)嵌 在高級優(yōu)化選項中,ADS 1.2 編譯器默認(rèn)自動內(nèi)嵌 -Oautoinline
6、(default -O2) -Ono_autoline (default for -O0,-O1) 哪個函數(shù)是否被內(nèi)嵌取決于: 他們是否被 _inline標(biāo)示 優(yōu)化的級別 -Otime / -Ospace 函數(shù)被調(diào)用的次數(shù) 如果函數(shù)在別的模塊中不被調(diào)用,一個好的建議是用static標(biāo)識函數(shù),否則,編譯器將在內(nèi)嵌譯碼里把該函數(shù)編譯乘非內(nèi)嵌的 加代碼的長度 使調(diào)試信息更復(fù)雜,Example.,Inline example,內(nèi)嵌例子,Agenda,ARM編譯器的優(yōu)化 C/C+和匯編混合模式編程 使用ARM編譯器編碼 局部和全局?jǐn)?shù)據(jù)討論,C和匯編的混合編程,C/C+ 和匯編能很容易的混合: 可實現(xiàn)在c
7、中無法實現(xiàn)的處理器功能 使用新的或不支持的指令 產(chǎn)生更高效的代碼 直接鏈接變量和程序 確定符合程序調(diào)用規(guī)范 輸入/輸出相關(guān)的符號 編譯器也可包含內(nèi)嵌匯編 大多數(shù)arm指令集都可實現(xiàn) 寄存器操作數(shù)可支持任意的c/c+的表達(dá)式 內(nèi)嵌匯編代碼可由編譯器的優(yōu)化器來傳遞,ATPCS(arm/thumb程序調(diào)用規(guī)范),r8,r9/sb,r10/sl,r11,r12,r13/sp,r14/lr,r15/pc,r0,r1,r2,r3,r4,r5,r6,r7,寄存器變量 必須保護,作為函數(shù)傳遞的參數(shù)值,Scratch register (corruptible),Stack PointerLink Regist
8、er Program Counter,編譯器使用一套規(guī)則的來設(shè)置寄存器的用法 ARM-Thumb Procedure Call Standard or ATPCS (or APCS) CPSR 標(biāo)志位可被函數(shù)調(diào)用所破壞 任何和編譯過的代碼交互工作的匯編碼在接口層必 須滿足ATPCS的規(guī)范,Register,- 如果 RWPI選項有效,作為棧的基地址,- 如果軟件堆棧檢查有效,作為棧的限制值,- 可作為臨時的一個值棧一樣來使用,- 子程序內(nèi)部調(diào)用的可改寫的寄存器,- 程序計數(shù)器,在C程序中調(diào)用匯編,在匯編程序中用export name來定義 在C程序中直接調(diào)用,用EXTERN聲明 正常鏈接,ex
9、tern void mystrcopy(char *d, const char *s); int main(void) const char *src = “Source”; char dest10; . mystrcopy(dest, src); . ,AREA StringCopy, CODE, READONLY EXPORT mystrcopy mystrcopy LDRB r2, r1, #1 STRB r2, r0, #1 CMP r2, #0 BNE mystrcopy MOV pc, lr END,這里所有的參數(shù)都是可以用寄存器來傳遞的,所以不需要在匯編程序中使用PUSH/POP
10、來保護,CALL,內(nèi)嵌匯編,允許使用一些不能由編譯器自動生成的指令: MSR / MRS 新的指令 協(xié)處理器指令 通常在關(guān)聯(lián)的內(nèi)嵌函數(shù)中使用 使用C變量代替寄存器 不是一個真正的匯編文件 通過優(yōu)化器實現(xiàn) ADS FAQ 入口 “Using the Inline Assembler”,#define Q_Flag 0 x08000000 / Bit 27 _inline void Clear_Q_flag (void) int temp; _asm MRS temp, CPSR BIC temp, temp, #Q_Flag MSR CPSR_f, temp _inline int mult16
11、(short a, short b, int c) int temp; _asm SMLABB temp,a,b,c return temp; ,Agenda,ARM編譯器的優(yōu)化 C/C+和匯編混合模式編程 使用ARM編譯器編碼 局部和全局?jǐn)?shù)據(jù)討論,參數(shù)傳遞,開始四個字大小的參數(shù)直接使用寄存器的R0-R3來傳遞(快速且高效的) 更多的信息可參看ATPCS 如果需要更多的參數(shù),將使用堆棧。(需要額外的指令和慢速的存儲器操作) 所以通常限制參數(shù)的個數(shù),使它為4或更少。 如果不可避免,把常用的參數(shù)前4個放在R0-R3中,Example.,Parameter Passing (4 parameters
12、) int func1(int a, int b, int c, int d) return a+b+c+d; int caller1(void) return func1(1,2,3,4); ,func1 0 x000000 : ADD r0,r0,r1 0 x000004 : ADD r0,r0,r2 0 x000008 : ADD r0,r0,r3 0 x00000c : MOV pc,lr caller1 0 x000014 : MOV r3,#4 0 x000018 : MOV r2,#3 0 x00001c : MOV r1,#2 0 x000020 : MOV r0,#1 0 x
13、000024 : B func1,Parameter Passing (4 parameters),Parameter Passing (6 parameters),Parameter Passing (6 parameters),func2 0 x000000 : STR lr, sp,#-4! 0 x000004 : ADD r0,r0,r1 0 x000008 : ADD r0,r0,r2 0 x00000C : ADD r0,r0,r3 0 x000010 : LDMIB sp,r12,r14 0 x000014 : ADD r0,r0,r12 0 x000018 : ADD r0,r
14、0,r14 0 x00001C : LDR pc,sp,#4 caller2 0 x000020 : STMFD sp!,r2,r3,lr 0 x000024 : MOV r3,#6 0 x000028 : MOV r2,#5 0 x00002C : STMIA sp,r2,r3 0 x000030 : MOV r3,#4 0 x000034 : MOV r2,#3 0 x000038 : MOV r1,#2 0 x00003C : MOV r0,#1 0 x000040 : BL func2 0 x000044 : LDMFD sp!,r2,r3,pc,int func2(int a,int
15、 b,intc, int,d,int e,int f) return a+b+c+d+e+f; int caller2(void) return func1(1,2,3,4,5,6); ,This code is compiled with “-O2 -Ono_autoinline”,循環(huán)終止,在for(), while() dowhile()的循環(huán)中,用減到0代替加到某個值。 比如,用下面的代替 : for (loop = 1; loop = total; loop+) /(ADD,CMP) 代替為: for (loop = total; loop != 0; loop-) /(SUBS)
16、盡量減少循環(huán)的次數(shù) 代碼小,且使用更少的寄存器,Example.,Loop Termination,Count up int fact1(int limit) int i; int fact = 1; for (i = 1; i = limit; i+) fact = fact * i; return fact; ,Count down int fact2(int limit) int i; int fact = 1; for (i = limit; i != 0; i-) fact = fact * i; return fact; ,fact2 0 x000000 : MOVS r1,r0
17、0 x000004 : MOV r0,#1 0 x000008 : MOVEQ pc,lr 0 x00000c : MUL r0,r1,r0 0 x000010 : SUBS r1,r1,#1 0 x000014 : BNE 0 x0c 0 x000018 : MOV pc,lr,fact1 0 x000000 : MOV r2,#1 0 x000004 : MOV r1,#1 0 x000008 : CMP r0,#1 0 x00000c : BLT 0 x20 0 x000010 : MUL r2,r1,r2 0 x000014 : ADD r1,r1,#1 0 x000018 : CMP
18、 r1,r0 0 x00001c : BLE 0 x10 0 x000020 : MOV r0,r2 0 x000024 : MOV pc,lr,This code is compiled with “-O2 -Otime”,除法操作(1),ARM核不含除法硬件 除法通常用一個運行庫函數(shù)來實現(xiàn) 運行需要很多的周期,unsigned div(unsigned a, unsigned b) return (b / a); ,div B _rt_udiv,unsigned div2(unsigned b) return (b / 2); ,div2 MOV r0,r0,LSR #1 MOV pc,l
19、r,一些除法操作在編譯時作為特例來處理 除2操作,被左移代替,除法操作 (2),在 -O1和-O2 (使用 -Otime), 其他的常量將使用一個標(biāo)準(zhǔn)的乘法序列來完成 例如: 實時除法程序 使用CLZ指令 只有V5te體系結(jié)構(gòu)才有效。 用下面的辦法來選擇 C - #pragma import _use_realtime_division Assembler - IMPORT _use_realtime_division,div10 MOV r1,r0 LDR r0,=0 xCCCCCCCD UMULL r2,r1,r0,r1 MOV r0,r1,LSR #3 MOV pc,lr,unsigne
20、d div10(unsigned c) return (c / 10); ,余數(shù) 模算法,余數(shù)的操作符 %, 通常使用模算法 如果這個值的模不是2的n次冪,它將花費大量的時間和代碼空間 避免這種情況發(fā)生的辦法使用if()作狀態(tài)檢查 比如說:count的范圍是0到59 count = (count+1) % 60; 用下面的句子代替 if (+count = 60) count = 0;,modulo ADD r1,r0,#1 MOV r0,#0 x3c BL _rt_udiv MOV r0,r1,test_and_reset ADD r0,r0,#1 CMP r0,#0 x3c MOVCS r
21、0,#0,這個代碼用“-O1 -Ospace”編譯,浮點,軟件浮點庫 (fplib) 默認(rèn):-fpu softvfp (or softfpa) 浮點協(xié)處理器 VFP (ARM10 and ARM9) -fpu vfp (or vfpv1 or vfpv2) FPA (eg ARM7 500fe) - now obsolete -fpu fpa 軟件浮點仿真 (FPE) 通過未定義的異常來捕獲協(xié)處理器指令 VFP (and FPA) 實際上是硬件協(xié)處理器和仿真的混合 要求支持代碼去實現(xiàn)混合運算 在AFS 1.3 和以后的版本里有VFP的 支持代碼, 在ADS的FPA里. 在thumb代碼使用fp
22、處, vfp系統(tǒng)用-fpu softvfp+vfp編譯 使用 -auto_float_constants 預(yù)防常量被處理為雙精度類型,關(guān)閉警告用 -Wk.,Example.,float foo(float num1, float num2) float temp, temp2; temp = num1 + num2; temp2 = num2 * num2; return temp2-temp; ,Floating point examples,Agenda,ARM 編譯器優(yōu)化 C/C+和匯編混合模式編程 使用ARM編譯器編碼 局部和全局?jǐn)?shù)據(jù),變量類型,全局和靜態(tài)變量保留在RAM里 需使用lo
23、ads/stores訪問外部存儲器 局部變量通常放在寄存器中,用來快速且高效的處理 如果編譯器的寄存器分配算法認(rèn)為超過現(xiàn)有的寄存器數(shù)量,將把變量壓入棧中 對局部變量,用 word-sized (int) 代替 halfword 和 byte: 為了確保不受其他條件的影響,可特別指定使用32-bit寄存器變量.,int wordsize(int a) wordsize 0 x000000 : MOV r0,r0,LSL #1 return (a*2); 0 x000004 : MOV pc,lr short halfsize(short b) halfsize 0 x000008 : MOV r
24、0,r0,LSL #17 return (b*2); 0 x00000c : MOV r0,r0,ASR #16 0 x000010 : MOV pc,lr char bytesize(char c) bytesize 0 x000014 : MOV r0,r0,LSL #25 return (c*2); 0 x000018 : MOV r0,r0,LSR #24 0 x00001c : MOV pc,lr,變量大小,堆棧的用法,C/C+代碼的堆棧使用,堆棧用來保留: 子程序的返回地址 溢出的局部變量 局部數(shù)組和結(jié)構(gòu)體 注意: 函數(shù)越小越好: (更少的變量,更少的溢出); 更少數(shù)量的live變
25、量 (比如:函數(shù)里每個點保存的有用的數(shù)據(jù)) 避免使用大的局部結(jié)構(gòu)體或數(shù)組 (使用malloc/free代替) 避免遞歸,堆棧使用估計,鏈接使用 -callgraph 顯示靜態(tài)堆棧的開銷(html文件). 編譯時使用軟件堆棧檢查 -apcs /swst 在棧結(jié)束點設(shè)置 watchpoint 測試堆棧 定義大的棧 填充某個值,看覆蓋了多少,從而判定棧的使用情況 ARMulator映射文件 拒絕訪問棧下面的區(qū)域,棧溢出將導(dǎo)致一個data abort異常 stackuse.c ARMulator模式, 跟蹤堆棧的大小,用ARMulator的統(tǒng)計來輸出報告,當(dāng)要對堆棧使用情況進(jìn)行估計時,使用worst
26、case,全局?jǐn)?shù)據(jù)布局,char one; short two; char three; int four;,char,short,char,e.g. 聲明的數(shù)據(jù),Declared alignment 12 bytes (4 bytes of padding),Optimal alignment 8 bytes (Zero bytes of padding),ADS 1.1+ 將自動 用此風(fēng)格排序,short,全局?jǐn)?shù)據(jù)保存在存儲器里,不是寄存器 需要load / store指令來訪問 用物理尺寸的邊界對齊 ADS 1.2 會優(yōu)化在一個模塊里的全局?jǐn)?shù)據(jù)的布局 用-Ono_data_reorder
27、 將關(guān)閉排序,不對齊訪問,ARM硬件需要在自然尺寸的邊界訪問內(nèi)存 Word訪問在word尺寸 Halfword訪問在halfword尺寸 Byte訪問在byte尺寸 不對齊訪問 遺留代碼 特定協(xié)議 需要必須告訴編譯器,讓它產(chǎn)生適當(dāng)?shù)闹噶钚蛄?使用 _packed 屬性 可能導(dǎo)致多字節(jié)訪問代替單字節(jié)訪問 用LDM指令的結(jié)果有2 字,轉(zhuǎn)變?yōu)樯蓡巫?不對齊數(shù)據(jù)的訪問所產(chǎn)生的意外的結(jié)果取決于指令的使用 將是不可預(yù)知的,指針的對齊,必須非常小心指針的對齊 可能導(dǎo)致程序的失敗,#include int *a = (int *)0 x1000;int *b = (int *)0 x2000;char *c
28、 = (char *)0 x3001;_packed int *d;void foo (void) memcpy (b,a,12); memcpy (c,a,12); b = (int *)c; memcpy (b,a,12); d = (_packed int *)c; memcpy (void *)d,a,12);,STMFD r13!,r4,r14 LDR r4,0 x58 LDR r1,r4,#0 LDR r0,r4,#4 LDMIA r1,r2,r3,r12 STMIA r0,r2,r3,r12 LDR r0,r4,#8 LDR r1,r4,#0 MOV r2,#0 xc BL _r
29、t_memcpy LDR r0,r4,#8 STR r0,r4,#4 LDR r1,r4,#0 LDMIA r1,r2,r3,r12 STMIA r0,r2,r3,r12 LDR r0,r4,#8 LDR r1,0 x5c MOV r2,#0 xc STR r0,r1,#0 LDR r1,r4,#0 BL _rt_memcpy LDMFD r13!,r4,pc,結(jié)構(gòu)的打包,在結(jié)構(gòu)里定義打包的元素代替結(jié)構(gòu)的打包 他將幫助減小訪問輸出的結(jié)構(gòu)的開銷 ADS FAQ 入口: Aligned v. unaligned accesses and use of _packed,_packed struct mystruct int aligned_i; short aligned_s; int unaligned_i; ; extern struct mystruct S;,short,int,U_int,
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 萬達(dá)廣場股權(quán)轉(zhuǎn)讓合同范例
- 典當(dāng)寄售合同范例
- 公司間戰(zhàn)略合同范例
- 上海寶馬5系購車合同范本
- 供鋼材合同范例
- 產(chǎn)品購銷簡易合同范例
- 債權(quán)性投資合同范本
- 債務(wù)抵押合同范例
- 農(nóng)家樂租賃合同范例
- 養(yǎng)殖基地養(yǎng)雞合同范例
- 客戶溝通技巧與客戶投訴處理培訓(xùn)課件
- 完整版臨時用水用電施工方案
- 江蘇省南通市2025屆高三第一次調(diào)研測試數(shù)學(xué)試題(南通一模)(含答案)
- 【課件】進(jìn)出口貨物報關(guān)單填制
- Codesys培訓(xùn)課件教學(xué)課件
- 2024-2030年中國菊粉行業(yè)發(fā)展?fàn)顩r及競爭力研究報告
- 合成生物學(xué)研發(fā)平臺與年產(chǎn)200噸合成生物制品項目可行性研究報告寫作模板-申批備案
- (2024)河南省公務(wù)員考試《行測》真題及答案解析
- 創(chuàng)傷性凝血病救治
- 中央紀(jì)委國家監(jiān)委機關(guān)直屬單位招聘工作人員筆試真題2023
- 臨床超聲引導(dǎo)下中等長度導(dǎo)管置管臨床實踐
評論
0/150
提交評論