Nanashi-soft○プログラマ専用○Windows gcc SDL○
__m128i a;
と宣言すると、整数型の 16バイトがメモリ上に確保されます
中身の型は特に指定する必要は無く、演算を行うマクロ関数によって決まります
このベクタ変数に値を代入するにはマクロ関数を使用します
int a, b, c, d; a= 1; b= 2; c= 3; d= 4; __m128i va; va= _mm_set_epi32(a, b, c, d);
こんな感じです
__m128iを元の変数に戻す時もマクロ関数を使用します
最下位の値を取り出す事しかできないので、右に4バイトずつシフトしながら取り出します
d= _mm_cvtsi128_si32(va); vc= _mm_srli_si128(vc, 4); c = _mm_cvtsi128_si32(vc); vc= _mm_srli_si128(vc, 4); b = _mm_cvtsi128_si32(vc); vc= _mm_srli_si128(vc, 4); a = _mm_cvtsi128_si32(vc);
但し、変数の中身は壊れてしまいます
足し算を行ってみます
int a, b, c; a = 1; b = 2; c = a + b;
この cの足し算部分 c=s+bだけを SIMDで書くと、
int a, b, c; a = 1; b = 2; __m128i va, vb, vc; //演算用のベクタ変数宣言 va= _mm_set_epi32(0, 0, 0, a); //ベクタ変数にaをセット vb= _mm_set_epi32(0, 0, 0, b); //ベクタ変数にbをセット vc = _mm_add_epi32(va, vb); //a+bの足し算 c = _mm_cvtsi128_si32(vc); //結果をcに代入 printf("c=%d\n", c);
のようになります
ベクター変数は、ベクター変数同士でしか演算が行えませんので、計算に必要な値を全てベクター変数に代入しておく必要があります
このように、SIMDは演算を行う前準備を行うコストが必要になります
ですから、設計段階から SIMDを想定したロジックにしておかなければなりません