H.264在ADSP-BF561上的實現(xiàn)與優(yōu)化
2.2.2.3 代碼層次優(yōu)化
針對ADSP-BF561平臺,代碼層次的優(yōu)化工作包括以下幾個方面:
(1)內(nèi)聯(lián)函數(shù)。將經(jīng)常調(diào)用的函數(shù)體較小的函數(shù)改為內(nèi)聯(lián)。編譯條件中有關(guān)于內(nèi)聯(lián)函數(shù)優(yōu)化的選項。內(nèi)聯(lián)函數(shù)的使用是將代碼的大小和運行效率取一個折中。根據(jù)實際情況,代碼的大小并非限制條件,所以應(yīng)盡可能多地使用內(nèi)聯(lián)函數(shù)。在項目配置中選中when declared inline選項。
(2)跳轉(zhuǎn)預測。ADSP-BF561采用了靜態(tài)預測的方式來預測有條件判斷情況,預測不成功會造成4~8個內(nèi)核時鐘(CCLK)的延誤。如果事先知道某些跳轉(zhuǎn)的概率,將可能性最大的分支放在最前面,可以從概率上降低預測不成功而造成的stall。
(3)使用硬件支持循環(huán)。對于大部分平臺,將一些循環(huán)體小的循環(huán)展開也能提高效率。ADSP-BF561有兩組硬件計數(shù)器用以支持循環(huán)。所以除非是展開三層以上的循環(huán),否則,展開循環(huán)體不能提高效率。
(4)內(nèi)存。嵌入式系統(tǒng)的內(nèi)存是非常寶貴的資源。避免頻繁的動態(tài)申請和釋放內(nèi)存,能減少碎片產(chǎn)生,提高內(nèi)存的利用率。X264工程也不會頻繁地申請釋放內(nèi)存。在項目中,具體做法是編寫平臺相關(guān)的malloc和free函數(shù)。將經(jīng)常使用的中間數(shù)據(jù)在L1數(shù)據(jù)空間中分配。
(5)注釋不需要代碼。去掉代碼中不需要的部分,主要會去掉CAVLC以及部分碼率控制、csp、cpu、信息統(tǒng)計、調(diào)試和psnr計算等部分代碼,這樣做的目的是為了減小文件大小和去除代碼中的一些跳轉(zhuǎn)。不建議刪除代碼,可以使用注釋符或用宏切換的方式,以防止以后參數(shù)改變時需要使用未使用過的代碼。
2.2.2.4 平臺層次優(yōu)化
ADSP-BF561相應(yīng)的編程參考和硬件參考對其平臺特性有詳細介紹。一些平臺自帶的優(yōu)化功能,如CACHE的開啟和配置等不專門在此討論。
(1)匯編代碼編寫
使用匯編優(yōu)化有兩個方法:對于LEAF函數(shù)(函數(shù)體中不再調(diào)用其余函數(shù)),采用整個函數(shù)完全用匯編指令重寫的方式;而對于NONLEAF函數(shù)則可使用asm關(guān)鍵字,在C代碼中嵌入?yún)R編代碼。在匯編代碼的編寫過程中一些情況會造成流水線stall,在編寫匯編代碼時要特別注意避免這些情況。IDE集成了PIPLELINE VIEWER工具,如圖4所示。在編寫完成匯編代碼后,可使用該工具觀察運行時流水線的情況。如果有stall等出現(xiàn),會給出原因,優(yōu)化人員根據(jù)工具分析結(jié)果重新更改代碼,提高執(zhí)行效率。
ADI公司提供的IDE具有非常靈活的設(shè)置,能根據(jù)用戶的需要生成針對不同限制的代碼。如內(nèi)存有限,用戶可以設(shè)置生成文件更小的代碼;如果用戶更注重運行速度,則設(shè)置編譯器生成運行速度更快的代碼,或是在其間取一個折中。
ADSP-BF561有專門用于處理視頻相關(guān)的一些專用DSP指令(video pixel operations、vector operations等),這些專用指令通過SIMD技術(shù)或者操作專門硬件支持某些特殊運算(累加、多參數(shù)取均值,同時完成加減法等),以提高運行速度。如前文求SAD情況,匯編指令中有指令專門計算連續(xù)4個像素與另外連續(xù)4個像素之差的絕對值之和,結(jié)果與累加器的值相加。如果要隔點算(即取一半的點計算),反而需要增加指令后對數(shù)據(jù)進行下采樣,既耗時而且不準確。所以采用計算一半像素點的策略并不適用于ADSP-BF561。編譯器自動生成的代碼中不會使用到這些專用指令。所以只能根據(jù)對算法的理解和對平臺的熟悉程度來對算法進行匯編優(yōu)化。
在編寫匯編代碼時還需注意部分寄存器的使用,如I0、I1,其值不僅用做地址索引,還會影響許多指令的計算結(jié)果。在使用這些寄存器時,一定要注意將其壓?;蛑脼檫m當?shù)闹怠4送?,關(guān)于數(shù)據(jù)的載入,一般應(yīng)遵循對齊原則,但在做運動估計計算匹配準則函數(shù)時,這樣的要求往往達不到。故如能將兩者分開來計算,將更能提高效率。
此外,應(yīng)盡量合理地使用寄存器,多使用并行指令也能提高代碼的執(zhí)行效率。
(2)分級存儲器結(jié)構(gòu)
ADSP-BF561處理器采用改進的哈佛結(jié)構(gòu)和分級的存儲器結(jié)構(gòu)。Level 1(L1)存儲器以全速運行,只有很少的延遲。在L1級,指令存儲器存放指令。兩個數(shù)據(jù)存儲器存放數(shù)據(jù),一個專用的臨時數(shù)據(jù)存儲器存放堆棧和局部變量信息。由多個L1 存儲器組成的模塊,可進行SRAM和CACHE 的混合配置。存儲器管理單元(MMU)提供存儲器保護功能,對運行于內(nèi)核上的獨立任務(wù),可保護系統(tǒng)寄存器免于意外的存取。L1 存儲器是ADSP-BF561處理器內(nèi)核中性能最高、最重要的存儲器。通過外部總線接口單元(EBIU),片外存儲器可以由SDRAM、FLASH 和SRAM 進行擴展,可以訪問多達132 MB的物理存儲器。根據(jù)這樣的特點,將執(zhí)行率更高的代碼放入L1指令緩存中,能使代碼更快地運行。IDE提供了Profile工具,能在運行時統(tǒng)計各個函數(shù)所占的CYCLE數(shù)和占總CYCLE數(shù)的百分比。通過將X264中比較耗時的部分算法代碼,如模式選擇部分代碼放入L1指令空間,能進一步提升運行效率。Profile工具統(tǒng)計結(jié)果同樣也是選擇需要使用匯編優(yōu)化函數(shù)的依據(jù),IDE可根據(jù)Profile結(jié)果對代碼進行優(yōu)化。X264代碼Profile統(tǒng)計結(jié)果與測試數(shù)據(jù)有很大關(guān)系,選用更類似以后應(yīng)用場所的數(shù)據(jù)作為測試數(shù)據(jù),能使統(tǒng)計結(jié)果更接近以后的應(yīng)用環(huán)境。為達到比較準確的統(tǒng)計結(jié)果,最好在Simulation階段進行統(tǒng)計。雖然這樣非常耗時,但為得到一個準確的統(tǒng)計作為參考依據(jù)是值得的。此外CACHE VIEWER工具能提供運行時CACHE的使用情況,使用它來分析CACHE的使用,對于提高代碼運行效率很有用處。
評論