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

2014年9月6日土曜日

SIMD

t f B! P L
引き続き、ベクトルレジスタ同士を結合してシフトの方法など。最後のAVX2編。

AVXでは合わせてシフト命令がなかったので、shuffle命令を使いました。
AVX2でもshuffle命令で操作可能です。

でも、AVX2にはシフト命令が追加されていますのでこれも使えます。
シフト命令は、1バイト単位でシフトできるので、使い方をしっておくと便利そうです。
なので、今回はこれを使います。_mm256_alignr_epi8命令です。

この命令はリンク先の説明の通り、なんか複雑なシフトをします。
何を計算しているかというと、もともと128ビットでやってたシフト処理を、
下位128ビット同士と上位128ビット同士で同時に計算しています。

おお、これは便利と、単純に使ってみると、
__m256 t = _mm256_alignr_epi8(s08, s00, 4);
tには、s01s02s03s08s05s06s07s12みたいなデータが入って(´・ω・`)ガッカリ…

そこで、事前準備をします。
__m256 s04 = _mm256_permute2f128_ps(s08, s00, 3);
__m256 t = _mm256_alignr_epi8(s04, s00, 4);
こうすると、tにはs01s02s03s04s05s06s07s08が入ってばっちりです。

実際に使うには、キャストが必要で、こんな感じですね。
__m256 s04 = _mm256_permute2f128_ps(s08, s00, 3);
__m256 t = _mm256_castsi256_ps(_mm256_alignr_epi8(
        _mm256_castps_si256(s04), _mm256_castps_si256(s00), 4);
また、シフト幅を増やすときは、桁溢れに気をつけてください。
s00 = s00;
s01 = _mm256_alignr_epi8(s04, s00, 4);
s02 = _mm256_alignr_epi8(s04, s00, 8);
s03 = _mm256_alignr_epi8(s04, s00, 12);
s04 = s04;
s05 = _mm256_alignr_epi8(s08, s04, 4);
s06 = ...

みたいな感じになります。

これでシフト処理のintrinsic忘備録お仕舞です。

ラベル

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