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; } }
これをコンパイルして動かしてみる。
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,
無事に実行できることが確認できた。