ベンチマーキングのために、RISC-Vのベクトル命令で構成されたAXPYを動作させてみることにする。
#include "vector_defines_m8.h" void axpy_intrinsics(double a, double *dx, double *dy, int n) { int i; long gvl = _MM_VSETVLI(e64, n); //PLCT // _MMR_f64 v_a = _MM_SET_f64(a, gvl); for (i = 0; i < n;) { gvl = _MM_VSETVLI(e64, n - i); //PLCT { _MMR_f64 v_dx = _MM_LOAD_f64(dx, gvl); _MMR_f64 v_dy = _MM_LOAD_f64(dy, gvl); _MMR_f64 v_res = _MM_MACC_f64_f(v_dy, a, v_dx, gvl); _MM_STORE_f64(dy, v_res, gvl); } dx += gvl; dy += gvl; i += gvl; } FENCE(); }
テストの命令列は以下のようになっている。LMUL=8を使うことを想定している。
0000000080002000 <axpy_intrinsics>: 80002000: f20507d3 fmv.d.x fa5,a0 80002004: 02d05863 blez a3,80002034 <axpy_intrinsics+0x34> 80002008: 4701 li a4,0 8000200a: 40e687bb subw a5,a3,a4 8000200e: 05b7f7d7 vsetvli a5,a5,e64,m8,ta,mu 80002012: 0db7f057 vsetvli zero,a5,e64,m8,ta,ma 80002016: 00379513 sll a0,a5,0x3 8000201a: 0205f407 vle64.v v8,(a1) 8000201e: 02067c07 vle64.v v24,(a2) 80002022: 9f3d addw a4,a4,a5 80002024: b287dc57 vfmacc.vf v24,fa5,v8 80002028: 02067c27 vse64.v v24,(a2) 8000202c: 95aa add a1,a1,a0 8000202e: 962a add a2,a2,a0 80002030: fcd74de3 blt a4,a3,8000200a <axpy_intrinsics+0xa> 80002034: 8082 ret
ベンチマーク実行、簡単に動いた! しかし性能的にはイマイチだ。やはり最初に発生したハザード直後に全部パイプラインをフラッシュしてしまうのは、性能上問題がありそうだ。
各イタレーションで、かなりの空きサイクルがある。MSHRの空きも大きい。やはりもうちょっとアグレッシブにMSHRの割り当てを行って、可能な限りキャッシュミスを減らしたい。