FPGA開発日記

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

LLVM18系でRISC-VのAuto-vectorizationがどの程度性能向上したかを確認する

LLVMの18系ではRISC-VのAuto-vectorizationに手を加えられているという話を聞いたので、少しベンチマークを動かして試してみた。

使ったのは最近ハマっているGAP Benchmarkのコンパイルで、LLVM18(まだ開発中)のバージョンは f9da447fa791c078dcae52e48dcd036d7e2e539c を使用している。

github.com

bfs.ccをAuto-vectorization付きでコンパイルし、生成されたアセンブリコードを見てみる。

clang++ --target=riscv64 -S --sysroot=/riscv//riscv64-unknown-elf --gcc-toolchain=/riscv/ -menable-experimental-extensions \
 -O3 -march=rv64gcv -mllvm -scalable-vectorization=on \
 -std=c++11 -O3 -Wall  src/bfs.cc -o - > bfs.riscv.S

LLVM16で生成したコードと比較して、ベクトル命令を中心に何が変わっているのかを観察した。

気になったのは、LMUL>1が生成できるようになっている点だ。ベンチマーク内でvsetvliを観察すると、m2をオペランドに持ったvsetvli命令が生成されている。

vsetvli a2, zero, e64, m1, ta, ma
vsetvli zero, a1, e64, m2, ta, ma
vsetvli s1, zero, e64, m2, ta, ma
vsetvli zero, zero, e32, m1, ta, ma
vsetvli a1, zero, e32, m2, ta, ma

一方LLVM16では、LMUL<=1のみしか生成されていない。

vsetvli a1, zero, e64, m1, ta, ma
vsetvli zero, a3, e64, m1, ta, ma
vsetvli a0, zero, e64, m1, ta, ma
vsetvli zero, zero, e32, mf2, ta, ma
vsetvli a1, zero, e32, m1, ta, ma

なるほど、こういうところで地味に性能を上げるのか。ベクトル命令列についても、全体的なところは変わらないが、LMUL=2向けにデータ移動系命令が変わっている程度だ。