//第二個循環(huán)體 sum = _sadd(sum,_smpy(y[i], y[i])); 這段代碼包含了兩個for循環(huán),在ccs中直接編譯運行并行度很差,利用線性匯編重寫代碼。我們發(fā)現(xiàn)兩個循環(huán)體的循環(huán)次數(shù)均為60(l_window=60),所處理的數(shù)組不同,并且兩個循環(huán)沒有相關性,可以把第一和第二個循環(huán)合并成一個循環(huán)。前者的功能是對語音信號進行加窗;后者是實現(xiàn)乘累加(mac)。兩者合并后采用線性匯編編寫,其代碼如下: mvk 60,i //設置循環(huán)次數(shù) loop1: lddw *ham++,hamih:hamil //hamwindow[]指針 lddw *x++,xih:xil //x[]指針 smpy2 hamil,xil,yi1:yi0 //兩對16位操作數(shù)相承,并行執(zhí)行 smpy2 hamih,xih,yi3:yi2 sadd yi0,con0x8000,yi0 sadd yi1,con0x8000,yi1 sadd yi2,con0x8000,yi2 sadd yi3,con0x8000,yi3 pac
r_16 to8copy _transfer_16 to8copy: . cp roc dst, src, stride . reg pdst, p src, count . reg ahi: alo, bhi: blo, chi: clo mvk 8, count mv dst, pdst mv src, p src loop: . trip 8, 8 lddw 3 *psrc, ahi: alo spacku4 ahi, alo, blo; keep the value in the range 0 - 255 lddw 3 *+psrc (8) , chi: clo spacku4 chi, clo, bhi stdw bhi: blo, 3 pdst add pdst
則編寫的線性匯編代碼的效率更高。具體的優(yōu)化措施如下: ①使用偽指令向匯編優(yōu)化器提供較為詳細的信息。 ②畫出指令的相關圖,根據相關圖合理分配邏輯單元,最大限度地保證指令的并行執(zhí)行。 ③充分使用c64x dsp 提供的強大包處理指令處理數(shù)據(包處理指令可同時處理2 個l6 位數(shù)據和4 個8 位數(shù)據)。本系統(tǒng)中使用了avgu4、min2、m ax2、spacku4、pack2、d0t p2、d0t pn2 和unpklu4 等指令。c64x dsp 還提供了stdw( stndw)、lddw( ldndw)指令, 可一次存取連續(xù)的64 位數(shù)據??衫胠ddw 指令, 將作1 次行變換所需數(shù)據1 次取來, 并將處理后的結果利用stdw 指令一次存好。這樣大大縮短了代碼長度, 提高了代碼效率。 ④利用schedule table 確定循環(huán)的重復間隔, 合理安排功能單元, 進行軟件的流水。 ⑤對于兩重循環(huán)嵌套, 可將內層循環(huán)展開為外層循環(huán)內部的條件指令。這樣可減小由內層循環(huán)所帶來的循環(huán)前后的prolog 和epilog 的開銷。 3 性能分析 設計、調試好硬件系統(tǒng)
可以用_sadd()內聯(lián)函數(shù)實現(xiàn),它是一個單周期的c6x指令。 result=_sadd(a,b); 要提高c6000數(shù)據處理率,應使一條load/store指令能訪問多個數(shù)據。c6000有與內聯(lián)函數(shù)相關的指令,例如_add2(),_mpyhl(),_mpylh()等,這些操作數(shù)以16位數(shù)據形式存儲在32位寄存器的高位部分和低位部分。當程序需要對一連串短型數(shù)據進行操作時,可使用字1次訪問2個短型數(shù)據,然后使用c6000相應指令來處理數(shù)據。相似的在c64x或c67x中,有時需要執(zhí)行64位的lddw來訪問兩個32位數(shù)據,4個16位數(shù)據,甚至8個8位數(shù)據。 3.2.4 循環(huán)展開 循環(huán)展開是改進性能的另一種,即把小循環(huán)的迭代展開,以讓循環(huán)的每次迭代出現(xiàn)在代碼中。這種方法可增加并行執(zhí)行的指令數(shù)。 有3種使循環(huán)展開的方法: (1)編譯器自動執(zhí)行循環(huán)展開; (2)在程序中使用unroll偽指令建議編譯器做循環(huán)展開; (3)用戶自己在c/c++代碼中展開。 3.3 匯編優(yōu)化 在對c/c++代碼使用了所有的c/c++優(yōu)化手段之后,如果仍然不滿意代碼的性能,就可以寫線性匯編
b0,b1,b2,b3 ;zero cntr ;zero con1 ;zero con2 mvk 15,cntr mvk 145,con1 mvk 60, con2 zero con3 mvkl 0x8000,con3 mpy sfc,con2,sfc1 ;sfc*60 add con1,sfc1,add1 ;145+sfc*60 add add1,pfindex,add2 ;145+sfc*60+pfindex add buff,add1,buff1 add buff,add2,buff2 ;lddw *buff2++,t3:t4 ;讀取64位的數(shù)據 loop: .trip 15 lddw *buff1++,t1:t2 ;讀取64位的數(shù)據(t2為低位) lddw *buff2++,t3:t4 ;讀取64位的數(shù)據 smpyhl t2,pfscgn,a1 smpyhl t1,pfscgn,a3 smpy t2,pfscgn,a0 smpy t1,pfscgn,a2 smpyhl t4,pfgain,b1 smpyhl t3,pfgain,b3 smpy t4,pfgain,b0 smpy t3,
----------------------------------;; load/store word from/to direct memory/immediate;; ldsw z,mem; ldiw z,imm.macro ldiw ldi @0l,low(@1) ldi @0h,high(@1).endm.macro ldsw lds @0l,@1 lds @0h,@1+1.endm.macro lddw ldd @0l,@1 ldd @0h,@1+1.endm.macro stsw sts @0,@1l sts @0+1,@1h.endm.macro stdw std @0,@1l std @0+1,@1h.endm;------------------------------------------------;; store immediate into indirect memory via r16;;