DSP編程技巧之28---答疑解惑哪家強(qiáng)之(3)
19. 編譯器的優(yōu)化選項(xiàng)那么多,有什么通用的模版可以既快速配置優(yōu)化選項(xiàng),又能達(dá)到較為合適的優(yōu)化效果?
本文引用地址:http://m.butianyuan.cn/article/266191.htm關(guān)于編譯器的優(yōu)化選項(xiàng),我們確實(shí)講了很多(http://m.butianyuan.cn/article/203169.htm和http://m.butianyuan.cn/article/215180.htm,對(duì)很多初學(xué)者來(lái)說(shuō)可能面臨“選擇恐懼癥”。所以我們?nèi)匀挥斜匾贫ㄒ恍┝鞒袒姆桨福奖愦蠹业氖褂?。例如?/p>
1) 把代碼盡可能根據(jù)功能劃分到多個(gè)獨(dú)立的文件中,這樣在優(yōu)化時(shí)可具有更多的級(jí)別供選擇。這樣做不光對(duì)優(yōu)化有好處,對(duì)代碼的模塊化也是有利的。
2) 使能符號(hào)調(diào)試功能--symdebug:dwarf或者 -g
在不啟用優(yōu)化器的情況下,編寫、編譯和調(diào)試代碼,這樣做的目的是在編譯之前首先能保證代碼的功能是正確的。
3) 啟用優(yōu)化功能,并再次驗(yàn)證代碼的功能。如果有需要,還得對(duì)代碼進(jìn)行一定的調(diào)試。
a) 優(yōu)化的級(jí)別有0,1,2和3等不同級(jí)別,對(duì)應(yīng)了不同類型和不同程度的代碼優(yōu)化。
在啟用優(yōu)化的情況下,必須指定優(yōu)化級(jí)別,否則優(yōu)化選項(xiàng)會(huì)被編譯器給忽略,同時(shí)顯示給你一個(gè)警告信息。
優(yōu)化級(jí)別0 (--opt_level=0 或 -o0)是最低程度的優(yōu)化。
優(yōu)化級(jí)別3 (--opt_level=3 或 –o3)是最高程度的優(yōu)化。
Ø 考慮從最低的優(yōu)化級(jí)別開(kāi)始進(jìn)行驗(yàn)證。
b) 從編譯器版本6.0.1開(kāi)始,又添加了優(yōu)化級(jí)別4的支持,即(--opt_level=4 或 -o4)
這個(gè)級(jí)別的優(yōu)化針對(duì)的是鏈接之后的代碼,它在鏈接完成之后,從整個(gè)應(yīng)用程序的角度來(lái)進(jìn)行可能的優(yōu)化,具有進(jìn)一步提高程序性能的潛力。與所有的優(yōu)化選項(xiàng)一樣,為了實(shí)現(xiàn)優(yōu)化的效果,就需要多付出一定的編譯時(shí)間,當(dāng)然這個(gè)時(shí)間花費(fèi)與DSP的代碼效率相比還是值得的。
4) 為了調(diào)試優(yōu)化過(guò)的代碼,需要在使用--opt_level的同時(shí)開(kāi)啟符號(hào)調(diào)試選項(xiàng)-g。這保證了在保持代碼調(diào)試功能的同時(shí),仍然可以實(shí)現(xiàn)最大程度的代碼優(yōu)化。
老版本的編譯器中還可使用-mn選項(xiàng),它可以在開(kāi)啟符號(hào)調(diào)試選項(xiàng)的同時(shí)提供一定的優(yōu)化效果,但是此選項(xiàng)如今已經(jīng)廢止,再使用它不能起到任何效果了。
5) 去掉符號(hào)調(diào)試選項(xiàng)(-g)
a) 在已經(jīng)驗(yàn)證了代碼的功能之后,可以移除符號(hào)調(diào)試選項(xiàng)了。這是因?yàn)殡m然符號(hào)調(diào)試選項(xiàng)對(duì)代碼的效率影響非常小,但是在某些情況下可能會(huì)影響到特定代碼的執(zhí)行。例如,編譯器在使用某些FPU32指令的情況下,可以對(duì)代碼進(jìn)行并行度更高的處理,或者減少NOP空指令的使用,這對(duì)應(yīng)提高代碼運(yùn)行速度是有幫助的;在使用-g選項(xiàng)的情況下,則有可能會(huì)妨礙編譯器充分發(fā)揮這一能力。如果對(duì)稱不是特別“強(qiáng)迫”的話,也可以干脆不去管它。
b) 在比較老版本的編譯器手冊(cè)中,建議在此步驟中使用--symdebug:skeletal選項(xiàng)。但是這是個(gè)已經(jīng)廢棄的參數(shù),不再建議使用,即使使能了也不會(huì)再產(chǎn)生任何效果。
c) 不開(kāi)啟-ss選項(xiàng)。
這個(gè)選項(xiàng)可以把C/C++的表達(dá)式生成交叉列表,以注釋的形式插入到編譯生成的匯編代碼中,方便我們查看/閱讀生成的匯編代碼。這個(gè)功能雖然方便了調(diào)試,但是顯然也妨礙了對(duì)代碼的優(yōu)化。
如果你希望把優(yōu)化器所做的改動(dòng)以注釋的形式插入到編譯生成的匯編代碼中的話,則可以在開(kāi)啟了-g選項(xiàng)的前提下,使用-s選項(xiàng)。如果不使用-g,則-s與-ss的效果是相同的。
20. 為什么開(kāi)啟代碼優(yōu)化之后,程序就無(wú)法實(shí)現(xiàn)正確的功能了?
在開(kāi)啟代碼優(yōu)化之后,代碼中的一些功能有可能會(huì)被編譯器改變,例如:
未初始化的變化會(huì)被優(yōu)化掉;
未正確使用volatile關(guān)鍵詞的變量功能不正常;
與標(biāo)準(zhǔn)ANSI C的結(jié)果有出入
匯編函數(shù)沒(méi)能正確保存/恢復(fù)寄存器的
所以為了保證程序在代碼優(yōu)化之后仍然能正確地執(zhí)行我們的意圖,一定要認(rèn)真閱讀一下相關(guān)編譯器選項(xiàng)的使用說(shuō)明。這其中需要注意的一些典型問(wèn)題,可以參考http://m.butianyuan.cn/article/255842.htm。
21. volatile關(guān)鍵字能對(duì)我們有什么幫助?
volatile提醒編譯器它后面所定義的變量隨時(shí)都有可能改變,因此編譯后的程序每次需要存儲(chǔ)或讀取這個(gè)變量的時(shí)候,都會(huì)直接從變量地址中讀取數(shù)據(jù)。如果沒(méi)有volatile關(guān)鍵字,則編譯器可能優(yōu)化讀取和存儲(chǔ),可能暫時(shí)使用寄存器中的值,如果這個(gè)變量由別的程序更新了的話,將出現(xiàn)不一致的現(xiàn)象。volatile的使用場(chǎng)合可以包括:
在中斷或者別的任務(wù)中會(huì)被修改的變量
可以被硬件改變的外設(shè)寄存器的值
可以被其它處理器所修改的變量的值(用于多核的場(chǎng)合,例如OMAP等)
c++相關(guān)文章:c++教程
評(píng)論