白 偉,張 帥
(太原廣播電視大學(xué),山西 太原 030002)
AVS 數(shù)字音頻、視頻編碼標(biāo)準(zhǔn)是我國(guó)自主定制的基礎(chǔ)性壓縮標(biāo)準(zhǔn),其特點(diǎn)是編碼效率顯著較高、復(fù)雜度明顯降低、圖像質(zhì)量實(shí)現(xiàn)高清晰度和較強(qiáng)的抗誤碼性能[1,2]。在AVS 編碼過(guò)程中熵編碼模塊運(yùn)算過(guò)程相對(duì)復(fù)雜,并且耗時(shí)較長(zhǎng),因此快速實(shí)現(xiàn)熵編碼有利于編碼器的實(shí)時(shí)實(shí)現(xiàn)。
超長(zhǎng)指令字(VLIW)和直接處理打包數(shù)據(jù)技術(shù)在高端DSP 體系結(jié)構(gòu)中得到廣泛應(yīng)用,因此如何結(jié)合兩者的優(yōu)點(diǎn)并有效提高算法的運(yùn)行速度將成為深入研究的熱點(diǎn)[3,4]。TMS320DM6446 是美國(guó)TI 公司研發(fā)的高集成度視頻處理芯片,本文以該開發(fā)平臺(tái)為例,研究了利用該系統(tǒng)平臺(tái)優(yōu)化超長(zhǎng)指令字(VLIW)和打包數(shù)據(jù)處理技術(shù)的方法,并實(shí)現(xiàn)了對(duì)AVS 熵編碼模塊的匯編級(jí)優(yōu)化。
AVS 標(biāo)準(zhǔn)首先利用Zig- Zag 對(duì)量化后的數(shù)據(jù)進(jìn)行掃描,游程和幅值對(duì)(Run,Level)是量化后的8* 8 個(gè)系數(shù)按照掃描順序得到的序列對(duì),Level 為非零系數(shù)的幅值,游程Run為連續(xù)為0 的系數(shù)的個(gè)數(shù)。研究表明,游程和幅值具有關(guān)聯(lián)性,在整個(gè)頻率范圍內(nèi),當(dāng)幅值變化較小,對(duì)應(yīng)的游程可能會(huì)發(fā)生較大的變化,而當(dāng)幅值不斷增大時(shí),其對(duì)應(yīng)的游程則會(huì)有明顯下降。由于(Run,Level)掃描序列局部的聯(lián)合概率分布具有一定的差異性,因此AVS 采用了聯(lián)合編碼的方法,并設(shè)計(jì)了19 個(gè)VLC 碼表為適應(yīng)局部的差異性,根據(jù)幅值變化的程度動(dòng)態(tài)使用相應(yīng)的碼表,從而大大提高了VLC 編碼的效率。其編碼過(guò)程如圖1 所示。
每張VLC 碼表存儲(chǔ)空間26 ×27 byte,19 張VLC 碼表需要的存儲(chǔ)空間約為13 kbyte。對(duì)于嵌入式處理器,其內(nèi)部存儲(chǔ)器速度快,存儲(chǔ)空間有限,將19 張VLC 碼表完全存儲(chǔ)在內(nèi)部存儲(chǔ)器,將浪費(fèi)珍貴的的內(nèi)部存儲(chǔ)空間,放在外部存儲(chǔ)器,將大大降低編碼速度。對(duì)VLC 碼表進(jìn)行分析,其中有效碼字(非負(fù)值)僅有30 個(gè)左右,碼表中存在大量的逃逸標(biāo)志位-1。對(duì)VLC 碼表進(jìn)行改造,每張碼表存儲(chǔ)32(為了字對(duì)齊)個(gè)碼字,對(duì)逃逸標(biāo)志不存儲(chǔ),通過(guò)更多判斷完成實(shí)現(xiàn)。改進(jìn)后的碼表所需要的存儲(chǔ)空間約為0.6 kbyte,占用的存儲(chǔ)空間僅是原來(lái)的4.3%,完全可以放在內(nèi)部存儲(chǔ),同時(shí)也方便查找,提高數(shù)據(jù)cache 命中率。
圖1 熵編碼流程圖
支持VLIW 的DSP 具有的特性是一條指令并行執(zhí)行多個(gè)線程。C64 +有兩個(gè)數(shù)據(jù)處理通路:path A 和path B,每個(gè)數(shù)據(jù)處理通道有一個(gè)包含32 個(gè)32bit 寄存器和4 個(gè)運(yùn)算單元(M、D、L 和S)。四個(gè)運(yùn)算單元分別執(zhí)行乘法運(yùn)算、地址運(yùn)算、邏輯運(yùn)算和移位運(yùn)算等操作。由于path A 和path B是可以并行運(yùn)算的,8 個(gè)運(yùn)算單元在一個(gè)指令周期內(nèi)并行執(zhí)行的效率將是最高的,因此實(shí)際應(yīng)用中盡可能將path A 和path B 的八個(gè)功能單元并行執(zhí)行[5]。
DSP 數(shù)據(jù)打包處理是指對(duì)多個(gè)整型數(shù)據(jù)進(jìn)行相同操作時(shí)使用單一指令對(duì)進(jìn)行同時(shí)訪問(wèn)的技術(shù)。C64x +增加了49條新指令,提供的指令支持雙字讀取和存儲(chǔ)指令,新的指令占用程序空間小,處理效率高,大大提高了流媒體的處理速度。打包數(shù)據(jù)類型是C64x +打包數(shù)據(jù)處理的基礎(chǔ),支持8和16 位的數(shù)據(jù)打包類型[6]。
AVS ZIG-ZAG 掃描模塊是對(duì)量化后殘差數(shù)據(jù),原始的C 語(yǔ)言實(shí)現(xiàn)如下:
實(shí)現(xiàn)AVS 8x8 塊掃描需要64 次乘法運(yùn)算,64 次符號(hào)判斷,最多192 次加法運(yùn)算,320 次賦值運(yùn)算,可見(jiàn)編碼的復(fù)雜度相對(duì)較高。
預(yù)測(cè)殘差經(jīng)過(guò)整型量化之后,AVS Zig-Zag 對(duì)其數(shù)據(jù)進(jìn)行掃描,輸出為8 ×8 游程數(shù)據(jù)和幅值數(shù)據(jù)。ZIG-ZAG 掃描實(shí)現(xiàn)需要讀取掃描數(shù)組AVS_SCAN0[64]和AVS_SCAN1[64]。由于讀取數(shù)據(jù)指令存在延遲,并且耗時(shí)較長(zhǎng)的特點(diǎn),故采用LDDW 雙字取數(shù)據(jù)指令的技術(shù),一次同時(shí)取8 個(gè)需要處理數(shù)據(jù)。又因?yàn)镃64 +有兩個(gè)數(shù)據(jù)處理通路:path A 和path B,通道A 和B 又可以并行執(zhí)行,故用A 通路一次完成AVS_SCAN0 數(shù)組8 個(gè)數(shù)據(jù)讀取,用B 通路一次完成AVS_SCAN1 數(shù)組8 個(gè)數(shù)據(jù)讀取。用LDDW 指令從AVS_SCAN0數(shù)組一次讀取8 個(gè)xx,此時(shí)xx 為8 位,分別用UNPKHU4 和UNPKLU4 把它擴(kuò)展成16 位;用LDDW 指令從AVS_SCAN1數(shù)組一次讀取8 個(gè)yy,用MPYU4 指令一次完成8 個(gè)yy 與常數(shù)8 相乘,得到16 位的運(yùn)算結(jié)果,然后分別用A 和B 交叉通路和SADDU4 指令完成與8 個(gè)xx 相加。用DPACK2 指令將yy* 8 +xx 的值擴(kuò)展成每個(gè)寄存器一個(gè)值,然后讀出curr_val。將curr_val 與0 比較進(jìn)行賦值運(yùn)算,AB 兩側(cè)寄存器并行處理,循環(huán)8 次便可使全部運(yùn)算完成,最終將所得到的ipos 的值賦給icoef。其實(shí)現(xiàn)過(guò)程如圖2 所示。
圖2 ZIG-ZAG 掃描匯編優(yōu)化示意圖
該匯編優(yōu)化示意圖僅為一次循環(huán)的流程,經(jīng)過(guò)首次優(yōu)化后仍存在一些并行不完全的代碼,為提高代碼的并行性,需要將二次循環(huán)中的部分操作與首次循環(huán)沒(méi)有關(guān)聯(lián)的代碼再次進(jìn)行并行操作。
該量化系數(shù)經(jīng)掃描后需通過(guò)2D-VLC 查表和指數(shù)哥倫布編碼。假設(shè)掃描后得到N 個(gè)(Run,Level)對(duì),保存在數(shù)組RunBuf 和LevBuf 中。先用默認(rèn)的VLC 碼表TableArr[0],對(duì)RunBuf[N-1]和LevBuf[N-1]進(jìn)行指數(shù)哥倫布編碼。當(dāng)游程和幅值對(duì)(Run,Level)在該碼表范圍內(nèi)時(shí),根據(jù)索引求出碼字,再得到E-G 碼;反之當(dāng)(Run,Level)對(duì)不在碼表范圍內(nèi)時(shí),則作為逃逸事件進(jìn)行處理。然后根據(jù)幅值的絕對(duì)值更新碼表,如果大于之前幅值的最大值,則根據(jù)碼表索引數(shù)組求出用于下一個(gè)編碼的(Run,Level)碼表,反復(fù)循環(huán)至結(jié)束。對(duì)于逃逸事件先對(duì)Run 和Level 的符號(hào)編碼,如果Run 在碼表范圍內(nèi),說(shuō)明幅值絕對(duì)值有可能過(guò)大,則對(duì)幅值與參考值索引的差值進(jìn)行E-G 編碼;如果游程Run 超出了碼表的范圍,此時(shí)需要對(duì)幅值減1,然后再進(jìn)行E-G 編碼。對(duì)于負(fù)值的Level,當(dāng)其絕對(duì)值在碼表范圍內(nèi)時(shí),具體操作是對(duì)其絕對(duì)值加1,然后再進(jìn)行E-G 編碼。
從上面分析看出,2D-VLC 查表運(yùn)算需要根據(jù)不同門限值進(jìn)行查表操作,通過(guò)對(duì)VLC 碼表改造,節(jié)省了存儲(chǔ)空間,但也帶來(lái)了更多的判斷操作,因此需要合理的安排指令時(shí)序?qū)崿F(xiàn)高效的操作。不同碼表間的切換,需要大量的條件跳轉(zhuǎn)操作,因跳轉(zhuǎn)語(yǔ)句B 需要6 個(gè)指令周期的延遲,如何最大程度的在跳轉(zhuǎn)語(yǔ)句后進(jìn)行無(wú)關(guān)聯(lián)并行操作提高編碼效率的難點(diǎn)。查表過(guò)程中需要將level 的絕對(duì)值和run 的范圍進(jìn)行界定,從而確定具體碼字,如果將需要的不同常數(shù)提前準(zhǔn)備好,在判斷使用具體哪個(gè)碼表時(shí),就不需要大量的取數(shù)據(jù)操作,直接進(jìn)行比較,將大大提高效率。又因?yàn)镃64 +有兩個(gè)數(shù)據(jù)通路A 和B,通道A 和B 可以并行執(zhí)行,分別用不同的通路獨(dú)立完成level 和run 的范圍。首先用LDH 指令讀出level 和run 的值,并通過(guò)指令CMPEQ 與0-6 比較判斷處于其中哪一個(gè)表。根據(jù)判斷出的值跳轉(zhuǎn)到不同的表內(nèi)進(jìn)行下一步操作。表內(nèi)的操作基本相同,使用A 通道完成對(duì)level 界定,用B 通道完成對(duì)run 界定,通過(guò)ADD,CMPLT,MVK,CMPLT 和條件判斷等基本指令來(lái)完成。下面以幀內(nèi)熵編碼為例,說(shuō)明采用匯編指令優(yōu)化的實(shí)現(xiàn)過(guò)程。將各表跳轉(zhuǎn)的門限常數(shù)值預(yù)存到通用寄存器,表1,3,5,7 采用A 通道及相應(yīng)通用寄存器,表2,4,6,采用B 通道及相應(yīng)通用寄存器。因跳轉(zhuǎn)需要周期數(shù)較大,故在此期間將各表需要比較的常數(shù)預(yù)存到對(duì)應(yīng)寄存器。跳轉(zhuǎn)到各表后,通過(guò)MVK 指令將相應(yīng)的常數(shù)賦值到寄存器,通過(guò)CMPLT,CMPLT2 及CMPEQ 等比較指令確定最后的level 和run 值,通過(guò)level 和run 值來(lái)確定編碼的碼字,完成2D-VLC 查表。
2D-VLC 查表完成后,利用指數(shù)哥倫布編碼對(duì)查出來(lái)的碼字進(jìn)行處理,指數(shù)哥倫布編碼需要求出哥倫布碼的長(zhǎng)度與階數(shù)。哥倫布碼編碼完成之后會(huì)以二進(jìn)制的形式逐比特寫入碼流。為提高運(yùn)算效率,可以多次進(jìn)行并行寫碼流操作,以四個(gè)字節(jié)為單位,當(dāng)寫入碼流的長(zhǎng)度達(dá)到四個(gè)字節(jié)時(shí)結(jié)束操作。寫碼流的具體流程如圖3 所示。bs 結(jié)構(gòu)體中pos 記錄寫入的比特?cái)?shù),buf 保存寫入的比特值,tail 指向碼流輸出地址。在C64x+DSP 中,僅有A0-A2 和B0-B2 寄存器可作為條件判斷寄存器,資源比較少,且為高效運(yùn)行,A 通道和B 通道可并行運(yùn)行,因此操作時(shí)一般每個(gè)通道僅有3 個(gè)條件寄存器可使用,這就需要在優(yōu)化時(shí)充分挖掘條件寄存器的潛力,對(duì)條件寄存器使用狀態(tài)通過(guò)轉(zhuǎn)移表的形式標(biāo)注好狀態(tài),以便更好安排并行運(yùn)算。當(dāng)碼流賦值給輸出地址時(shí),會(huì)出現(xiàn)字節(jié)高低位取反的現(xiàn)象,需要使用SWAP4 指令提前進(jìn)行交換。
圖3 寫碼流示意圖
本文中采用TI 公司CCS3.3 仿真環(huán)境中profile 性能分析工具評(píng)估函數(shù)性能。不同的測(cè)試序列,熵編碼時(shí)間不同,為測(cè)試精確,對(duì)CIF 格式各種典型測(cè)試序列進(jìn)行測(cè)試,Y∶ U∶ V 為4∶ 2∶ 0,編碼100 幀。取測(cè)試周期數(shù)平均值,每次實(shí)驗(yàn)環(huán)境相同,C 語(yǔ)言實(shí)現(xiàn)優(yōu)化和匯編級(jí)優(yōu)化編譯環(huán)境設(shè)置相同,C 語(yǔ)言實(shí)現(xiàn)未優(yōu)化未使用優(yōu)化編譯選項(xiàng)-o3。測(cè)試結(jié)果如表1所示。
表1 不同優(yōu)化條件下函數(shù)性能比較
由上述實(shí)驗(yàn)結(jié)果得出:匯編級(jí)優(yōu)化后量化所需時(shí)鐘周期數(shù)是未優(yōu)化的7.73%(762 ÷9856),是C 語(yǔ)言優(yōu)化的17.622%(762 ÷4325);反量化需要的周期數(shù)是未優(yōu)化的7.31%,是C 語(yǔ)言優(yōu)化的13.93%。由此可見(jiàn),優(yōu)化效果顯著。
本文主要研究了DSP 平臺(tái)VLIW 和打包數(shù)據(jù)處理的優(yōu)化方法,采用此法對(duì)AVS ZIG-ZAG 掃描、2DVLC 查表和指數(shù)哥倫布編碼進(jìn)行匯編級(jí)優(yōu)化,減少了AVS 編碼器實(shí)現(xiàn)時(shí)間,能使AVS 算法在DSP 實(shí)現(xiàn)時(shí)延時(shí)更小。
[1]GB/T 200090.2-2006,信息技術(shù) 先進(jìn)音視頻編碼,第2 部分:視頻[S].2006.
[2]Wand Qiang et al,Context- Based 2D- VLC Entropy Coder in AVS Video Coding Standard,J.Comput.Sci&School,2006,21(3):315-322.
[3]李學(xué)明,李繼.用超長(zhǎng)指令實(shí)現(xiàn)DCT 的新算法[J].電子學(xué)報(bào),2003,33(7):1074-1077.
[4]劉廣,肖創(chuàng)柏,歐陽(yáng)萬(wàn)里,等.基于VLIW 的匯編級(jí)FDCT 和掃描量化優(yōu)化算法[J].計(jì)算機(jī)工程與應(yīng)用,2006,43(3):59-62.
[5]TMS320C64x+DSP Megamodule Reference Guide(SPRU871K)[Z].2010.
[6]TMS320C64x/C64x+DSP CPU and Instruction Set Reference Guide (SPRU732J)[Z].2010.