簡 歡
(福州瑞芯微電子有限公司,福建福州350003)
ARM NEON已廣泛應(yīng)用于數(shù)字信號處理和多媒體應(yīng)用中,特別是音視頻編解碼。本文基于ARM Cortex A9處理器平臺,對NEON處理器的結(jié)構(gòu)、指令和編程優(yōu)化方法等技術(shù)進行了研究,并在此平臺上開展了H.265解碼器的具體實現(xiàn)和優(yōu)化。通過在瑞芯微電子的RK3188 SDK開發(fā)板上的實際測試,結(jié)果表明NEON處理器可以較好地提高H.265軟件解碼器在Cortex A9處理器上的執(zhí)行效率。
ARM Cortex A9是高性能ARM處理器,可實現(xiàn)各種基于ARM v7體系結(jié)構(gòu)的應(yīng)用和功能。Cortex A9處理器具備高效的、長度動態(tài)可變和多指令執(zhí)行超標(biāo)量體系結(jié)構(gòu),提供采用亂序猜測方式執(zhí)行的8階管道處理器。在消費類、網(wǎng)絡(luò)、企業(yè)和移動應(yīng)用中,Cortex A9都展示出了極高的性能和效率。
Cortex A9微體系結(jié)構(gòu)既可以配置成可伸縮的多核處理器,也可以配置成單核處理器??缮炜s的多核處理器和單核處理器支持多種L1高速緩存配置,同時支持可選的L2高速緩存控制器,Cortex A9的靈活性保證了對各種應(yīng)用領(lǐng)域和市場的適用性。
Cortex-A9的NEON處理器設(shè)計是基于ARM v7的SIMD(Single Instruction Multiple Data)和矢量浮點計算VFP v3(Vector Floating-Point)指令集進行的,在不同的芯片設(shè)計中NEON組件是可選的。在多媒體處理領(lǐng)域,如音視頻編解碼器、圖像處理和語音信號處理,以及通信領(lǐng)域,如基帶信息處理,NEON處理器都有自己獨特的優(yōu)勢。
NEON處理器是ARM Cortex A系列處理器的128位SIMD(單指令多數(shù)據(jù))體系結(jié)構(gòu)擴展,它具有32個64 bit位寬寄存器或者16個128 bit位寬寄存器,所有的寄存器都被視為具有相同數(shù)據(jù)類型的一個向量,支持多種數(shù)據(jù)類型,包括有符號和無符號數(shù)據(jù)類型,也包括單精度浮點數(shù)據(jù)類型。另外,NEON指令都是針對相同數(shù)據(jù)類型的通道處理的,即所有通道執(zhí)行相同的指令操作。
圖1是NEON寄存器的視圖,16個128 bit的4 byte寄存器Q0~Q15,或者32個64 bit的雙字寄存器D0~D31。注意NEON寄存器和ARM寄存器存在區(qū)別,但NEON會采用ARM的寄存器作為地址寄存器進行間接尋址。
圖1 NEON寄存器視圖
圖2是NEON單個寄存器組的元素分配,表示了NEON可支持的操作類型數(shù)據(jù)。包括有符號或者無符號的8 bit、16 bit、32 bit和64 bit的整型數(shù)據(jù)(I8,S8,U8,I16,S16,U16,I32,S32,U32,I64,S64,U64)或者單精度浮點數(shù)據(jù)(F32)。
圖2 NEON單個寄存器組的元素分配
NEON處理器同時支持內(nèi)存非對齊訪問和對齊訪問,對齊訪問的速度更快,可通過指定@bits來確定地址對齊的位數(shù),如@32,@64,@128等。數(shù)據(jù)加載和存儲支持交錯打包方式,即支持有2、3、4個通道的交錯數(shù)據(jù)加載和存儲。除此之外,還能在標(biāo)量和向量間進行數(shù)據(jù)的移動,但速度較慢。同時,NEON也支持單精度浮點的數(shù)據(jù)運算。
NEON編程優(yōu)化方法通常包括如下幾種手段:
1)編寫匯編代碼
最直接使用NEON的方式是編寫NEON匯編代碼。相對于其他的DSP編程語言,NEON的編寫并不復(fù)雜。但要寫出高質(zhì)量的,能對性能有較大優(yōu)化的匯編仍然具有一定難度。在對一個模塊進行NEON匯編優(yōu)化之前,需要先確保對模塊的算法優(yōu)化做到了最佳,特別是按照NEON的并行處理指令思路來改寫模塊,要將模塊改寫成使其盡量滿足NEON的并行處理框架。完成了算法優(yōu)化后,即可動手開始編寫匯編代碼。
和傳統(tǒng)的Intel X86匯編、DSP匯編相同,NEON匯編也涉及到出棧入棧操作,這要求匯編代碼編寫者小心對待,以免因為入棧和出棧不一致導(dǎo)致程序運行錯誤。
2)采用內(nèi)聯(lián)函數(shù)(Intrinsic Function)
內(nèi)聯(lián)函數(shù)可以被C和C++的程序所調(diào)用,可自動進行類型檢測和寄存器分配。內(nèi)聯(lián)函數(shù)在被編譯器編譯的時候,它會被轉(zhuǎn)化為有序的NEON指令進行執(zhí)行。簡單的看,采用內(nèi)聯(lián)函數(shù)可以實現(xiàn)在高級語言(如C/C++)中直接使用低級語言(如NEON)的功能。內(nèi)聯(lián)函數(shù)最大的好處是程序員不用去接觸匯編,可以減小優(yōu)化的難度。但采用內(nèi)聯(lián)函數(shù)獲得的優(yōu)化效率沒有直接使用匯編代碼獲得的優(yōu)化效率高。
3)自動矢量化
ARM編譯器可針對C/C++代碼進行自動矢量化操作,這樣做的一個好處就是程序員不需要編寫匯編代碼或者使用內(nèi)聯(lián)函數(shù),即可實現(xiàn)NEON優(yōu)化的效果。用C進行編程同時也保證了在不同平臺上的兼容性。
在C語言的for循環(huán)內(nèi)部使用自動矢量化技術(shù)可獲得較好的性能優(yōu)化結(jié)果。假設(shè)在執(zhí)行循環(huán)體操作時,每次循環(huán)內(nèi)部執(zhí)行的操作相同,則可以采用自動矢量化技術(shù),將多次循環(huán)的操作盡可能轉(zhuǎn)換成一次操作完成。在一次操作中,有多個計算單元按照相同的操作步驟來完成多次循環(huán)執(zhí)行。
4)使用第三方的NEON庫(NEON Library)
ARM公司本身對常見的算法進行了NEON優(yōu)化,并封裝成Library。如針對多媒體跨平臺API的OPENMAX[1],ARM 提供了針對 OPENAM 開發(fā)層(OPENMAX DEVELOPMENT LAYER)的優(yōu)化實現(xiàn)。在開源代碼社區(qū),有不少開發(fā)者和感興趣的人提供了很多基于NEON優(yōu)化的library,這些Library覆蓋了音視頻編解碼和數(shù)字信號處理的常見模塊。一個著名的NEON代碼優(yōu)化社區(qū)是Project Ne10[2]。
本文采用開源的 OPENHEVC[3]作為 H.265[4]解碼器進行優(yōu)化。相對于H.265標(biāo)準(zhǔn)的參考實現(xiàn)HM[5],OPENHEVC解碼器同樣符合H.265標(biāo)準(zhǔn)的語法語義,其實現(xiàn)更為簡練和高效。解碼器主要模塊包括熵解碼、反量化、反變換、幀內(nèi)預(yù)測、幀間運動補償(MC)、去塊效應(yīng)環(huán)路濾波(Deblocking)和樣本自適應(yīng)偏移量濾波器(SAO)等。其解碼器框圖如圖3所示。
圖3OPENHEVC解碼基本框架
在OPENHEVC解碼器中,由于熵解碼模塊的串行程度高,條件分支過多,不適合采用NEON進行優(yōu)化,該模塊可用ARM指令和Thumb指令代替NEON指令進行優(yōu)化。對于其他模塊,如整數(shù)反余弦變換(IDCT),MC和Deblocking等,模塊算法中對于不同像素點的運算過程可以高度并行,并且運算步驟基本一致,適合采用NEON優(yōu)化。因此對這部分進行了充分的NEON優(yōu)化。由于優(yōu)化的模塊較多,這里僅以IDCT為例,來說明NEON優(yōu)化的思路及具體實現(xiàn)。
H.265編碼標(biāo)準(zhǔn)中對變換單元(Transform Unit,TU)通過使用整數(shù)正弦變換(DST)和整數(shù)余弦變換(DCT)將時空域信號轉(zhuǎn)換為頻域信號,再進行量化,達到壓縮的目的。相應(yīng)地,在H.265解碼端,需要進行整數(shù)反正弦變換(IDST)和整數(shù)反余弦變換(IDCT)。
H.265指定了4種不同的TU塊尺寸,分別為4×4,8×8,16×16和32×32。在幀內(nèi)編碼中,4×4亮度變換塊采用DST進行整數(shù)變換,以此提高大約1%的壓縮比[6]。除此之外,其他類型的變換塊均統(tǒng)一采用IDCT進行處理。
以8×8 IDCT為例,描述如何采用NEON進行加速。
式中:X為8×8 TU塊的數(shù)據(jù);M為8×8 IDCT的系數(shù)變換矩陣;MT為M的轉(zhuǎn)置矩陣;Z為8×8 IDCT的最終結(jié)果。M具體取值為
即首先得到IDCT的一維運算結(jié)果Y,然后將MT和Y做矩陣乘法得到IDCT的二維運算結(jié)果Z。
對IDCT的一維運算采用蝶形變換來進行算法優(yōu)化,其實現(xiàn)框圖如圖4所示。
觀察式(1),可將其變換成如下等式
圖4 H.265,8×8 IDCT 1-D蝶形運算示意圖
圖4中x0到x7表示8×8 TU塊的同一列系數(shù),x0表示該列的第一個系數(shù),x7表示該列的最后一個系數(shù)。采用一維快速蝶形運算來實現(xiàn)IDCT算法,雖然從C代碼層面上已經(jīng)有效降低了計算復(fù)雜度,但每次運算都只針對矩陣中一列系數(shù),對于8×8矩陣來說,需要對8列系數(shù)進行8次相同運算,才能完成整個一維快速蝶形運算。而采用NEON進行并行優(yōu)化,可以將4次運算合并為1次,因此可極大提高運算速度。
基于IDCT的快速蝶形運算思路,采用NEON對IDCT進行優(yōu)化的整體思路如下:
1)在8×8 IDCT實現(xiàn)中,TU塊的系數(shù)采用16位無符號整數(shù)表示。充分利用NEON的128 bit位寬,可一次用2個連續(xù)的64位D寄存器(也可以用1個128位Q寄存器表示)保存TU塊一行8個系數(shù)。
2)NEON支持最多4個16 bit整數(shù)同時進行乘累加,因此通過前面加載進來的8個系數(shù),需要執(zhí)行兩次乘累加操作。由于8×8塊左邊4列和右邊4列的操作完全一樣,因此可以將8×8 TU塊分為左右兩個8×4子塊,對子塊采用快速蝶形運算得到8×4一維運算結(jié)果。
以左邊8×4子塊為例,詳細描述快速蝶形運算的NEON實現(xiàn)步驟。
(1)將8×4 TU塊的32個數(shù)據(jù)加載進D寄存器,后面的運算將不再從內(nèi)存中讀取數(shù)據(jù)。
(2)計算圖4 中O8_0~O8_3。將M[1][8],M[3][8],M[5][8]和M[7][8]的值賦給 D 寄存器,為后面的乘累加操作做準(zhǔn)備。
(3)對4個系數(shù)同時進行乘累加,得到O8_0。其示意圖如圖5a所示。同理可得到O8_1,O8_2和O8_3的結(jié)果。
(4)計算圖4 中E8_0~E8_3。將M[1][8],M[3][8],M[5][8]和M[7][8]的值賦給 D 寄存器,為后面的乘累加操作做準(zhǔn)備。
(5)如圖5b所示,對4個系數(shù)同時進行乘累加,得到e0。同理得到e1。
(6)和步驟(5)類似,如圖5c計算得到o0,o1。
(7)將e0,e1,o0和o1進行交叉相加減,得到E8_0~E8_3。
(8)最后對E8_0~E8_3,O8_0~O8_3進行交叉相加減,并最終經(jīng)過移位操作后得到最終結(jié)果。
為方便NEON在做IDCT二維計算的時候,可以如一維計算一樣,一次加載連續(xù)多個數(shù)據(jù)進入D寄存器,需要對IDCT一維輸出結(jié)果進行轉(zhuǎn)置。NEON中的VZIP指令可以幫助實現(xiàn)這樣的操作。VZIP指令可交叉存取兩個向量的元素。以VZIP.8為例,如圖6所示,可將dn和dm兩個寄存器每8 bit進行交叉存儲。
圖5 計算O8_0,e0和O0框圖
圖6 VZIP.8 dn,dm示意圖
二維運算過程和一維運算過程基本相似,這里不再敘述。二維運算的結(jié)果即最終的IDCT運算結(jié)果。
本文采用了內(nèi)置瑞芯微電子 RK3188處理器[7]的SDK開發(fā)板作為測試平臺,其CPU為ARM Cortex A9四核,帶NEON和VFP加速處理單元,CPU主頻最高可運行至1.6 GHz。
軟件平臺采用Android 4.4操作系統(tǒng),通過對H.265編碼視頻的解碼幀率測試,來評估NEON優(yōu)化代碼的效率。本文采用了包括各種分辨率和碼率的測試序列進行解碼測試,優(yōu)化效果隨著分辨率上升愈顯明顯。具體優(yōu)化結(jié)果如表1所示。
表1 OPENHEVC解碼器整體優(yōu)化效果對比
ARM NEON技術(shù)廣泛應(yīng)用于多媒體優(yōu)化中。NEON的SIMD架構(gòu)使得其非常適合多媒體編解碼器中的許多計算密集型模塊。NEON在H.265解碼器中的優(yōu)化效果表明,采用NEON進行多媒體優(yōu)化效果顯著,能較好地提高多媒體應(yīng)用的執(zhí)行效率。
:
[1] The standard for media library portability[EB/OL].[2014-02-05].http://www.khronos.org/openmax/.
[2] An open optimized software library project for the ARM architecture[EB/OL].[2014-02-05].http://projectne10.github.io/Ne10/.
[3] OpenHEVC [EB/OL].[2014-02-05].https://github.com/Open-HEVC/openHEVC.
[4] ITU-T recommendation H.265 [EB/OL].[2014-02-05].http://download.csdn.net/download/sugufe/5593167.
[5] HEVC Test Model(HM)documentation[EB/OL].[2014-02-05].https://hevc.hhi.fraunhofer.de/HM-doc/.
[6] SAXENA A,F(xiàn)ERNANDES F C.DCT/DST-based transform coding for intra prediction in image/video coding[J].IEEE Trans.Image Processing,2013,22(10):1685-1688.
[7] RK31 Series[EB/OL].[2014-02-05].http://www.rock-chips.com/a/en/products/RK31_Series/2013/0808/314.html.