<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > C代碼在TMS320C54X上的手工匯編優(yōu)化

C代碼在TMS320C54X上的手工匯編優(yōu)化

作者: 時(shí)間:2008-06-05 來(lái)源:網(wǎng)絡(luò ) 收藏

1引言

隨著(zhù)DSP技術(shù)的不斷發(fā)展和完善,數字信號處理的應用范圍越來(lái)越廣泛。工控、計算機、通信和消費電子產(chǎn)品中,都會(huì )找到它的影子。近年來(lái),隨著(zhù)多媒體通信的蓬勃發(fā)展,DSP也越來(lái)越多的應用在多媒體通信中,而在多媒體通信中DSP多用于語(yǔ)音壓縮和圖像處理等方面,而這些都需要巨大的計算量,在實(shí)時(shí)通信中一些低速DSP難以滿(mǎn)足要求,而使用高速DSP會(huì )大大提高成本,所以對進(jìn)行是現在DSP開(kāi)發(fā)中常用的一種方法。由于DSP的特殊結構,編譯器的編譯效率都比較低,難以將DSP計算能力全部發(fā)揮出來(lái),所以就必須根據DSP的特殊結構和指令集進(jìn)行。

本文結合筆者在TI公司的TMS320VC5402DSP上的對G.729算法的經(jīng)驗,提出一些優(yōu)化的方法和建議,而這些方法也適用其他54系列的DSP。


2芯片介紹

是TI公司于1996年推出的新一代定點(diǎn)數字處理器,它具有功耗小、高度并行等優(yōu)點(diǎn),可以滿(mǎn)足電信等眾多領(lǐng)域的實(shí)時(shí)處理要求。54系列有很多不同型號的芯片,它們的結構都是一樣的,只是在接口和存儲器空間上有些不同。在54系列眾多DSP芯片中TMS320VC5402是使用最廣泛的一種芯片,接下來(lái)將以TMS320VC5402為例介紹54系列DSP的性能特點(diǎn):

●運算速度最高達100MIPS
●具有先進(jìn)的多總線(xiàn)結構,三條16位數據存儲器總線(xiàn)和一條程序存儲器總線(xiàn)
●40位算術(shù)邏輯單元(ALU),包括一個(gè)40位桶形移位器和兩個(gè)40位累加器
●一個(gè)17bit17bit乘法器和40位專(zhuān)用加法器,允許16位帶/不帶符號乘法
●8個(gè)輔助寄存器和一個(gè)軟件棧
●內部采用改進(jìn)的哈佛結構,程序空間和數據空間分開(kāi),允許同時(shí)取指令和取操作數,并且允許在程序和數據空間相互傳送數據
●最大64K16bit外部數據空間,最大1M16bit外部程序空間,4K16bit片內ROM,16K16bit片內RAM
●內置可編程等待狀態(tài)發(fā)生器、鎖相環(huán)(PLL)時(shí)鐘發(fā)生器、兩個(gè)多通道緩沖串口、一個(gè)8位并行與外部處理器通信的HPI口、兩個(gè)16位定時(shí)器以及6通道DMA控制器
●支持單指令循環(huán)和塊循環(huán),采用六級流水線(xiàn),將一條指令執行所需要的取指、譯碼、取操作數并執行等幾個(gè)步驟同時(shí)完成,是指令周期降到最小適合算法的優(yōu)化

3優(yōu)化

對C代碼進(jìn)行優(yōu)化有三種方法:1.對照C代碼寫(xiě)出代碼,這種方法優(yōu)化的效率很高,但是開(kāi)發(fā)難度很大特別是當代碼量很大,結構很復雜時(shí)優(yōu)化很容易出錯;2.先用編譯器產(chǎn)生匯編代碼,然后改寫(xiě)匯編代碼,這種方法優(yōu)化的效率較低,因為框架被限定了,但是開(kāi)發(fā)難度降低了,不容易出錯。
由于現在常用的一些音頻、圖像處理算法都是結構很復雜的程序,所以建議使用第二種優(yōu)化方法。

3.1產(chǎn)生匯編代碼

TI公司為DSP開(kāi)發(fā)者提供一套編譯開(kāi)發(fā)平臺叫CCS(CodeComposerStudio),該工具提供了編譯器可以將C語(yǔ)言的程序編譯為DSP的匯編語(yǔ)言程序,然后鏈接生成可以在DSP上執行的COFF格式的out文件。

產(chǎn)生匯編代碼

而CCS自身也提供優(yōu)化器可對C代碼進(jìn)行優(yōu)化,并產(chǎn)生匯編語(yǔ)言程序,具體過(guò)程如圖1所示。

CCS提供了4級的文件優(yōu)化方案,分別是O0、O1、O2、O3,以下具體說(shuō)明
。
(1)O0寄存器級別

●執行控制流程簡(jiǎn)化
●用寄存器分配變量
●執行交替循環(huán)
●排除未用的代碼
●簡(jiǎn)化公式和表述
●擴大對內連函數的調用

(2)O1局部級別

執行所有O0級別的優(yōu)化,并且:

●執行局部常量的傳播
●排除未用的賦值
●排除局部共用表達式

(3)O2函數級別

執行所有O1級別的優(yōu)化,并且:

●執行循環(huán)優(yōu)化
●排除全局共用子表達式
●排除全局不用的賦值
●執行打開(kāi)循環(huán)

(4)O3文件級別

執行所有O1級別的優(yōu)化,并且:

●排除未被調用的函數
●簡(jiǎn)化返回值沒(méi)被使用的函數
●讓小函數變成內聯(lián)調用
●保存函數說(shuō)明,以便主函數被優(yōu)化時(shí)知道被調用函數的屬性
●識別文件級別的變量的特性

在使用O3級別的優(yōu)化時(shí),還可以使用別的選項執行更細致的優(yōu)化

●OLN得到標準庫函數的文件
●ONN創(chuàng )造優(yōu)化信息文件
●PM執行程序級別優(yōu)化,編譯多個(gè)源文件


而我們在做優(yōu)化時(shí),選的是O2級別的優(yōu)化,因為使用O2級別優(yōu)化后產(chǎn)生的匯編文件帶有比較多的注釋信息,比較容易看懂程序,建議對程序不太熟和對匯編語(yǔ)言不太熟練的人使用。

3.2匯編優(yōu)化

因為匯編語(yǔ)言可讀性很差,并且代碼量很大,所以手工優(yōu)化工作量很大,并且容易出錯。為了確保優(yōu)化不出錯,我們就先制作一段測試序列即程序的輸入,然后運行程序對其進(jìn)行處理,生成一段正確的結果序列,檢驗手工優(yōu)化是否正確就是用優(yōu)化過(guò)的程序對相同的測試序列進(jìn)行處理,比較生成的結果序列和正確的結果序列是否一樣,一樣的話(huà)就代表優(yōu)化無(wú)誤。不過(guò)測試序列要比較長(cháng),因為有的錯誤開(kāi)始不會(huì )顯現出來(lái),只是慢慢累積,運行一段時(shí)間才會(huì )出現。

接下來(lái),就開(kāi)始手工優(yōu)化的工作。下面就是我對手工優(yōu)化的一些經(jīng)驗。

(1)盡量少進(jìn)行函數調用。因為進(jìn)行函數調用的時(shí)候,要將PC壓棧,還要將一些寄存器壓棧,函數調用完后,還要出棧,這都是一些不必要的操作,所以一些小的函數,就不調用,而是直接寫(xiě)入主函數里,這樣可以就可以減少那些壓棧出棧的操作,提高速度。

(2)優(yōu)化循環(huán)時(shí),盡量將一些操作放到循環(huán)外面去,減少操作的次數。例如一些賦值和初始化操作,可以提到循環(huán)外面去做,來(lái)提高速度。

(3)去除一些冗余的賦值。編譯器產(chǎn)生的代碼有很多賦值,經(jīng)常將一個(gè)值賦給寄存器,再賦給變量,這樣就產(chǎn)生了冗余。

(4)盡量使用RPT和RPTB來(lái)執行循環(huán)操作。在編譯器產(chǎn)生的代碼里很多循環(huán)操作是通過(guò)條件判別來(lái)實(shí)現的,這樣就多了很多無(wú)用的判別代碼,而54x的DSP芯片就提供專(zhuān)門(mén)的循環(huán)指令:RPT和RPTB。RPT的功能就是循環(huán)執行下一條指令,循環(huán)次數由RC寄存器的值決定,循環(huán)次數是RC寄存器的值加1,所以執行循環(huán)前要將循環(huán)次數減1賦給RC寄存器;RPTB是塊循環(huán)指令,它的功能是循環(huán)執行一段指令,它的循環(huán)次數由BRC寄存器決定,循環(huán)次數是BRC的寄存器的值加1,所以使用前需將循環(huán)次數減1賦給BRC寄存器。

(5)使用比較快的尋址方式。在數字信號處理里面,會(huì )對大量的數據進(jìn)行大量的運算,如果使用比較快的尋址方式會(huì )大大減少指令周期。因為數據大多是順序存放,所以我們用寄存器去尋址,操作完后自加1而指向下個(gè)數據,這樣尋址會(huì )減少很多指令周期。

(6)使用循環(huán)緩沖區。因為FFT,FIR等常用運算中都需要對數據進(jìn)行移位操作,如果數據量大的話(huà),程序花在數據移位上的開(kāi)銷(xiāo)就很大了,如果使用循環(huán)緩沖區就可以不進(jìn)行這些操作從而提高速度。

(7)使用一些專(zhuān)用指令。在54的指令系統里,有一些專(zhuān)用指令執行一些特殊的操作,例如平方,FIR等,如果用其他指令代替需要多個(gè)指令周期,而使用專(zhuān)用指令值需要一個(gè)指令周期。

(8)使用并行指令。因為DSP的流水線(xiàn)結構,可以讓一些指令同時(shí)運行,就產(chǎn)生了并行指令,使用并行指令會(huì )大大減少指令周期。

(9)將一些常用的程序和數據,放在片內RAM運行。DSP芯片上一般都帶有RAM,而片內RAM的尋址速度比片外RAM快一至兩倍,所以將常用程序和數據放在片內,會(huì )大大提高運行速度。

3.3優(yōu)化中常遇見(jiàn)的問(wèn)題

在手工優(yōu)化過(guò)程時(shí)會(huì )遇到很多問(wèn)題,以下幾點(diǎn)比較常見(jiàn)。

(1)對一些寄存器的設置。因為是手工優(yōu)化,所以對一些寄存器都要自己賦值,例如ST0、ST1和PMST等,不同的設置會(huì )導致運算結果的不一樣。其中一些用的比較多的位有SXM、OVM和FRCT。SXM是符號擴展位,如果SXM=0就不進(jìn)行符號擴展,如果SXM=1就進(jìn)行符號擴展(見(jiàn)圖2a)。OVM是溢出模式位,當發(fā)生溢出時(shí),如果OVM=0溢出的結果就被送往目的寄存器,如果OVM=1就往目的寄存器送最大的正數(007FFFFFFFh)或最小的負數(FF80000000h)。FRCT是小數模式位,當FRCT=1時(shí)乘法的結果會(huì )左移一位(見(jiàn)圖2b)。以上3個(gè)標志位的置位和復位是由SSBX和RSBX指令來(lái)完成的。

例子

(2)注意流水線(xiàn)沖突。5402的芯片有一個(gè)6級深度的指令流水線(xiàn),這6級流水線(xiàn)彼此是獨立的,在任何一個(gè)機器周期內,可以有1至6條不同的指令在工作。這6級流水線(xiàn)的功能分別是預取指、取指、譯碼、尋址、讀數和執行。C5402多級流水線(xiàn)操作可以讓多條指令同時(shí)指令訪(fǎng)問(wèn)CPU資源,如果多個(gè)流水線(xiàn)同時(shí)訪(fǎng)問(wèn)到相同的資源,就可能發(fā)生流水線(xiàn)沖突,有些沖突可以由CPU通過(guò)延遲尋址的方法自動(dòng)緩解,而有的沖突是不能防止的,需要由程序重新安排指令或插入空操作來(lái)解決。當用CCS編譯器對C程序進(jìn)行編譯的時(shí)候,編譯器會(huì )自動(dòng)加入NOP指令來(lái)解決流水線(xiàn)沖突,而進(jìn)行手工優(yōu)化的時(shí)候,就要特別注意這個(gè)問(wèn)題,大部分流水線(xiàn)沖突都是因為同時(shí)訪(fǎng)問(wèn)到某些寄存器,只要根據等待周期表加入相應的NOP指令就可以解決。

例子

(3)對一些參數的保存。在手工優(yōu)化的過(guò)程中,我們會(huì )用某些寄存器來(lái)傳遞數據,而在此過(guò)程中,如果調用了別的函數,這些寄存器的值就有可能被改變,所以在調用這些函數的時(shí)候,要先將這些參數壓棧保存,調用完后再將其出?;謴?。還有就是某些標志位的保存,因為在調用函數的過(guò)程會(huì )改變這些狀態(tài)標志位,所以在調用完后要將其恢復。

(4)循環(huán)緩沖區地址分配問(wèn)題。循環(huán)緩沖區的地址分配必須對齊,長(cháng)度為R的緩沖區必須從N位地址的邊界開(kāi)始(即循環(huán)緩沖區基地址的N個(gè)最低有效位必須為0),N是滿(mǎn)足2N>R的最小的整數。例如,長(cháng)度R=31的循環(huán)緩沖區必須從地址XXXXXXXXXXX000002(N=5,25>>31,該地址的最低5位為0)。

(5)內存泄漏問(wèn)題。因為DSP使用的是哈佛結構,數據空間和程序空間是分開(kāi)的,一般數據的操作不會(huì )影響到程序。但是DSP芯片上都帶有RAM,而這些空間數據和程序是共享的,所以對該部分的數據進(jìn)行操作,如果有泄漏的話(huà)會(huì )改寫(xiě)程序,導致程序跑飛。因此程序跑飛的話(huà),就要考慮是否有內存泄漏。

4結論

以上經(jīng)驗和技巧均是筆者在實(shí)際的DSP工程中總結得出,實(shí)踐證明對實(shí)際開(kāi)發(fā)非常有幫助。以筆者對G.729算法優(yōu)化為例,在優(yōu)化之前,G.729的運算量為1000MIPS,優(yōu)化后的運算量為30MIPS,提高了30多倍,可見(jiàn)優(yōu)化的效果很明顯。以上這些經(jīng)驗主要是針對TI公司的54系列,但對于別的型號的DSP也有借鑒作用。

參考文獻

1彭啟琮.實(shí)用教程.電子科技大學(xué)出版社,2000
2戴明楨.數字信號處理器結構、原理及應用.TIDSPSUNIVERSITY,2000



評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>