Nanashi-softプログラマ専用Windows gcc SDL


◇Windowsでgcc+SDL -SSE2(SIMD)で計算する-

○ベクター変数

__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を想定したロジックにしておかなければなりません


TOPプログラマ専用Windows gcc SDL