AArch64のエミュレート環境を作成したので、SVE命令を含むプログラムを実行してみる。
前記事の方法で、エミュレート環境を作成した。
コンパイラ(GCC)は以下をインストールした。
$ sudo apt install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
SVE命令の実行
SVE(Scalable Vector Extension)は可変長SIMDのための拡張命令である。
以下の論文が詳しいが、ベクトルのためのレジスタ長(ベクトル長)を128bit~2048bitの可変値で対応できる命令である。ベクトル長が異なるCPUでも同じ命令が利用できるという利点がある。
例として挙げられている関数をコンパイルする。
#include <iostream>
#include <arm_sve.h>
void daxpy(double *x, double *y, double a, int n)
{
for(int i = 0; i < n; i++) {
y[i] = a*x[i] + y[i];
}
}
$ aarch64-linux-gnu-g++ -static -march=armv8.3-a+sve -O3 test.cpp
-S
オプションでアセンブリを確認するとSVE拡張命令が使われていることがわかる。
.L4:
ld1d z1.d, p0/z, [x0, x3, lsl 3]
ld1d z2.d, p0/z, [x1, x3, lsl 3]
fmad z1.d, p1/m, z0.d, z2.d
st1d z1.d, p0, [x1, x3, lsl 3]
add x3, x3, x4
whilelo p0.d, w3, w2
b.any .L4
エミュレート環境ではこのコードを動作することもできた。(このエミュレート環境では256bit
のベクトル長となっている)
// x = 3.0, y = 2.0, a = 3.0, n = 10000に設定
// yの要素の値を出力
$ ./a.out
11