Vector splat in AVX.

by syoyo

Splatting value from vector element to make new vector, for example v.xxxx, is frequently used in graphics application, but unfortunately there’s no direct instruction to do this in AVX’s _mm256 type(double x 4).

This is because perm or shuffle instruction cannot move data over 128bit boundary.

Thus, I figured out how to do a vector splatting with combination of some AVX instructions.

My answer is first make a 128bit splat value with shuffle_pd then copy it to upper and lower 128bit part of 256bit value with permute2f128.

(project files)

With AVX simulator, I’ve confirmed correct result.


v = 1.000000, 2.000000, 3.000000, 4.000000
v.xxxx = 1.000000, 1.000000, 1.000000, 1.000000
v.yyyy = 2.000000, 2.000000, 2.000000, 2.000000
v.zzzz = 3.000000, 3.000000, 3.000000, 3.000000
v.wwww = 4.000000, 4.000000, 4.000000, 4.000000

[Ja]

AVX ですが、_m256d 型(double x 4)って結構 128bit の制約があって、自由に 256bit 以内でデータを移動させるということができません.

たとえば、よくグラフィックスでは v.xxxx と、ひとつのベクトル要素値をすべてのベクトル要素のスロットにコピーしたベクトルが必要になることが多いのですが、これが _m256 だとできない.

HW 設計上, しかたがなかったのかもしれませんが、これから AVX はさらに 512 bit, 1024 bit とか拡張していくと Intel は言っていますが、この問題はどうするんでしょうね? まあこのようなめんどくさい問題を解決するために MUDA は生まれたわけですが.

というわけで、ベクトルの splat くらいできないといろいろ困るので、AVX で splat を実現する命令の組み合わせを考えてみました(この組み合わせを、MUDA で利用する).

shuffle と permute2f128 の 2 命令を使って vector splat を実現できます.

今回は printf で結果を見せるようにしていますが、シミュレータにレジスタ値をダンプさせたり、gdb と組み合わせてデバッグするなどして、より効率的に検証を行うこともできます(gdb との組み合わせだと、動作がすごくおそいけど).

いやーしかし、やっぱりシミュレータは便利ですね(機能シミュレータというのがちょっと残念だけど).

Advertisements