廖曉群,王佳儀,蘇 濤,李 敏,張美春
(1.西安科技大學 通信與信息工程學院,陜西 西安 710054;2.西安電子科技大學 雷達信號處理國家重點實驗室,陜西 西安 710071)
HXDSP1042是中國電子科技集團第三十八研究所在BWDSP100單核DSP基礎上研制的首款高性能多核DSP產品,從芯片的硬件架構到軟件開發(fā)平臺,再到指令集系統(tǒng),都具有完全自主知識產權。它是一個32 位浮點數(shù)字信號處理器,工作主頻700 MHz,時鐘周期1.4 ns,運算能力達每秒300 億次浮點運算或每秒80 億次浮點乘法累加運算[1]。HXDSP1042內部集成2個新一代處理器內核eC104+,該內核是BWDSP100內核eC104的增強和改進版,其性能得到大幅提升,達到eC104的3倍,并且其應用領域也由雷達、電子對抗進一步擴展到了通信、視頻圖像處理和高性能計算等[2]。眾多的應用領域需要更大的計算帶寬以及更高的數(shù)據(jù)精度,相對于32位數(shù)據(jù)運算來說,64位的數(shù)據(jù)計算可以支持更大的內存以及可以運行更大范圍的運算。通過不斷的研究,目前編譯器HXDSP1042通過改進軟件的方式對指令模板進行優(yōu)化設計,實現(xiàn)了64位數(shù)據(jù)的運算,支持64 位數(shù)據(jù)類型的相關語法,滿足了高速實時信號處理的需求[3]。
雙精度浮點矩陣運算函數(shù)屬于矩陣類算法,是最基本的庫函數(shù),矩陣類算法是雷達信號處理的常用運算,在自適應波束形成、方向估計中矩陣運算占有相當大的比重,它的實現(xiàn)為上層函數(shù)與處理提供了強大的調用接口。這些函數(shù)的使用較為頻繁,經編譯系統(tǒng)直接生成的代碼性能并不高,不能充分發(fā)揮DSP芯片自身的特點,因此選用匯編語言完成庫函數(shù)的設計,以保證硬件資源利用的最大化。直接從C版本的算法改寫成串行的匯編語言,并沒有結合DSP芯片的硬件特點,存在一定的缺陷,若指令排布不合理,嚴重的還可能會發(fā)生Bank沖突。為了解決上述問題,有必要從匯編層面優(yōu)化其性能,提高矩陣乘向量的運算效率。高性能的數(shù)據(jù)運算,能夠保證信號處理過程的精度以及處理的速度。針對最新一代HXDSP1042平臺所搭載的函數(shù)庫實施并行優(yōu)化,不僅能提升相關應用程序的運算速度,充分發(fā)揮HXDSP1042的性能,同時對DSP國產化的實現(xiàn)也具有實際意義。
針對DSP平臺對其配套的函數(shù)庫進行優(yōu)化是比較重要的工作,在此之前就有很多研究人員基于HXDSP平臺進行了一系列的優(yōu)化研究與設計。文獻[4]結合HXDSP1042的特殊指令和硬件邏輯,對中值濾波等圖像濾波函數(shù)進行了優(yōu)化,最終使得在四簇流水模式下,所有函數(shù)的性能均提升了51倍以上。文獻[5]采用軟件流水等方式對圖像編碼器進行優(yōu)化,通過對編碼器的代碼并行處理與優(yōu)化,使得基于TMS320C6678平臺的編碼速率由3.30幀/秒提升到159.98幀/秒。文獻[6]針對BWDSP100的硬件特點,采用逆序循環(huán)與位反序尋址等方式充分發(fā)揮IO帶寬,高性能實現(xiàn)了數(shù)字信號處理函數(shù)中的快速傅里葉變換算法,使得1 024點的FFT性能達到了ADI公司的ADSP-TS201系列的8倍。
雙精度浮點數(shù)據(jù)運算具有更大的計算帶寬以及更高的精確度,并且能夠處理更復雜的數(shù)據(jù)。文中主要借鑒已有的一些研究成果,基于循環(huán)展開、軟件流水、向量化和指令調度等常用優(yōu)化技術,并結合HXDSP1042硬件體系結構和指令集特點,對64位數(shù)據(jù)類型的運算函數(shù)庫中的矩陣與向量運算進行并行優(yōu)化與實現(xiàn)。實驗結果表明,相比優(yōu)化前的串行算法結構,并行優(yōu)化后的函數(shù)加速比達到了11以上。
HXDSP1042遵循兼容原則,保證“魂芯一號”(BWDSP100)程序運行,內部集成了2個新一代處理器內核eC104+,如圖1所示,該內核的硬件結構在一代處理器BWDSP100的內核eC104基礎上進行了增強和優(yōu)化。
圖1 eC104+的內核架構
2.1.1 提升運算性能
HXDSP1042仍采用16發(fā)射VLIW和4路SIMD混合結構的EfficiencyCore技術。核內的執(zhí)行部件包含在4個執(zhí)行宏中,但執(zhí)行宏的功能在eC104的基礎上進行了增強,從而極大地提升了DSP的運算性能。其中, MUL由原來的4個擴展到了8個,SHF由原來的2個擴展到了4個,并且通用寄存器也增加了一倍。具體內容如表1所示。
2.1.2 擴展指令集
所支持的指令操作由之前的600多條增長到了1 300多條,擴展了謂詞指令,支持條件執(zhí)行,增加了面向圖像處理、通信的加速指令,大幅提升了指令執(zhí)行效率。
表1 執(zhí)行宏中的執(zhí)行部件
2.1.3 優(yōu)化存儲空間
HXDSP1042在存儲空間劃分上有優(yōu)化,程序空間和數(shù)據(jù)空間在物理上分離,相對于BWDSP100的3個內存塊,其內存塊增加到6個,每個內存塊(block)的大小為256 K*32 bit。雙內核共享256 K字指令存儲器(SRAM),提高了該DSP的多任務調度效率。
2.1.4 流水線擴展
流水線擴展到了13級。其中取指令占3級,指令緩沖占3級,指令譯碼占4級,取操作數(shù)占1級,指令執(zhí)行占1級,指令結果寫回占1級。影響指令執(zhí)行的因素中數(shù)據(jù)相關、數(shù)據(jù)bank 沖突、原子操作、訪問核外存儲資源引發(fā)的等待,均可引發(fā)指令流水的停頓,需要在算法優(yōu)化過程中避免。
2.1.5 豐富的外設
HXDSP1042集成6對高速SerDes接口,工作在x4模式,支持協(xié)議包括RapidIO(最多2對)、PCIe3.0(最多1對)及JESD204B(最多3對)等協(xié)議。由于支持JESD204B協(xié)議,“魂芯二號”DSP可實現(xiàn)與ADC/DAC器件的高速直接互聯(lián)。此外,“魂芯二號”DSP還集成有DDR3/4、Ethernet、UART、GPIO、I2C和并口等常用外設,方便用戶使用。
HXDSP計算指令的通用格式如下:
[Macro]Rm=Rn op Rs
Macro是執(zhí)行宏的代號,op是操作,符號“‖”連接多個可并行指令,比如:xRm=Rn+Rs是Scalar指令,表示在X宏上執(zhí)行整數(shù)加法操作,xyztRm=Rn+Rs是SIMD指令,表示在{X,Y,Z,T}四個宏上同時執(zhí)行整數(shù)加法操作,等于xRm=Rn+Rs‖yRm=Rn+Rs‖zRm=Rn+Rs‖tRm=Rn+Rs。
HXDSP雖然采用了SIMD架構,但并沒有提供傳統(tǒng)意義上的長向量化部件,而是提供了很多向量化指令[7]。文中經常用到的指令包括:64位浮點數(shù)據(jù)的乘法指令、加減法指令以及雙字尋址指令等。以下是常用指令的詳細說明。由于在HXDSP中只有32位寄存器,因此對于64位數(shù)據(jù)的存儲需要利用原有的32位寄存器分別存儲64位數(shù)據(jù)的高位和低位,64位浮點的加減法的實現(xiàn)需要四條微操作指令:
{Macro}DFHACCk=DFHRm+1±DFHRn+1
{Macro}DFLACCk=DFLRm±DFLRn
{Macro}DFHRs+1=DFHACCk
{Macro}DFLRs=DFLACCk
其中,DFHACCk和DFLACCk在指令中存儲的是64位加減法的結果。HRm、LRm兩個寄存器分別存儲64位浮點數(shù)的高低32位,代表一個64位浮點數(shù),這兩個通用寄存器的索引號必須連續(xù)。存儲結果記為DFRs+1:s,Rs+1存儲64位浮點數(shù)的高32位,Rs存儲低32位。在計算時需要先算高位數(shù)再算低位數(shù),等高低位數(shù)都計算完成才可將結果保存至寄存器,并且以上4個微操作的ALU選擇“k”必須相同,才能完成一次64位浮點數(shù)減法,占一個ALU。對于double乘法的實現(xiàn),需要通過兩條指令組合進行使用,有如下兩種方式:
{Macro}QMACCH=DFRm+1:m*DFRn+1:n
{Macro}DFRs+1:s=QMACCH
或:
{Macro}QMACCL=DFRm+1:m*DFRn+1:n
{Macro}DFRs+1:s=QMACCL
其中,QMACCH和QMACCL在指令中存儲的都是64位乘法的結果。該指令實現(xiàn)的功能為將寄存器Rm+1:m中存儲的64位浮點數(shù)與Rn+1:n中的64位浮點數(shù)相乘,結果存入Rs+1:s中。兩種方式實現(xiàn)的功能都是64位浮點數(shù)據(jù)的乘法,其中{Macro}表示指定某個或某些宏內進行運算,如果{Macro}為空就表示四個宏上都進行乘法運算。
本節(jié)使用到的優(yōu)化方案,其著力點在于消除性能瓶頸,試圖通過多讀多寫的方式,盡可能讓所有功能部件參與運算,鋪滿流水線,從而獲得函數(shù)執(zhí)行性能和效率的提升。
雙字尋址傳輸指令允許程序在1個時鐘周期內讀取多個字,進一步減少函數(shù)的訪存次數(shù),如:
{X,Y,Z,T} Rs+1:s=[Un+=Um,Uk]
[Un+=Um,Uk]={X,Y,Z,T}Rs+1:s
第一條指令是讀訪存指令, Un是基地址,Uk是在Un地址基礎上的調整量,Um則是指令執(zhí)行后基地址Un的修正量。指令采用雙字節(jié)尋址,故指令1表示能夠一次性讀出[Un]和[Un+1]、[Un+2Uk]和[Un+2Uk+1]、[U0+2×2U2]和[U0+2×2U2+1]、[U0+3×2U2]和[U0+3×2U2+1]共8個地址的數(shù)據(jù),并將第這8個地址的數(shù)據(jù)依次送到4個宏的同名寄存器{X,Y,Z,T} Rs+1:s。第二條指令是寫存儲指令。由于Uk的大小不確定,如果某兩個或兩個以上的地址落在同一存儲器bank上,就會產生bank沖突,一旦產生bank沖突,必須使整個流水線停頓,直到所有的數(shù)據(jù)被正確的讀出或寫入,才能恢復正常流水。
移位器的使用:移位器的作用在于對源操作數(shù)進行任意裁減、分解、移位和拼接等。濾波算法里涉及到一些求商的計算,可使用移位器來代替需要迭代的除法實現(xiàn)。比如,要計算單精度浮點數(shù)r4除以32的值,通常情況下為了保證浮點數(shù)據(jù)的精度,需要對除法計算進行迭代,此時用算術移位器來做除法計算只需要一個微指令r4 ashift -5就可以實現(xiàn)。
BWDSP體系結構中具有三個地址產生器(U,V,W),相互獨立工作,HXDSP104X內核內部數(shù)據(jù)總線一共有四條,為兩讀兩寫,同一時間最多只允許三條總線工作,也就是說一個時鐘周期內最多進兩組數(shù)。在矩陣與向量計算的循環(huán)體內可使用r11:10=[u0+=8,1]‖r15:14=[v0+=8,1]‖[w0+=2,1]=r61:60并行指令實現(xiàn)兩讀一寫的操作,或者使用[u0+=8, 1]=r3:2‖[v0+=8, 1]=r1:0‖r5:4=[w0+=8, 1]實現(xiàn)兩寫一讀的操作,也就是支持同時3條讀寫指令,使得在一個指令行內可讀取多個向量數(shù)據(jù),提升計算效率。
HXDSP芯片指令并行的優(yōu)化指的是同一指令同時控制多個運算單元執(zhí)行相同操作的優(yōu)化。SIMD架構使得在一條指令中便可以操作多條數(shù)據(jù)流,各個運算宏之間同種運算部件進行相同的操作可以用一條指令來控制,這樣就可以很好地兼顧運算部件控制的靈活性和計算效率之間的矛盾。HXDSP1042內一共有4個互相獨立的計算單元(4路SIMD),依次是簇X,Y,Z和T。每個計算簇內都有ALU、MUL、SHF、SPU和寄存器組,這些器件可以對不同類型的數(shù)據(jù)進行計算與操作。并且每個計算簇均有相應的讀寫端口,端口通過芯片內部讀寫數(shù)據(jù)總線與片上SRAM內存連接,共形成了4條數(shù)據(jù)通道[8]。由于HXDSP芯片內部具有以上特點,因此在具體優(yōu)化運算函數(shù)時,要對算子進行具體分析,使其充分利用硬件資源單元。使用單條指令在4個運算邏輯單元操作不同通道的數(shù)據(jù),從而實現(xiàn)算子在HXDSP內部的細粒度并行計算。
程序中的條件分支是影響程序性能的一個重要原因,普通的“if”循環(huán)判斷指令在ECS的環(huán)境中需要占10個時鐘周期的時間,這使得有循環(huán)操作算法的運算總開銷大大增加。而使用零開銷循環(huán)指令,相對于普通的“if”指令而言只需占用1個時鐘周期,降低了循環(huán)總開銷,零開銷循環(huán)的作用就相當于自動計數(shù)裝置,一旦索引值達到循環(huán)體限定的數(shù)字就會自動跳出[9]。HXDSP1042中的指令集提供了LCx(x=0,1,2,3)指令專用與零開銷循環(huán),指令形式為“if LCx B loop”,表示若LCx為真則跳轉至名為“l(fā)oop”的分支處。
基于循環(huán)展開的優(yōu)化指的是在一次循環(huán)中展開多次相同的循環(huán)的優(yōu)化,基于軟件流水的優(yōu)化指的是將所述多次相同的循環(huán)并行交叉執(zhí)行。循環(huán)展開是一種算法實現(xiàn)級的優(yōu)化,通過將循環(huán)體代碼重復多次來實現(xiàn),這也是一種向量化的思想。循環(huán)展開通過將迭代間的并行轉化為迭代內的并行,讓循環(huán)體內部的運行周期盡可能減少。當使用到的數(shù)據(jù)之間不相關時,這些指令的流水線是可以并行起來執(zhí)行的[10-12]。
在庫函數(shù)中,通常程序中的循環(huán)占用了較大的時間比,因此匯編程序的優(yōu)化主要是對循環(huán)的優(yōu)化。循環(huán)展開是通過增加每次迭代元素的數(shù)量,來減少循環(huán)的迭代次數(shù)。同時流水線技術可以讓多條指令線重疊起來,并行執(zhí)行,以此提高程序并行度[13]。
HXDSP采用可讀性強的匯編指令,VLIW(超長指令字)架構使得單周期內可并行執(zhí)行16條指令,同時應用程序分支預測機制減少了分支程序在流水線中的開銷。為了避免流水線的空轉,對于不存在相關依賴或沖突的指令可以組合拼成一個指令行,提高指令并行度[14]。指令調度即從程序中識別出指令級可并行的成分,并利用這些可并行性合理安排指令的執(zhí)行順序,已達到最大限度發(fā)揮目標機所提供的處理能力的目的。目前該編譯器還未實現(xiàn)自動化識別,需要進行手動指令調度來盡可能地提升硬件利用率[15]。
4 雙精度浮點矩陣與向量運算函數(shù)的優(yōu)化實現(xiàn)
為了滿足一些對高精度浮點運算的科學計算的需求,函數(shù)庫中最常用的單精度浮點基本運算都有與之對應的雙精度浮點數(shù)據(jù)的運算。對于32位浮點類型數(shù)據(jù)只能保證6位7位有效數(shù)字,不能滿足一些更高精度的數(shù)據(jù)運算,而64位的浮點雙精度數(shù)據(jù)類型能夠保證15位、16位的有效數(shù)字,滿足大多數(shù)浮點數(shù)據(jù)運算的要求[16]。 “xmulv”表示double型實數(shù)矩陣乘以double型向量。對于矩陣和向量之間的操作,主要是乘法以及累加計算的操作,但是在實際結合硬件架構進行匯編優(yōu)化時,需要考慮的因素眾多,不僅要滿足理論運行時間,還要達到精度的技術指標。設A=(aij)是一個m×s的矩陣,B=(bi)是一個s×1的向量,則矩陣乘以向量(xmulv)的通用公式定義為:
ci=ai1b1+ai2b2+…+aisbs,i=1,2,…,m
(1)
展開后可表示為:
(2)
文中實驗的軟件平臺為“魂芯”系列處理器的統(tǒng)一軟件開發(fā)平臺ECS,所使用的軟件版本為ECS2.0,使用的指令集為BW32v2最新版指令集。HXDSP1042處理器的工作頻率為700 MHz,所以一個時鐘周期為1.4 ns。文中的工作將以矩陣乘以向量運算函數(shù)(xmulv)為例進行闡述。
4.2.1 算法實施層的優(yōu)化
矩陣乘以向量(xmulv)算法實現(xiàn)的偽代碼如下:
算法1:xmulv函數(shù)的偽代碼。
輸入:矩陣pa,向量pb
輸出:pc=pa*pb
(1)function xmulv(pa, pb, pc)
(2)for row=0→a-1 do
(3)pc[i]=0
(4)for col=0→b-1 do
(5)pc[i]+=pa[i*b+k] * pb[k]
(6)end for
(7)end for
將未經優(yōu)化的原始算法記為算法1,這部分的矩陣乘向量函數(shù)的實現(xiàn)是串行的,沒有發(fā)揮出HXDSP的底層架構優(yōu)勢,因此需要結合具體的硬件架構和指令特點來對算法的實現(xiàn)進行優(yōu)化。在進行細粒度并行優(yōu)化前,先對其進行算法實施層的優(yōu)化:將兩層for循環(huán)用3.3節(jié)介紹的零開銷循環(huán)進行改寫。對于向量運算,只需要一層循環(huán),對于矩陣運算則至少需要兩層循環(huán)來實現(xiàn)。矩陣(M×N)乘向量(N×1)的運算,外層需要M次循環(huán)迭代,內層需要N次循環(huán)迭代,串行運算時共需要M×N×10個時鐘周期。將普通的“if”判斷換成零開銷循環(huán)判斷,所占用的運行時鐘周期可以至少降到M×N個,顯著降低了循環(huán)總開銷,得到了算法2。64位數(shù)據(jù)的矩陣乘以向量函數(shù),具體實現(xiàn)時共有兩層循環(huán),內層循環(huán)實現(xiàn)矩陣的行與向量的乘累加結果,外層循環(huán)控制行的移位操作,其匯編形式核心代碼循環(huán)展開之前的形式如下:
算法2 :矩陣乘向量運算串行計算。
輸入:64位數(shù)據(jù)的矩陣,64位數(shù)據(jù)的向量
輸出:矩陣乘以向量的結果
(1)_xmulv_rowloop://外層循環(huán)
(2)_xmulv_maccloop: //內層循環(huán)
(3)xr11:10=[u0+=8,1] //取矩陣的值(每次取一個值)
(4)xr15:14=[v0+=8,1] //取向量的值(每次取一個值)
(5)xQMACCH=DFR11:10*DFR15:14 //相乘
(6)xDFR31:30=QMACCH
(7)xDFHACC0=DFHR41+DFHR31 //將結果存至累加器
(8)xDFLACC0=DFLR40+DFLR30
(9)xDFHR41=DFHACC0 //存儲高位值
(10)xDFLR40=DFLACC0 //存儲低位值
(11).code_align 16
(12)if lc0 b _xmulv_maccloop
(13)_xmulv_maccexit:
(14)[w0+=2,1]=xr41:40 //存儲結果值到寄存器w0
(15).code_align 16
(16)if lc2 b _xmulv_rowloop
在這種未進行循環(huán)展開的形式下,一個矩陣乘向量的計算總共需要做M×N×2次訪存和乘累加的計算操作,M×N次內層循環(huán)判斷,M次外層循環(huán)判斷。對于64位數(shù)據(jù)的運算指令本身就比32位計算要復雜,這使得函數(shù)運算所需的理論運行時間太大,達不到庫函數(shù)的技術指標。
HXDSP芯片內部包含4個執(zhí)行宏,每個執(zhí)行宏包含64字的通用寄存器組,通用寄存器組內又分為A面寄存器和B面寄存器,所以每個宏內有128個通用寄存器,四個宏的運算可以并行。并且,在HXDSP的內核eC104+中,內和數(shù)據(jù)總線有2條讀總線和2條寫總線,總線提供的數(shù)據(jù)字寬為3個64 bit,最多可同時利用其中的3條總線實現(xiàn)傳輸,即同時最多支持兩讀一寫或者兩寫一讀的讀寫模式。在具體實現(xiàn)時,可以同時讀取4個矩陣中的雙精度浮點實數(shù)和4個向量中的數(shù)進行計算。循環(huán)內部的乘法和累加循環(huán)計算需要按照3.4節(jié)的方法將循環(huán)進行展開,具體的方式如下:
上述代碼執(zhí)行時,每次從矩陣和向量中分別取出一個數(shù)進行相乘累加運算,只利用了eC104+內核中的一個執(zhí)行宏X,沒有充分利用核內的數(shù)據(jù)總線和運算資源??紤]SIMD指令與雙字尋址方法,可以從4個宏中同時讀取數(shù)據(jù)。每次循環(huán)完成4個輸入元素的運算,雙字傳輸方式使得每次都能從各個執(zhí)行宏中讀取1個64位的數(shù)據(jù),即64 bit×4=256 bit,占滿一條讀總線。向量數(shù)據(jù)的訪存占用另一條讀總線與之并行,這使得訪存操作次數(shù)由原來的M×N減少到了M×N×2/8。同時,結合循環(huán)展開的優(yōu)化技術,可優(yōu)化循環(huán)體中的讀取、處理和存儲操作,將循環(huán)過程中不相關的數(shù)據(jù)通過循環(huán)展開并行執(zhí)行,減少循環(huán)過程中的運行時間。這使得內層循環(huán)次數(shù)減少到了1/4。得到優(yōu)化后的核心代碼例子如下:
算法3:矩陣乘向量運算并行優(yōu)化。
輸入:64位數(shù)據(jù)的矩陣,64位數(shù)據(jù)的向量
輸出:矩陣乘以向量的結果
(1)_xmulv_rowloop:
(2)_xmulv_maccloop:
(3)r11:10=[u0+=8,1]‖r15:14=[v0+=8,1] /*同時取矩陣與向量的值(每個指令行可取4個64bit的值)*/
(4)QMACCH=DFR11:10*DFR15:14 //4個值的乘法同時計算
(5)DFHACC0=DFHR41+DFHR31‖DFR31:30=QMACCH
(6)DFLACC0=DFLR40+DFLR30‖DFHR41=DFHACC0
(7)DFLR40=DFLACC0
(8).code_align 16
(9)if lc0 b _xmulv_maccloop
(10)_xmulv_maccexit:
(11)[w0+=2,1]=r41:40 //存儲結果值到寄存器w0
(12).code_align 16
(13)if lc2 b _xmulv_rowloop
在實現(xiàn)過程中,充分考慮軟件流水技術,通過重組循環(huán)來減少指令間的延遲,設法使得不同循環(huán)體之間的指令能夠并行執(zhí)行,從而使得循環(huán)數(shù)目成倍減少。此時,得到了算法3,算法3相對于算法2的平均性能提升了1.5倍。接下來就是按照3.5節(jié)介紹的指令重排技術讓指令盡可能地并行執(zhí)行,減少運行時間,得到算法4,相對于算法3的實現(xiàn)性能平均提升了1.4倍。算法2、3、4的性能比較如圖2所示。
圖2 算法2~算法4的性能比較
此時,用自動化測試平臺對優(yōu)化后的算法效率進行測試發(fā)現(xiàn)算法的性能并未達到技術指標,并且輸入的矩陣規(guī)格越大所耗費的運行時間越多。因此為了減少運行時間,提高運行效率,需要對軟件流水的排布作進一步的優(yōu)化。
4.2.2 流水排布的優(yōu)化
一般的64位矩陣運算中循環(huán)體軟件流水示意圖如圖3所示。
圖3 通用的64位矩陣計算軟件流水示意圖
對于雙精度浮點的矩陣乘向量函數(shù),在HXDSP中的存儲與計算都是將其高位和低位分別存儲在32位寄存器中,因此在算法處理過程中所花費的時鐘周期相對單精度數(shù)據(jù)計算要多。在進入循環(huán)核心期之前,數(shù)據(jù)讀取和準備操作占用了相當大一部分運行時間。因此,若每次循環(huán)都要從循環(huán)起始期開始執(zhí)行,在跳出循環(huán)核心期的時候會有一部分循環(huán)體是已啟動但并未執(zhí)行操作。當運算的矩陣規(guī)模較大時,這些循環(huán)體已啟動但并未執(zhí)行操作的數(shù)據(jù)就會造成取數(shù)冗余,會大大增加函數(shù)整體的運行時間。為了讓整個運算充分地并行執(zhí)行,提升數(shù)據(jù)量大時的計算效率并避免讀取冗余的數(shù)據(jù),需要對預設的軟件流水排版進行調整,讓每一次循環(huán)取出的數(shù)據(jù)都能被完全執(zhí)行。解決方法就是讓循環(huán)核心期的每一次零開銷循環(huán)判斷跳轉到特定的位置,在該位置將之前循環(huán)起始期所取出的全部數(shù)據(jù)計算完,然后再跳轉至矩陣中下一行需要計算的數(shù)據(jù)。
下面給出匯編算法主體循環(huán)部分中的一個cycle進行具體說明:
.code_align 16
if nlc0 b _xmulv_maccexit2‖DFLR40=DFLACC0
r21:20=[u0+=8,1]‖r25:24=[v0+=8,1]
‖QMACCL=DFR23:22*DFR27:26
‖DFR35:34=QMACCH
‖DFHACC3=DFHR47+DFHR37
‖DFLACC2=DFLR44+DFLR34
‖DFHR43=DFHACC1
主循環(huán)中每次循環(huán)可處理4個64位數(shù)據(jù)的取值、運算和累加。BWDSP1042算法編寫只有A面寄存器時支持16個slot,當一個cycle中存在A、B面寄存器傳輸時,最多只支持14個slot,這就使得算法編寫有時陷入瓶頸,編寫時應盡量避免這種情況。上述這段代碼中,第一段代碼共占用3個slot,其中跳轉指令占用了2個slot;第二段代碼共占用了7個slot,共占用了8個MUL,8個ALU,所以ALU和MUL的利用率為100%。主循環(huán)體中的每段代碼執(zhí)行完成之后,都會跳轉至對應的位置即“Loop_exit n”處,目的是為了將之前讀取的數(shù)計算完。
調整后的循環(huán)排布主要有兩部分做了調整:第一部分是循環(huán)結尾部分,不再使用統(tǒng)一的結尾方式。而是讓每個從循環(huán)體內跳出的分支都有一個單獨的結構去將之前取出的數(shù)完全計算完,不至于造成取數(shù)冗余。計算的同時再并行上矩陣運算的下一行的循環(huán)起始與核心期,使得每個指令行都是充分地并行執(zhí)行。可以看出,對下一行計算的處理部分是相同的,這樣做的目的是為了方便計算完下一行的數(shù)之后重新跳轉至“Loop”處,接著計算剩余的數(shù)。
第二部分是循環(huán)次數(shù)的調整。由于Loop循環(huán)體內的每個指令行執(zhí)行完都會跳轉至不同的分支指令,因此需要對零開銷循環(huán)次數(shù)lcx根據(jù)具體的方案進行調整。對于文中所實現(xiàn)的矩陣乘運算函數(shù),循環(huán)起始期用了10拍取出了10×4個數(shù)(每一拍取出4個64位的數(shù)),核心期用了10拍取出了10×4個數(shù)。因此內層循環(huán)lc0初始值為n/4-10,經過下一行計算時lc0被賦值為n/4-20。將該思想應用到算法中后得到算法5。
在以上優(yōu)化的基礎上,再對匯編代碼的并行性進一步挖掘,再次利用3.5節(jié)的指令調度技術將算法再次優(yōu)化。在64位運算中,對于累加計算,需要提前設定幾個寄存器作為累加器來存儲每回累加計算的結果。這些累加器的初始化以及對于零開銷循環(huán)次數(shù)lc0、lc1的設置可以通過指令調度將其與其他不相關的指令行并行來避免單獨占用一個運行周期。此時,得到算法6。算法5和算法6的性能比較如圖4所示。
圖4 算法5和算法6的性能比較
表2是具體的對矩陣乘向量函數(shù)(xmulv)進行優(yōu)化前后的性能對比。其中cycles為時鐘周期的單位,表中結果數(shù)據(jù)為使用算法優(yōu)化前后在HXDSP1042處理器上執(zhí)行不同數(shù)據(jù)規(guī)模程序時的具體時鐘周期數(shù)。
由表2可得,算法xmulv相對于優(yōu)化前的初始算法平均性能提升了大概14.96倍。實驗結果表明,VLIW DSP處理器下文中的優(yōu)化方法充分利用處理器強大的計算能力和資源優(yōu)勢,可使得64位的矩陣函數(shù)的運算時鐘周期明顯減少,可顯著提升該函數(shù)在VLIW DSP上的執(zhí)行性能。
表2 矩陣乘向量函數(shù)(xmulv)優(yōu)化前后的對比
針對HXDSP1042芯片體系結構特點,文中對其軟件系統(tǒng)所配套的64位運算函數(shù),通過利用數(shù)據(jù)讀取操作并行、零開銷循環(huán)、循環(huán)展開與軟件流水、指令調度等方法進行優(yōu)化,實現(xiàn)了相關函數(shù)匯編代碼。實驗結果表明,在充分挖掘其并行性下,雙精度浮點型矩陣乘以向量函數(shù)的加速比能達到11以上,證明匯編函數(shù)的優(yōu)化效果可以提升函數(shù)在HXDSP上的計算性能。該并行性優(yōu)化方法對該系列的DSP上的函數(shù)基本適用,其中優(yōu)化后的循環(huán)展開與軟件流水排布對類似的矩陣運算都具有參考意義。在下一步工作中,將對雙精度浮點運算函數(shù)的操作指令進行改進,以進一步完善與優(yōu)化雙精度庫函數(shù)的計算效率,使其滿足大量需要高精度浮點運算的計算需求,提高工作效率。