基于網(wǎng)絡(luò )的嵌入式IP可視電話(huà)設計方案
第3階段是編寫(xiě)線(xiàn)性匯編代碼 從C代碼中抽出對性能影響很大的代碼段,用線(xiàn)性匯編重新編寫(xiě)這段代碼,然后使用匯編優(yōu)化器優(yōu)化該代碼。
2.1 C代碼的開(kāi)發(fā)和優(yōu)化
開(kāi)發(fā)過(guò)程中要充分利用Tl公司為用戶(hù)提供的功能強大的函數庫,比如IMAGE.LIB庫中就包含許多常用函數,可以實(shí)現DCT/IDCT變換、DCT量化、自適應濾波等功能。這些函數都是優(yōu)化過(guò)的,完全能夠實(shí)現軟件流水,效率很高。另外,開(kāi)發(fā)C語(yǔ)言代碼還需要考慮的要點(diǎn)包括:① 使用適當的數據結構- - 對定點(diǎn)乘法,應盡可能使用short型數據;對循環(huán)計數器應使用int或者無(wú)符號int 類(lèi)型。②使用查找表或常數值代替通過(guò)直接計算得到結果的語(yǔ)句或函數。
代碼分析結果顯示DCT、IDCT 、運動(dòng)估計占程序總運算量的比重很大,因此這部分是程序優(yōu)化的重點(diǎn)。優(yōu)化C 代碼包括使用編譯器選項、使用內聯(lián)函數、使用軟件流水等。
(1)向編譯器指明不相關(guān)的指令。
為使指令并行操作,編譯器必須確定指令間的相關(guān)性,只有不相關(guān)的指令才可并行執行。若編譯器不能確定兩條指令是不相關(guān)的,則只能安排它們串行執行。用戶(hù)可通過(guò)如下方法指明相關(guān)的指令:
①關(guān)鍵字cons t 表示一個(gè)變量或一個(gè)變量的存儲單元保持不變,使用const 可提高代碼的性能和適應性。
②使用-mt 選項向編譯器說(shuō)明在代碼中不存在存儲器相關(guān)性,即允許編譯器在無(wú)存儲器相關(guān)性的假設下進(jìn)行優(yōu)化。
(2)使用內聯(lián)函數(intrinsics)。
可用內聯(lián)函數快速優(yōu)化C 代碼。如在算術(shù)操作中,常對計算的結果做飽和(saturation)處理,使用intrinsics只須調用SADD, 一個(gè)指令周期便可得到最終結果。比花費兩個(gè)嵌套的條件判斷語(yǔ)句來(lái)判斷結果是否溢出,最后得到結果效率要高得多。
(3)使用軟件流水。
在編譯時(shí),使用-o2 選項和-o3 選項,編譯器可對循環(huán)代碼實(shí)現軟件流水。為填滿(mǎn)軟件流水線(xiàn),軟件流水結構需要執行的最小循環(huán)迭代次數稱(chēng)為最小循環(huán)次數。循環(huán)總數小于最小循環(huán)次數時(shí),執行不流水形式循環(huán); 循環(huán)總數大于最小循環(huán)次數時(shí),執行軟件流水形式循環(huán)??梢允褂?ms 選項,使編譯器根據循環(huán)次數僅產(chǎn)生一種循環(huán)形式; 可使用-o3 和-pm 選項,使優(yōu)化器訪(fǎng)問(wèn)整個(gè)程序,了解循環(huán)次數信息; 使用-nassert 內聯(lián)函數,防止冗余循環(huán)產(chǎn)生;使用-mh 選項,消除軟件流水循環(huán)的排空,從而減小代碼尺寸。
由于在嵌套循環(huán)中編譯器僅對最里面的循環(huán)執行軟件流水,因此對于執行周期很少的內循環(huán)進(jìn)行循環(huán)展開(kāi),對外循環(huán)進(jìn)行軟件流水。
使用軟件流水應當注意的問(wèn)題: 盡管軟件流水循環(huán)可以包含內聯(lián)函數,但不能包含函數調用; 在循環(huán)中不使用break 語(yǔ)句; 循環(huán)控制變量不能與循環(huán)體內的語(yǔ)句有關(guān); 如果循環(huán)體內復雜的條件代碼需要超過(guò)5 個(gè)條件寄存器或者32 個(gè)以上寄存器,則這個(gè)循環(huán)不可進(jìn)行軟件流水。
(4)片內存儲器的分配及DMA技術(shù)的運用。
DM643 內部有16 KB 的一級程序緩存、16 KB 的一級數據緩存和256 KB 的程序數據共享二級緩存,遠小于執行程序和待處理圖像數據,不可能將程序和圖像數據都在片內RAM 中緩存,因此合理地配置和使用存儲空間,對系統整體效率影響很大。
提高算法程序執行速度的關(guān)鍵是使核心循環(huán)代碼和要訪(fǎng)問(wèn)的數據在第1 次訪(fǎng)問(wèn)之后全部發(fā)生L1P 和L1D 命中。核心循環(huán)代碼占的空間很小,執行過(guò)一次之后,完全可以全部在L1P 中緩存,因此,不用考慮代碼如何在存儲器中存放,主要問(wèn)題是圖像數據的存放。
由于L1D 采取LRU (Least Recently Used)分配機制,因此對于小于等于16 KB 的連續存放的數據塊可完全在L1D 中命中。以解碼過(guò)程為例,IDCT 和運動(dòng)補償模塊都是以宏塊為單位進(jìn)行運算的,IDCT 數據類(lèi)型為short型,運動(dòng)補償中的預測幀和當前幀的數據類(lèi)型為unsignedchar 型。計算一個(gè)宏塊(420 格式)的IDCT 和運動(dòng)補償要訪(fǎng)問(wèn)的數據大小共需1 536 字節,運動(dòng)補償的數據包括預測宏塊和當前宏塊的數據,實(shí)際解碼中以6 個(gè)宏塊(10 KB)作為1 次處理對象。待處理的數據要從外部存儲器搬到L2 中連續的存儲空間,可利用EDMA 與CPU 并行工作的特點(diǎn),采取Ping??Pong 技術(shù),使CPU 在處理Ping空間數據的同時(shí),由EDMA 將下次要處理的數據搬到Pong 空間中; 當CPU 處理Pong 空間數據時(shí),再由EDMA將Ping 空間已處理好的數據搬回外部存儲器,并將下次要處理的數據搬到Ping 空間,這樣就可達到CPU 的最大計算能力。Ping、Pong 空間各占用的大小為20 KB, 兩個(gè)總共約40 KB.L2 中的剩余空間分出64 KB 留給數據空間,用于解碼中常用的解碼表、量化步長(cháng)、輸入壓縮碼流緩沖區和輸出碼流緩沖區等。64 KB 的程序空間用于存儲H. 264 算法中的運動(dòng)預測、運動(dòng)補償和中斷服務(wù)程序等關(guān)鍵代碼。L2 其余部分配置為Cache, 操作與L1D 類(lèi)似。
2. 2 編寫(xiě)線(xiàn)性匯編代碼
為了提高代碼性能,對影響處理速度的關(guān)鍵C 代碼段可以用線(xiàn)性匯編重新編寫(xiě)。線(xiàn)性匯編代碼類(lèi)似于匯編代碼,不同的是線(xiàn)性匯編代碼中不需要給出匯編代碼必須指出的所有信息(如所使用的寄存器、指令的并行與否、指令的延遲周期和指令使用的功能單元等),匯編優(yōu)化器會(huì )根據代碼的情況確定這些信息。當然,如果能夠事先確定一些信息(如循環(huán)的執行次數、存儲區的地址等),則編寫(xiě)的線(xiàn)性匯編代碼的效率更高。具體的優(yōu)化措施如下:
①使用偽指令向匯編優(yōu)化器提供較為詳細的信息。
②畫(huà)出指令的相關(guān)圖,根據相關(guān)圖合理分配邏輯單元,最大限度地保證指令的并行執行。
③充分使用C64x DSP 提供的強大包處理指令處理數據(包處理指令可同時(shí)處理2 個(gè)l6 位數據和4 個(gè)8 位數據)。本系統中使用了AVGU4、MIN2、M AX2、SPACKU4、PACK2、D0T P2、D0T PN2 和UNPKLU4 等指令。C64x DSP 還提供了STDW(STNDW)、LDDW(LDNDW)指令,可一次存取連續的64 位數據??衫肔DDW 指令,將作1 次行變換所需數據1 次取來(lái),并將處理后的結果利用STDW 指令一次存好。這樣大大縮短了代碼長(cháng)度,提高了代碼效率。
④利用Schedule Table 確定循環(huán)的重復間隔,合理安排功能單元,進(jìn)行軟件的流水。
linux操作系統文章專(zhuān)題:linux操作系統詳解(linux不再難懂) 鎖相環(huán)相關(guān)文章:鎖相環(huán)原理
評論