SSEやAVX2で符号拡張をする時に、アンパックのゼロと対象の変数の順番を忘れるので覚書として。
8->16以外も基本的にやり方は同じなのであとはご自分でどうぞ。
u8x16_to_u16x8x2.cpp
#include <stdio.h>
#include <emmintrin.h>
void main()
{
__declspec(align(16)) unsigned char u8[16];
__declspec(align(16)) unsigned short u16[16];
// テストデータとして1~16を入れる。
for(int i = 0; i < 16 ; ++i) {
u8[i] = i + 1;
}
// ゼロの入ったレジスタの用意
__m128i zero = _mm_setzero_si128();
// SSEレジスタに転送
__m128i src1 = _mm_load_si128((const __m128i*)u8);
// 1,0,2,0,3,0,4,0,5,0,6,0,7,0
__m128i lower = _mm_unpacklo_epi8(src1, zero);
// 8,0,9,0,10,0,11,0,12,0,13,0,14,0,15,0
__m128i higher = _mm_unpackhi_epi8(src1, zero);
// u16にコピー
_mm_store_si128((__m128i*)u16, lower);
_mm_store_si128((__m128i*)(u16+8), higher);
// 結果の確認
for(int i = 0; i < 16 ; ++i) {
printf("%d, %d, %d, %s\n", i, u8[i], u16[i], (u8[i] == u16[i]) ? "同じ" : "違う");
}
}
参考
こちらをかなり参考にさせて頂いています。--> http://www.officedaytime.com/tips/simd.html