FPGA開発日記

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

RISC-Vのベクトル拡張命令RVVの環境を試す (2. ベクトル命令を使ったサンプルプログラムの作成)

https://cdn-ak.f.st-hatena.com/images/fotolife/m/msyksphinz/20190615/20190615201045.png

RISC-Vのベクトル拡張命令であるRISC-V Vector Extensionは仕様の策定されており、徐々に実装が進んでいる。

  • riscv-toolsのSpike命令セットシミュレータ
  • riscv-gnu-toolchainの対応

前回ツールセットのインストールが完了したので、今回はサンプルプログラムを作ってみることにした。

今回は、ベクトル命令を用いて2つの配列要素をそれぞれ乗算するプログラムだ。ベクトル命令を使って実装する。

vlw.v命令を使ってロードし、vfmul.vvを使ってベクトル乗算を行う。 VLENの長さはSpikeの設定で512に設定し、各ベクトルの最低演算要素ELENを32に設定することで、同時に16個の演算を行うことができるようにする。

spike --isa=rv64gcv --varch=v512:e32:s32 pk rvv_example # ログを出力しない。
spike -l --isa=rv64gcv --varch=v512:e32:s32 pk rvv_example > run.log 2>&1 # ログを出力する
int v_test(int size, float *f0, float *f1, float *f2)
{
  float *v0_p, *v1_p, *v2_p;
  int vl_length = 32;

  for (int i = 0; i < size; i+=vl_length) {
    asm volatile ("vsetvli %0, %1, e32":"=r"(vl_length):"r"(size - i));

    asm volatile ("vlw.v  v0,(%0)"::"r"(f0));   // 32b signed
    asm volatile ("vlw.v  v1,(%0)"::"r"(f1));   // 32b signed

    asm volatile ("vfmul.vv v2, v1, v0");
    asm volatile ("vsw.v  v2,(%0)"::"r"(f2));   // 32b signed

    f0 += vl_length;
    f1 += vl_length;
    f2 += vl_length;
  }

}

github.com

これをコンパイルして動かしてみる。

riscv64-unknown-elf-gcc -O3 -march=rv64gcv rvv.c -o rvv
riscv64-unknown-elf-objdump -d rvv > rvv.elf.dmp
  • Spikeシミュレータで実行
spike --isa=rv64gcv --varch=v512:e32:s32 pk rvv
calling v_test
0.000000, 127.000000, 252.000000, 375.000000, 496.000000, 615.000000, 732.000000, 847.000000, 960.000000, 1071.000000,
1180.000000, 1287.000000, 1392.000000, 1495.000000, 1596.000000, 1695.000000, 1792.000000, 1887.000000, 1980.000000, 2071.000000,
2160.000000, 2247.000000, 2332.000000, 2415.000000, 2496.000000, 2575.000000, 2652.000000, 2727.000000, 2800.000000, 2871.000000,
2940.000000, 3007.000000, 3072.000000, 3135.000000, 3196.000000, 3255.000000, 3312.000000, 3367.000000, 3420.000000, 3471.000000,
3520.000000, 3567.000000, 3612.000000, 3655.000000, 3696.000000, 3735.000000, 3772.000000, 3807.000000, 3840.000000, 3871.000000,
3900.000000, 3927.000000, 3952.000000, 3975.000000, 3996.000000, 4015.000000, 4032.000000, 4047.000000, 4060.000000, 4071.000000,
4080.000000, 4087.000000, 4092.000000, 4095.000000, 4096.000000, 4095.000000, 4092.000000, 4087.000000, 4080.000000, 4071.000000,
4060.000000, 4047.000000, 4032.000000, 4015.000000, 3996.000000, 3975.000000, 3952.000000, 3927.000000, 3900.000000, 3871.000000,
3840.000000, 3807.000000, 3772.000000, 3735.000000, 3696.000000, 3655.000000, 3612.000000, 3567.000000, 3520.000000, 3471.000000,
3420.000000, 3367.000000, 3312.000000, 3255.000000, 3196.000000, 3135.000000, 3072.000000, 3007.000000, 2940.000000, 2871.000000,
2800.000000, 2727.000000, 2652.000000, 2575.000000, 2496.000000, 2415.000000, 2332.000000, 2247.000000, 2160.000000, 2071.000000,
1980.000000, 1887.000000, 1792.000000, 1695.000000, 1596.000000, 1495.000000, 1392.000000, 1287.000000, 1180.000000, 1071.000000,

無事に実行できることが確認できた。