fract16型のベクトルとfract16型の固定小数点乗算を行います。
ベクトル乗算同様にC++言語を使って記述したのが以下のプログラムです。
void stk::mul( fract16 dst[], fract16 src1[], fract16 src2, int count ) { #pragma no_alias #pragma different_banks for ( int i=0; i<count; i++ ) dst[i] = multr_fr1x16( src1[i], src2); }
さて、VisualDSP++3.5( February Update )が生成するコードを以下に示します。
このコードはベクトル同士の乗算同様に細かく場合分けされ、SIMD化されていますが、残念なことにループボディーの長さは人間が最適化する場合より1サイクル増えています。つまり、性能は半分しか出ていません。手で最適化すれば2191空挺団のなぜ最適化できるかで説明した3段ソフトウェア・パイプライン化によってループ・ボディーを1サイクルに収めることができます。
Dumping range 0xffa009fc - 0xffa00afb by 1 (Assembly)... [FFA009FC] P1 = R0 ; [FFA009FE] P0 = R1 ; [FFA00A00] [ -- SP ] = R7 ; [FFA00A02] R3 = [ SP + 0x10 ] ; [FFA00A04] CC = R3 <= 0 ; [FFA00A06] IF CC JUMP 114 /*0xFFA00A78*/ ; [FFA00A08] R0 = R0 | R1 ; [FFA00A0A] R7 = 3 ; [FFA00A0C] R0 = R0 & R7 ; [FFA00A0E] CC = R0 == 0 ; [FFA00A10] IF ! CC JUMP 76 /*0xFFA00A5C*/ ; [FFA00A12] CC = R3 <= 1 ; [FFA00A14] IF CC JUMP 62 /*0xFFA00A52*/ ; [FFA00A16] R0 = 1 ; [FFA00A18] R7 = R3 >>> 1 ; [FFA00A1C] R0 = MAX ( R0 , R7 ) ; [FFA00A20] R0 += -1 ; [FFA00A22] I0 = R1 ; [FFA00A24] P0 = R0 ; [FFA00A26] R2.H = R2.L << 0x0 ; [FFA00A2A] LSETUP ( 14 /*0xFFA00A38*/ , 22 /*0xFFA00A40*/ ) LC0 = P0 ; [FFA00A2E] CC = R0 == 0 ; [FFA00A30] R0 = [ I0 ++ ] ; [FFA00A32] IF CC JUMP 16 /*0xFFA00A42*/ ; [FFA00A34] NOP ; [FFA00A36] NOP ; [FFA00A38] R1.H = R0.H * R2.H , R1.L = R0.L * R2.L || NOP || R0 = [ I0 ++ ] ; [FFA00A40] [ P1 ++ ] = R1 ; [FFA00A42] R1.H = R0.H * R2.H , R1.L = R0.L * R2.L ; [FFA00A46] R0 = 1 ; [FFA00A48] R0 = R3 & R0 ; [FFA00A4A] CC = R0 == 1 ; [FFA00A4C] [ P1 ++ ] = R1 ; [FFA00A4E] P0 = I0 ; [FFA00A50] IF ! CC JUMP 40 /*0xFFA00A78*/ ( BP ) ; [FFA00A52] R0 = W [ P0 ++ ] ( X ) ; [FFA00A54] R0.L = R0.L * R2.L ; [FFA00A58] W [ P1 ++ ] = R0 ; [FFA00A5A] JUMP.S 30 /*0xFFA00A78*/ ; [FFA00A5C] R0 = 1 ; [FFA00A5E] R0 = MAX ( R0 , R3 ) ; [FFA00A62] P2 = R0 ; [FFA00A64] R0 = W [ P0 ++ ] ( X ) ; [FFA00A66] I0 = P1 ; [FFA00A68] LSETUP ( 4 /*0xFFA00A6C*/ , 8 /*0xFFA00A70*/ ) LC0 = P2 ; [FFA00A6C] R0.L = R0.L * R2.L ; [FFA00A70] MNOP || R0 = W [ P0 ++ ] ( X ) || W [ I0 ++ ] = R0.L ; [FFA00A78] R7 = [ SP ++ ] ; [FFA00A7A] RTS ;
この辺はまだまだと思わせますが、どうでしょう。今回はベクトルとスカラーの積にそれほど性能を求めるわけではないので、このまま手を加えないで使っています。