基于TMS320DM642 的X264 視頻編碼器的優(yōu)化
示例中, 除了數(shù)據(jù)搬移中必需的數(shù)據(jù)存放源地址和目的地址之外,還定義了變量Ping_Pong 和DAT_ID。其中Ping_Pong 是一個標志變量,用來表示當(dāng)前存放搬移數(shù)據(jù)的目的存儲區(qū)是Ping 存儲區(qū)還是Pong 存儲區(qū),DAT_ID 是正在進行的EDMA 搬移的句柄變量。在進入正式的編碼循環(huán)體以前,EDMA 會事先把一個要編碼的宏塊像素值搬移到Ping 存儲區(qū)(假設(shè)Ping_Pong=0 表示Ping存儲區(qū))。進入循環(huán)體以后,首先進行目標存儲區(qū)的交替(Ping_Pong=1-Ping_Pong,此時Ping_Pong=1,表示 Pong 存儲區(qū)),接著等待前一次搬移是否完成(DAT_wait(DAT_ID)),如果前一次搬移完成,就可以立即開始下一次搬移,同時CPU 立即進行對本次搬移數(shù)據(jù)的處理。以后的操作類似,直至所有的宏塊都完成編碼,結(jié)束循環(huán)體。
3.3 循環(huán)體的優(yōu)化
在X264 視頻編碼器中,循環(huán)體出現(xiàn)的頻率比較高,而且往往循環(huán)體是在整個編碼器中比較占用時間的部分。尤其是當(dāng)出現(xiàn)循環(huán)體嵌套,或者循環(huán)體內(nèi)部存在邏輯判斷語句或者函數(shù)調(diào)用時,編譯器一般不會對該循環(huán)進行優(yōu)化。針對這些問題, 比較常用的方法有嵌套循環(huán)體內(nèi)部循環(huán)展開,用條件操作符代替邏輯判斷語句,使用內(nèi)聯(lián)函數(shù),使用MUST_ITERATE 偽指令操作符[11-12],將大循環(huán)體拆成幾個小循環(huán)體。筆者使用的循環(huán)體優(yōu)化的例子代碼為:本文引用地址:http://cafeforensic.com/article/166324.htm
在上面示例中,偽指令MUST_ITERATE 主要是告訴編碼器,本次循環(huán)總共要執(zhí)行396 次,這樣編譯器就可以進行軟件流水來優(yōu)化這個循環(huán)。
3.4 編譯器優(yōu)化選項
在完成上述的手工優(yōu)化后,接下來通過設(shè)置編譯器選項來使用編譯器優(yōu)化,本文采用的編譯器優(yōu)化選項有:-pm(在程序級別進行優(yōu)化),-o3(對文件級別進行最強的優(yōu)化),-op3(速度最重要),-ml3(缺省情況下將全部數(shù)據(jù)和函數(shù)作為far 型)。
3.5 DSP 匯編優(yōu)化
假如使用上述優(yōu)化策略對編碼工程進行優(yōu)化后,編碼器的速度還不能達到應(yīng)用要求,就需要編寫手工匯編程序。編寫手工匯編程序之前, 首先要用CCS 的profile工具對編碼工程進行剖析, 找出比較耗時或頻繁調(diào)用的函數(shù)部分,把這些部分改寫成匯編函數(shù)。
DSP 采用的是哈佛體系結(jié)構(gòu), 將數(shù)據(jù)和程序分開存放。大體上來說,編寫匯編語言函數(shù)主要步驟為:把操作數(shù)從內(nèi)存中取出來放到CPU 的寄存器中, 然后在CPU內(nèi)部用不同的運算單元對寄存器里的操作數(shù)進行運算,最后把運算的結(jié)果存到內(nèi)存中。其中,函數(shù)參數(shù)傳遞、函數(shù)返回值寄存器、條件寄存器、棧指針寄存器的保存都必須按照規(guī)定使用相應(yīng)的寄存器,否則會出現(xiàn)錯誤。
在編寫匯編語言的過程中要考慮下方面:1) 充分理解待編寫的函數(shù)的邏輯功能。只有真正理解了函數(shù)實現(xiàn)的功能和具體的數(shù)據(jù)流程圖, 才能使匯編語言的構(gòu)架比較高效;2) 數(shù)據(jù)結(jié)構(gòu)的選擇和安排。由于DM642 允許數(shù)據(jù)打包處理,即一條指令可以同時對幾個字節(jié)進行操作,這對于圖像和視頻處理非常有益, 所以能夠打包處理的就盡可能打包處理;3) 寄存器的分配和指令的先后順序。DM642 的CPU 有2 套完全對稱的運算單元和寄存器。只要把操作數(shù)分別存、取到隸屬于不同套的寄存器里面,采用不同的運算單元,合理安排指令的先后順序,保證在資源不沖突的條件下盡量在一個周期內(nèi)安排更多的指令,實現(xiàn)指令運行的高效性、并行性。
評論