王金洋
基于C6000系列DSP的算法優化研究
王金洋

王金洋 余紅英 樊永生
中北大學計算機與控制工程學院

目前DSP高性能運算芯片已經在工業數字信號處理、超高分辨率視頻編解碼等領域得到廣泛應用。C6000屬于TI公司的達芬奇系列雙核處理器芯片,既具ARM對于各類外設接口的豐富支持,同時具有DSP數字信號處理器的強大運算能力。本文針對C6000的實際算法設計時候的5個關鍵技術展開討論并在編程實踐中研究如何具體使用。本文研究內容對于之后基于C6000的音視頻應用,特別是安防產業中近年來1080P超高清分辨率IPC的普遍使用,對于算法的并行性和效率提出的越來越高的要求具有十分重要的意義。
目前業內基于DSP的算法優化主要是基于DSP芯片本身硬件優化和運行于DSP的算法本身的設計優化。TI公司的C6000系列DSP具有許多架構上的優勢,使得C6000很適合實時應用領域和對運算要求特別高的場合。但是為了充分的發揮C6000架構的特點,我們有必要做代碼優化。本文首先介紹5個關鍵性技術用于理解C6000 DSP架構和優化。然后介紹在實踐中遇到的問題以及采用這5種優化技術所產生的效果。
C6000 DSP中為并行化處理設計的處理器核心和為高吞吐量設計的流水線技術使得其在工業應用中具有出色的表現。所以C6000的工業應用中的優化的目的就是盡可能充分的利用DSP 處理器核心和流水線技術。
C6000的優化涉及5個關鍵技術如下:
DSP core,DSP處理器核心,為并行化處理設計;
DSP pipeline,DSP pipeline技術,為高吞吐量設計;
Software pipelining,指令派度策略可以提高pipeline的使用率;
Compiler optimization,開發者配置編譯器并引導編譯器的整個編譯過程,可以進行代碼級和文件級優化;
Intrinsic operations,C6000系列編譯器固有的庫以及inline函數。
簡化的加載/存儲架構
圖1描述的是一種簡化的加載/存儲架構,其中包含負責執行所有指令的處理器單元和大量的用于存儲指令執行過程中的操作數和數據的寄存器。所有將要執行的指令從內存中獲取(指令的地址存儲在程序計數寄存器中)并按照順序送入處理器單元。數據可以通過加載指令從內存中到寄存器中且寄存器數值可以通過存儲指令放入到內存中。

圖1 一種簡化的加載/存儲架構
乘法與累加算法演示
數字信號處理中最常用的操作是乘法與累加,在FIR(Finite Impulse Response,有限脈沖響應)濾波器和FFT(Fast Fourier Transform,快速傅里葉變換)變換算法中使用的很多。Example 1顯示的是使用C語言編寫的乘法和累加循環代碼。
Example 1:
for(i=0;i〈count;i++)
{
prod = m[i]*n[i];
sum += prod;
}
Example 2是用偽匯編語言編寫的乘法與累加循環操作。
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所示的架構CPU核心中執行,每一個循環周期CPU需要執行6條指令。為了完成整個循環需要CPU花費6個指令周期,所以具有很大的優化空間。
C674x流水線技術
以上介紹的CPU架構對于一條指令的處理分為三步。第一步為取指令,第二步為指令解碼,第三步為指令執行。對應于CPU的工作為第一步從內存中獲取指令,第二步為解析指令,第三步為完成操作。為了使得系統性能最大化,就要充分的發揮硬件支持,而解決的辦法就是多指令流水技術。

表1 具備流水線和非流水線技術CPU對比
從表中可以得出使用流水線技術的CPU比不使用流水線技術的CPU效率和吞吐量至少高50%。
軟件流水
軟件流水技術是指在循環中使用并行運算技術以盡量的發揮CPU的并行處理能力。我們用以下代碼演示軟件流水的技術過程。
Example 3:在內存中累加15個變量
解決方案1:傳統的指令分布:重復以下代碼15次,匯編偽代碼如下:
Load *pointer_value++, data_value
Add data_value, data_sum
解決方案2:軟件流水技術,匯編偽代碼如下
Load1 Load2 Load3 Load4 Load5
Load6 Add1 Load7 Add2 …
在解決方案1中使用了非流水線技術,它每次要耗費CPU6個時鐘周期完成取指令和加指令。整個操作過程中,CPU需要耗費90個時鐘周期,其中沒有使用并行技術,在絕大多數的時鐘周期中硬件的并行性都沒有用到。在解決方案2中使用了軟件流水技術,在Load1執行后Load2馬上執行,以后的時鐘周期都會多執行一個Load指令。另一方面Add1在第6時鐘周期執行。從代碼執行級別來看和解決方案1類似,但是如果從CPU執行角度看完成內存中15個變量的只需要20個時鐘周期,比解決方案1效率和吞吐量快4.5倍。
編譯器優化
編譯器優化指的是使用C編譯器產生匯編代碼文件,過程中要求最大化地使用C6000的核心功能性單元和CPU核心的流水線。TI官方推薦使用C語言進行應用開發,便于以后的應用更新和移植。C語言編譯器負責生成高度優化的匯編語言文件,并且支持大量的與優化和調試配置選項。一般情況下編譯器會生成高度優化的匯編代碼文件,但是許多情況下為了保證執行的正確性,我們采取保守的方法,也即開發者提供額外的信息和指令給編譯器去引導編譯器的編譯過程從而達到最大優化。
通常引導編譯器優化過程的方法有:
控制優化過程的編譯器選項;負責處理所有的編譯器輸入文件,例如—opt_level控制編譯優化過程達到的程度。
;C674x C語言編譯器支持多個ANSI C和C6000關鍵字,這些關鍵字添加到要優化的函數或者對象之前。
編譯指令;告知編譯器如何處理特別的函數和對象或者代碼段。例如MUST_INTERATE添加到一個循環前,規定了循環的最小和最大循環次數。
顯式代碼優化
編譯器優化是一種非常有效并且節約時間的優化方法,但是在循環中調用函數或者開發者要實現復雜的操作情形下,編譯器優化就不能滿足要求了。C674x提供了三種方法分別是內置操作,DSP庫函數,C內聯函數。
C6000功能性單元支持大量的復雜的函數,例如shuffle算法(將某個32 bit變量按照奇數位、偶數位分拆成兩個變量)的實現在內置操作中2個時鐘周期即可完成,但是如果用C代碼實現則需要大量的代碼耗費大量的時鐘周期。為了幫助開發者在類似的情形中進一步地提升性能,C6000提供的內置操作類似于函數聲明,使用下劃線進行特別說明。如shuffle位操作可以調用_shfl。對于許多的信號和數學操作不必全部使用內置操作,因為TI提供了高度優化的軟件庫,例如FastRTS和DSPLIB。庫中的函數可以用來減少開發和優化的時間,也可以用來作為內置函數使用的參考示例。例如DSPLIB中的基于混合基函數的反傅里葉變換DSPF_sp_iffSPxSP很好地綜合了顯示代碼優化技術。
依據遞歸計算FFT的算法步驟是:第一步將輸入數組元素進行反置變換,第二步遍歷樹的每一層,第三步遍歷一層中每一對數據,第四步根據這一對數據和蝶形公式計算上一層;其中涉及的復數和向量的運算代碼歸并為兩個類。
C6000的FFT算法對于輸入的每一幀圖像看做是線性數組進行處理,在串口上打印出每一幀的處理時間和當前幀速。當輸入為1080P圖像時候,幀速為4~5FPS,而采用了內置操作、編譯器優化、DSPLIB、SRam雙緩沖之后幀速可以提高到24FPS,基本滿足人眼對于視頻的實時性和連貫性要求。
總而言之,TI C6000 DSP的優化技術在目前的超高分辨率音視頻解決方案中得到越來越多的使用,合理的采用和平衡優化技術對于提高算法的效率、并行性和實時性要求具有十分重要的意義。
10.3969/j.issn.1001-8972.2015.01.035
*/