2014年9月6日土曜日

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

こないだいってたフィルター処理のベクトル化の話の続き。

こないだはこういう形で書くとロード回数が減っていいじゃんという話。
ただ、ロード回数を減らすには、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ビット単位の操作以外はできないので、
もっと細かい処理をするにはなんか別の方法が必要です。
自分は細かい処理しなかったので調べてません。

0 件のコメント:

コメントを投稿