FPGA開発日記

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

自作CPUにベクトル命令を追加する実装検討(42. AXPYベンチマークを動かす)

ベンチマーキングのために、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の割り当てを行って、可能な限りキャッシュミスを減らしたい。