FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

自作CPUにベクトル命令を追加する実装検討 (24. ベクトル・ベンチマークのデバッグ)

簡単なベクトル命令のベンチマークを作って、動かしてみようと思う。

作ったのはAXPYで、単純に2つのベクトル要素をロードして足し算して、ベクトルストアするだけだ。

 // vvadd function                                                                                                                                                                                                                                                                                                                                                                        

 void vvadd( int n, int a[], int b[], int c[] )
 {

   int i;
   for ( i = 0; i < n; i++ )
     c[i] = a[i] + b[i];
 }

で、これをベクトル化するとこんな感じのアセンブリ命令となる。

github.com

 vvaddint32:
     vsetvli t0, a0, e32, ta, ma  # Set vector length based on 32-bit vectors
     vle32.v v0, (a1)         # Get first vector
       sub a0, a0, t0         # Decrement number done
       slli t0, t0, 2         # Multiply number done by 4 bytes
       add a1, a1, t0         # Bump pointer
     vle32.v v1, (a2)         # Get second vector
       add a2, a2, t0         # Bump pointer
     vadd.vv v2, v0, v1       # Sum vectors
     vse32.v v2, (a3)         # Store result
       add a3, a3, t0         # Bump pointer
       bnez a0, vvaddint32    # Loop back
     ret                    # Finished

まずは単純にテストを動かしてみる。まあデバッグが足りてないから落ちるだろうな。

最初の数回のイタレーションは動いた。以下の波形を見ると、最初のイタレーションのベクトル・ロードに対して、演算と次のイタレーションのベクトル・ロードが動いてアウト・オブ・オーダ実行ができていることがわかる。

でも変だな?次のベクトル演算が開始するまでに時間がかかりすぎている。ちょっとこの辺は要解析だと思う。

6607 : 484 : PC=[0000000080002004] (M,38,01) 0205e007 vle32.v v0, (a1)
VPR[00](32) <= 000002b6_00000188_0000037a_000003a3_00000006_0000026d_00000325_00000248_000003b5_00000084_0000015e_000002ed_000000bb_00000234_00000341_00000029_
6607 : 485 : PC=[0000000080002008] (M,38,02) 40550533 sub     a0, a0, t0
GPR[10](13) <= 000000000000011c
6607 : 486 : PC=[000000008000200c] (M,38,04) 0000028a c.slli  t0, 2
GPR[05](2) <= 0000000000000040
6607 : 487 : PC=[000000008000200e] (M,38,08) 00009596 c.add   a1, t0
GPR[11](119) <= 0000000080003480
6617 : 488 : PC=[0000000080002010] (M,39,01) 02066087 vle32.v v1, (a2)
VPR[01](33) <= 000000e4_00000382_00000251_00000153_0000023c_000000d2_0000008c_000000d8_00000099_00000040_0000023c_0000016d_000003dd_00000001_0000014f_000001c6_
6617 : 489 : PC=[0000000080002014] (M,39,02) 00009616 c.add   a2, t0
GPR[12](149) <= 0000000080003940
6617 : 490 : PC=[0000000080002016] (M,39,04) 02008157 vadd.vv v2, v0, v1
VPR[02](70) <= 0000039a_0000050a_000005cb_000004f6_00000242_0000033f_000003b1_00000320_0000044e_000000c4_0000039a_0000045a_00000498_00000235_00000490_000001ef_
26490 : L1D Load-In     : 80003480(00210) : 00000239_0000021b_000003aa_000001da_00000178_0000036b_000002a6_0000013f_00000306_00000293_0000013a_000001aa_00000128_00000074_0000006e_000003c1
26490 : Load ISS Check  : 80003480        : 00000239_0000021b_000003aa_000001da_00000178_0000036b_000002a6_0000013f_00000306_00000293_0000013a_000001aa_00000128_00000074_0000006e_000003c1
6623 : 491 : PC=[000000008000201a] (M,40,01) 0206e127 vse32.v v2, (a3)
==========================================
6623 : 492 : PC=[000000008000201e] (M,40,02) 00009696 c.add   a3, t0
GPR[13](73) <= 0000000080024080
6623 : 493 : PC=[0000000080002020] (M,40,04) 0000f165 c.bnez  a0, pc - 32
6624 : 494 : PC=[0000000080002000] (M,41,01) 0d0572d7 vsetvli t0, a0, e32, m1, ta, ma
GPR[05](178) <= 0000000000000010
6634 : 495 : PC=[0000000080002004] (M,42,01) 0205e007 vle32.v v0, (a1)
VPR[00](34) <= 00000239_0000021b_000003aa_000001da_00000178_0000036b_000002a6_0000013f_00000306_00000293_0000013a_000001aa_00000128_00000074_0000006e_000003c1_
6634 : 496 : PC=[0000000080002008] (M,42,02) 40550533 sub     a0, a0, t0
GPR[10](99) <= 000000000000010c
6634 : 497 : PC=[000000008000200c] (M,42,04) 0000028a c.slli  t0, 2
GPR[05](157) <= 0000000000000040
6634 : 498 : PC=[000000008000200e] (M,42,08) 00009596 c.add   a1, t0
GPR[11](152) <= 00000000800034c0
6640 : 499 : PC=[0000000080002010] (M,43,01) 02066087 vle32.v v1, (a2)
VPR[01](36) <= 000001fd_00000287_00000102_00000110_00000234_000002b8_00000096_000003d5_0000032c_000002bd_000001b4_000001f4_00000286_000002ee_00000373_0000000c_
6640 : 500 : PC=[0000000080002014] (M,43,02) 00009616 c.add   a2, t0
GPR[12](66) <= 0000000080003980
6640 : 501 : PC=[0000000080002016] (M,43,04) 02008157 vadd.vv v2, v0, v1
VPR[02](71) <= 00000436_000004a2_000004ac_000002ea_000003ac_00000623_0000033c_00000514_00000632_00000550_000002ee_0000039e_000003ae_00000362_000003e1_000003cd_
26566 : L1D Load-In     : 80024040(00257) : 0000039a_0000050a_000005cb_000004f6_00000242_0000033f_000003b1_00000320_0000044e_000000c4_0000039a_0000045a_00000498_00000235_00000490_000001ef
26566 : Load ISS Check  : 80024040        : 0000039a_0000050a_000005cb_000004f6_00000242_0000033f_000003b1_00000320_0000044e_000000c4_0000039a_0000045a_00000498_00000235_00000490_000001ef