高效的C編程之:C編譯器及其優(yōu)化
如果不生成調(diào)試表,這是默認(rèn)優(yōu)化級(jí)別。
·-O3:最高優(yōu)化級(jí)別。使用該優(yōu)化級(jí)別,使生成的代碼在時(shí)間和空間上尋求平衡。該選項(xiàng)常和-Ospace和-Otime配合使用。
·-O3–Otime:使用該選項(xiàng)編譯的代碼比-O2–Otime選項(xiàng)編譯的代碼,在執(zhí)行速度上要快,但占用的空間也更大。
·-O3-Ospace:產(chǎn)生的代碼比使用-O2-Ospace選項(xiàng)產(chǎn)生的代碼尺寸小,但執(zhí)行效率可能會(huì)差。
如果要使編譯的代碼更側(cè)重于代碼的尺寸或執(zhí)行效率(兩者往往不可兼得),可以使用下面的編譯選項(xiàng)。
·-Ospace:指示編譯程序執(zhí)行優(yōu)化,以延長執(zhí)行時(shí)間為代價(jià)減小映像大小。例如,由外部函數(shù)調(diào)用代替內(nèi)聯(lián)函數(shù)。如果代碼大小比性能更重要,則使用該選項(xiàng)。這是編譯器的默認(rèn)設(shè)置。
·-Otime:指示編譯程序執(zhí)行優(yōu)化,以增大映像大小為代價(jià)縮短執(zhí)行時(shí)間。如果執(zhí)行時(shí)間比代碼大小更重要,則使用該選項(xiàng)。例如,它編譯:
while(expression)body;
為:
if(expression){
dobody;
while(expression);
}
如果既不指定-Otime也不指定-Ospace,則編譯器默認(rèn)使用-Ospace??墒褂?Otime編譯代碼中對時(shí)間要求嚴(yán)格的部分,使用-Ospace編譯其余部分。但不能在同一編譯程序調(diào)用中同時(shí)指定-Otime和-Ospace。
14.1.4AAPCS選項(xiàng)
ARM結(jié)構(gòu)過程調(diào)用標(biāo)準(zhǔn)AAPCS(ProcedureCallStandardfortheARMArchitecture)是ARM體系結(jié)構(gòu)二進(jìn)制接口ABI(ApplicationBinaryInterfacefortheARMArchitecture【BSABI】)標(biāo)準(zhǔn)的一部分。使用該標(biāo)準(zhǔn)可以很方便的執(zhí)行C和匯編語言的相互調(diào)用。
編譯程序時(shí),使用--apcs選項(xiàng)可以指定所使用得AAPCS標(biāo)準(zhǔn)的版本。如果沒有指定--apcs或--cpu選項(xiàng),則編譯器使用下面默認(rèn)編譯選項(xiàng)。
--apcs/noswst/nointer/noropi/norwpi--cpuARM7TDMI--fpusoftvfp
有關(guān)AAPCS的詳細(xì)信息,請參加ARM相關(guān)文檔。
14.1.5編譯選項(xiàng)對代碼生成影響示例
本節(jié)舉例說明編譯器的優(yōu)化選項(xiàng)如何影響代碼生成。
1.使用-O0選項(xiàng)
下面的例子顯示了即使使用-O0編譯選項(xiàng)對代碼進(jìn)行編譯時(shí),有些冗余代碼還是會(huì)被編譯器自動(dòng)清除。
intf(int*p)
{
return(*p==*p);
}
使用armcc-c-O0對源程序進(jìn)行編譯,生成的匯編代碼如下所示。
f
MOVr1,r0
MOVr0,#1
MOVpc,lr
通過上面的例子可以看到,編譯出的最終代碼中沒有加載(Load)指針P的值,變量*p被編譯器優(yōu)化掉了。如果不想讓編譯器對變量*p做優(yōu)化,可以使用“volatile”對變量進(jìn)行聲明。下面的例子,顯示了將變量聲明為“volatile”類型后,使用armcc編譯(-O2的優(yōu)化級(jí)別)后的結(jié)果。
f
LDRr1,[r0]
LDRr0,[r0]
CMPr1,r0
MOVNEr0,#0
MOVEQr0,#1
MOVpc,lr
另外,編譯的代碼中的“MOVr1,r0”并沒有實(shí)際意義,只是為了方便調(diào)試程序時(shí)設(shè)置斷點(diǎn)使用。
2.冗余代碼的清除
下面例子顯示了一段急待優(yōu)化的代碼。
intdummy()
{
inta=10,b=20;
intc;
c=a+b;
return0;
}
當(dāng)使用arm–c–O0進(jìn)行編譯時(shí),產(chǎn)生的匯編碼如下所示。
dummy:
0000807CE3A0100AMOV r1,#0xa
>>>REDUNDANT#3inta=10,b=20;
00008080E3A02014MOV r2,#0x14
>>>REDUNDANT#5c=a+b;
00008084E0813002ADD r3,r1,r2
>>>REDUNDANT#6return0;
00008088E3A00000MOV r0,#0
>>>REDUNDANT#7}
0000808CE12FFF1EBX r14
從上面的匯編輸出可以看到,編譯器并沒有對程序中的冗余變量做任何工作。但上面這段代碼在編譯時(shí),編譯器會(huì)給出警告,警告信息如下所示。
Warning:#550-D:variablecwassetbutneverused
Redundant.cline4intc;
但如果將編譯器的優(yōu)化級(jí)別提高,如使用arm–c–O1命令,則編譯器輸出的匯編代碼如下所示。
dummy:
0000807CE3A00000MOVr0,#0
>>>REDUNDANT#7}
00008080E12FFF1EBXr14
從上面的例子看出,當(dāng)優(yōu)化級(jí)別提高到-O1時(shí),程序中的冗余變量就會(huì)被清除。
c語言相關(guān)文章:c語言教程
評論