gcc拡張で手軽にベクタ命令
int v __attribute__((vector_size(16)));
とすると、v はサイズが16byteで各要素がint型であるベクタである。
int が 4byte だとすると、結果的に v は4つの要素を持つことになる。
このようにして定義されたベクタは
- + (add)
- - (sub)
- * (mul)
- / (div)
- unary minus
- ^ (xor)
- | (or)
- & (and)
- ~ (not)
の演算が可能。
実際に使うときには union を用いると使いやすそうだ。
#include <stdio.h> typedef union { int v __attribute__((vector_size(16))); int i[4]; } v4si; int main(void) { v4si a = {.i = {0, 1, 2, 3}}, b = {.i = {3, 2, 1, 0}}, c; int i; c.v = a.v + b.v; for (i = 0; i < 4; i++) { printf("%d ", c.i[i]); } putchar('\n'); return 0; }
% ./a.out 3 3 3 3
gcc -S してアセンブリコードを見てみると、movdqa や paddd といった命令が使われているのが分かる。
移植性の観点から言えば
などにある intrinsic functions を使うほうが良いのだけど、どうしても読みにくくなってしまう。*1
移植性を考えなくていい俺々コードを書くときにはこっちの方法も使うことがあるかもしれない。
*1:上記の方法でもベクタ演算の度に .v、ストアやロードのときには .i がつきまとって、それはそれで少し見づらくなるのだけど