もちろん、NEONはSIMD命令でRVVはVector命令群なので目的も細かな仕様も異なるわけだけれども、命令の挙動として似ているものを対比してみる。
- Coding for Neon
- Unit-Stride Load 命令
RVV命令の場合はVLE
.V 命令などがある。 VLE8.V / VLE16.V / VLE32.V / VLE64.V
など。 NEONにおいては、LD1命令がそれに該当する。
複数のベクトルレジスタに書く場合は、RVVの場合はLMUL>2に設定することで可能になる(ただしレジスタの指定できるアドレスは半分になる)。
VSETVLI m2 VLE32.V v8, (x10) # v8とv9に32ビット単位でのデータをロードする VSETVLI m4 VLE16.V v4, (x10) # v4-v7に16ビット単位でのデータをロードする
NEONでは、LD1命令のオペランドを複数指定することで複数のレジスタにデータをロードすることができるようになる。
LD1 { V0.16B, V1.16B }, [x0] # v0とv1に16ビット単位でのデータロードを行う
あまり関係ないが、連続的なデータをロードするので、32ビット単位とか16ビット単位などの条件はあまり命令の挙動に関係がないのだが、アドレスミスアラインの条件として使用する程度である。
- Segment命令 RVVにはSegment Load/Store命令というものが定義されている。
VLSEG3E32.V v8, (x10) # v8, v9, v10に対して縦方向に値をロードする
NEONの場合は以下の記述で同様なことが可能になる。
LD3 { V0.16B, V1.16B, V2.16B }, [x0]
これはST3でも同様のことが可能だ。同様にLD2/LD3/LD4が定義されており、これは VLSEG2E<EEW>.V / VLSEG3E<EEW>.V / VLSEG4E<EEW>.V
で定義されている。
インターリーブ無しで1つのベクトルレジスタに値を格納する命令 | LD1 Vx, [Rx] |
VSET LMUL=1; VLE.V Vx, (Rx) |
---|---|---|
インターリーブ無しで2つのベクトルレジスタに値を格納する命令 | LD1 {Vx, Vy} [Rx] |
VSET LMUL=2; VLE.V Vx, (Rx) |
インターリーブ無しで3つのベクトルレジスタに値を格納する命令 | LD1 {Vx, Vy, Vz} [Rx] |
|
インターリーブ無しで4つのベクトルレジスタに値を格納する命令 | LD1 {Vx, Vy, Vz, Vw} [Rx] |
VSET LMUL=4; VLE.V Vx, (Rx) |
インターリーブ無しで8つのベクトルレジスタに値を格納する命令 | VSET LMUL=8; VLE.V Vx, (Rx) |
|
2要素をインタリーブしながら2つのベクトルレジスタに値を格納する命令 | LD2 {Vx, Vy} [Rx] |
VLSEG2E.V Vx, (Rx) |
3要素をインタリーブしながら3つのベクトルレジスタに値を格納する命令 | LD3 {Vx, Vy, Vz} [Rx] |
VLSEG3E.V Vx, (Rx) |
4要素をインタリーブしながら4つのベクトルレジスタに値を格納する命令 | LD4 {Vx, Vy, Vz, Vw} [Rx] |
VLSEG4E.V Vx, (Rx) |
5要素をインタリーブしながら5つのベクトルレジスタに値を格納する命令 | VLSEG5E.V Vx, (Rx) |
|
6要素をインタリーブしながら6つのベクトルレジスタに値を格納する命令 | VLSEG6E.V Vx, (Rx) |
|
7要素をインタリーブしながら7つのベクトルレジスタに値を格納する命令 | VLSEG7E.V Vx, (Rx) |