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