王金洋
基于C6000系列DSP的算法優(yōu)化研究
王金洋
王金洋 余紅英 樊永生
中北大學計算機與控制工程學院
目前DSP高性能運算芯片已經(jīng)在工業(yè)數(shù)字信號處理、超高分辨率視頻編解碼等領(lǐng)域得到廣泛應用。C6000屬于TI公司的達芬奇系列雙核處理器芯片,既具ARM對于各類外設接口的豐富支持,同時具有DSP數(shù)字信號處理器的強大運算能力。本文針對C6000的實際算法設計時候的5個關(guān)鍵技術(shù)展開討論并在編程實踐中研究如何具體使用。本文研究內(nèi)容對于之后基于C6000的音視頻應用,特別是安防產(chǎn)業(yè)中近年來1080P超高清分辨率IPC的普遍使用,對于算法的并行性和效率提出的越來越高的要求具有十分重要的意義。
目前業(yè)內(nèi)基于DSP的算法優(yōu)化主要是基于DSP芯片本身硬件優(yōu)化和運行于DSP的算法本身的設計優(yōu)化。TI公司的C6000系列DSP具有許多架構(gòu)上的優(yōu)勢,使得C6000很適合實時應用領(lǐng)域和對運算要求特別高的場合。但是為了充分的發(fā)揮C6000架構(gòu)的特點,我們有必要做代碼優(yōu)化。本文首先介紹5個關(guān)鍵性技術(shù)用于理解C6000 DSP架構(gòu)和優(yōu)化。然后介紹在實踐中遇到的問題以及采用這5種優(yōu)化技術(shù)所產(chǎn)生的效果。
C6000 DSP中為并行化處理設計的處理器核心和為高吞吐量設計的流水線技術(shù)使得其在工業(yè)應用中具有出色的表現(xiàn)。所以C6000的工業(yè)應用中的優(yōu)化的目的就是盡可能充分的利用DSP 處理器核心和流水線技術(shù)。
C6000的優(yōu)化涉及5個關(guān)鍵技術(shù)如下:
DSP core,DSP處理器核心,為并行化處理設計;
DSP pipeline,DSP pipeline技術(shù),為高吞吐量設計;
Software pipelining,指令派度策略可以提高pipeline的使用率;
Compiler optimization,開發(fā)者配置編譯器并引導編譯器的整個編譯過程,可以進行代碼級和文件級優(yōu)化;
Intrinsic operations,C6000系列編譯器固有的庫以及inline函數(shù)。
簡化的加載/存儲架構(gòu)
圖1描述的是一種簡化的加載/存儲架構(gòu),其中包含負責執(zhí)行所有指令的處理器單元和大量的用于存儲指令執(zhí)行過程中的操作數(shù)和數(shù)據(jù)的寄存器。所有將要執(zhí)行的指令從內(nèi)存中獲?。ㄖ噶畹牡刂反鎯υ诔绦蛴嫈?shù)寄存器中)并按照順序送入處理器單元。數(shù)據(jù)可以通過加載指令從內(nèi)存中到寄存器中且寄存器數(shù)值可以通過存儲指令放入到內(nèi)存中。
圖1 一種簡化的加載/存儲架構(gòu)
乘法與累加算法演示
數(shù)字信號處理中最常用的操作是乘法與累加,在FIR(Finite Impulse Response,有限脈沖響應)濾波器和FFT(Fast Fourier Transform,快速傅里葉變換)變換算法中使用的很多。Example 1顯示的是使用C語言編寫的乘法和累加循環(huán)代碼。
Example 1:
for(i=0;i〈count;i++)
{
prod = m[i]*n[i];
sum += prod;
}
Example 2是用偽匯編語言編寫的乘法與累加循環(huán)操作。
Example 2:
/*
pointer_m & pointer_n represent registers used to hold the address of the data in memory.
data_m, data_n, data_product, data_sum,and data_count represent registers used to hold actual data.
The branch instruction (with a condition enabled) tells the CPU to jump back to the top of the loop (loop_top) if the value in the data_count register is not zero.
loop_top:load *pointer_m++, data_m
load *pointer_n++, data_n
multiply data_m,data_n,data_prod
add data_prod,data_sum,data_sum
substract data_count,1,data_count
if(data_count !=1) branch loop_top
假設Example 2中的代碼在圖1所示的架構(gòu)CPU核心中執(zhí)行,每一個循環(huán)周期CPU需要執(zhí)行6條指令。為了完成整個循環(huán)需要CPU花費6個指令周期,所以具有很大的優(yōu)化空間。
C674x流水線技術(shù)
以上介紹的CPU架構(gòu)對于一條指令的處理分為三步。第一步為取指令,第二步為指令解碼,第三步為指令執(zhí)行。對應于CPU的工作為第一步從內(nèi)存中獲取指令,第二步為解析指令,第三步為完成操作。為了使得系統(tǒng)性能最大化,就要充分的發(fā)揮硬件支持,而解決的辦法就是多指令流水技術(shù)。
表1 具備流水線和非流水線技術(shù)CPU對比
從表中可以得出使用流水線技術(shù)的CPU比不使用流水線技術(shù)的CPU效率和吞吐量至少高50%。
軟件流水
軟件流水技術(shù)是指在循環(huán)中使用并行運算技術(shù)以盡量的發(fā)揮CPU的并行處理能力。我們用以下代碼演示軟件流水的技術(shù)過程。
Example 3:在內(nèi)存中累加15個變量
解決方案1:傳統(tǒng)的指令分布:重復以下代碼15次,匯編偽代碼如下:
Load *pointer_value++, data_value
Add data_value, data_sum
解決方案2:軟件流水技術(shù),匯編偽代碼如下
Load1 Load2 Load3 Load4 Load5
Load6 Add1 Load7 Add2 …
在解決方案1中使用了非流水線技術(shù),它每次要耗費CPU6個時鐘周期完成取指令和加指令。整個操作過程中,CPU需要耗費90個時鐘周期,其中沒有使用并行技術(shù),在絕大多數(shù)的時鐘周期中硬件的并行性都沒有用到。在解決方案2中使用了軟件流水技術(shù),在Load1執(zhí)行后Load2馬上執(zhí)行,以后的時鐘周期都會多執(zhí)行一個Load指令。另一方面Add1在第6時鐘周期執(zhí)行。從代碼執(zhí)行級別來看和解決方案1類似,但是如果從CPU執(zhí)行角度看完成內(nèi)存中15個變量的只需要20個時鐘周期,比解決方案1效率和吞吐量快4.5倍。
編譯器優(yōu)化
編譯器優(yōu)化指的是使用C編譯器產(chǎn)生匯編代碼文件,過程中要求最大化地使用C6000的核心功能性單元和CPU核心的流水線。TI官方推薦使用C語言進行應用開發(fā),便于以后的應用更新和移植。C語言編譯器負責生成高度優(yōu)化的匯編語言文件,并且支持大量的與優(yōu)化和調(diào)試配置選項。一般情況下編譯器會生成高度優(yōu)化的匯編代碼文件,但是許多情況下為了保證執(zhí)行的正確性,我們采取保守的方法,也即開發(fā)者提供額外的信息和指令給編譯器去引導編譯器的編譯過程從而達到最大優(yōu)化。
通常引導編譯器優(yōu)化過程的方法有:
控制優(yōu)化過程的編譯器選項;負責處理所有的編譯器輸入文件,例如—opt_level控制編譯優(yōu)化過程達到的程度。
;C674x C語言編譯器支持多個ANSI C和C6000關(guān)鍵字,這些關(guān)鍵字添加到要優(yōu)化的函數(shù)或者對象之前。
編譯指令;告知編譯器如何處理特別的函數(shù)和對象或者代碼段。例如MUST_INTERATE添加到一個循環(huán)前,規(guī)定了循環(huán)的最小和最大循環(huán)次數(shù)。
顯式代碼優(yōu)化
編譯器優(yōu)化是一種非常有效并且節(jié)約時間的優(yōu)化方法,但是在循環(huán)中調(diào)用函數(shù)或者開發(fā)者要實現(xiàn)復雜的操作情形下,編譯器優(yōu)化就不能滿足要求了。C674x提供了三種方法分別是內(nèi)置操作,DSP庫函數(shù),C內(nèi)聯(lián)函數(shù)。
C6000功能性單元支持大量的復雜的函數(shù),例如shuffle算法(將某個32 bit變量按照奇數(shù)位、偶數(shù)位分拆成兩個變量)的實現(xiàn)在內(nèi)置操作中2個時鐘周期即可完成,但是如果用C代碼實現(xiàn)則需要大量的代碼耗費大量的時鐘周期。為了幫助開發(fā)者在類似的情形中進一步地提升性能,C6000提供的內(nèi)置操作類似于函數(shù)聲明,使用下劃線進行特別說明。如shuffle位操作可以調(diào)用_shfl。對于許多的信號和數(shù)學操作不必全部使用內(nèi)置操作,因為TI提供了高度優(yōu)化的軟件庫,例如FastRTS和DSPLIB。庫中的函數(shù)可以用來減少開發(fā)和優(yōu)化的時間,也可以用來作為內(nèi)置函數(shù)使用的參考示例。例如DSPLIB中的基于混合基函數(shù)的反傅里葉變換DSPF_sp_iffSPxSP很好地綜合了顯示代碼優(yōu)化技術(shù)。
依據(jù)遞歸計算FFT的算法步驟是:第一步將輸入數(shù)組元素進行反置變換,第二步遍歷樹的每一層,第三步遍歷一層中每一對數(shù)據(jù),第四步根據(jù)這一對數(shù)據(jù)和蝶形公式計算上一層;其中涉及的復數(shù)和向量的運算代碼歸并為兩個類。
C6000的FFT算法對于輸入的每一幀圖像看做是線性數(shù)組進行處理,在串口上打印出每一幀的處理時間和當前幀速。當輸入為1080P圖像時候,幀速為4~5FPS,而采用了內(nèi)置操作、編譯器優(yōu)化、DSPLIB、SRam雙緩沖之后幀速可以提高到24FPS,基本滿足人眼對于視頻的實時性和連貫性要求。
總而言之,TI C6000 DSP的優(yōu)化技術(shù)在目前的超高分辨率音視頻解決方案中得到越來越多的使用,合理的采用和平衡優(yōu)化技術(shù)對于提高算法的效率、并行性和實時性要求具有十分重要的意義。
10.3969/j.issn.1001-8972.2015.01.035
*/