ベクトルレジスタでの位置合わせ (_mm_alignr_epi8、_mm512_alignr_epi32)

2014年9月6日土曜日

SIMD

t f B! P L
こないだいってたフィルター処理のベクトル化の話の続き。

こないだはこういう形で書くとロード回数が減っていいじゃんという話。
ただ、ロード回数を減らすには、256ビット長の2つのレジスタを
くっつけて、自由にシフトできないといけませんでした。

なので今回は、ベクトルレジスタ同士を結合してシフトの方法など。
まずは、簡単なSSEとMICとAVX512から。

SSEの場合は128ビット長のベクトルレジスタ2つに入ったデータを、
MICやAVX512の場合は512ビット長のベクトルレジスタ2つに入ったデータを、
合わせてシフトします。

SSEの場合は、
__m128i s00 = _mm_loadu_si128(&schar[x]);
__m128i s16 = _mm_loadu_si128(&schar[x+16]);
__m128i s01 = _mm_alignr_epi8(s16, s00, 1);
__m128i s02 = _mm_alignr_epi8(s16, s00, 2);
__m128i s03 = ...
という具合。MICやAVX512の場合は、
__m512i s00, s16;
s00 = _mm512_loadunpacklo_epi32(s00, &sint[x]);
s00 = _mm512_loadunpackhi_epi32(s00, &sint[x+16]);
s16 = _mm512_loadunpacklo_epi32(s16, &sint[x+16]);
s16 = _mm512_loadunpackhi_epi32(s16, &sint[x+32]);
__m512i s01 = _mm512_alignr_epi32(s16, s00, 1);
__m512i s02 = _mm512_alignr_epi32(s16, s00, 2);
__m512i s03 = ...
という具合。

簡単ですね!超カンタン!全部がこうならいいのに。

浮動小数点型をシフトしたい場合は、タイプキャストを行います。例えば、
__m512 s01 = _mm512_castsi512_ps(_mm512_alignr_epi32(
    _mm512_castps_si512(s16), _mm512_castps_si512(s00), 1));
となります。

MICやAVX512では、32ビット単位の操作以外はできないので、
もっと細かい処理をするにはなんか別の方法が必要です。
自分は細かい処理しなかったので調べてません。

ラベル

AndroidTV (1) chromebook (2) DIY (4) docker (1) git (4) Ingress (4) llvm (3) MacBook (1) MVNO (1) narou (1) PS4 (2) QNAPNAS (9) SIMD (9) SmartBand (8) Ubuntu (9) VAIO (1) Windows (2) wsl (2) wsl2 (1) Xperia (20) トルネ (3) プログラム (26) ルーター (18) 音楽 (6) 家事 (2) 自炊 (2) 電子書籍 (2) 洋食 (4)

フォロワー

QooQ