【发布时间】:2013-05-11 04:11:00
【问题描述】:
是否有任何 SSE2 指令以相反的顺序从 int 缓冲区加载 128 位 int 向量寄存器?
【问题讨论】:
是否有任何 SSE2 指令以相反的顺序从 int 缓冲区加载 128 位 int 向量寄存器?
【问题讨论】:
编辑:(以下是单精度浮点标量,以防万一)
最近似(且方便)的是_mm_loadr_ps 内在函数。请注意,地址必须是 16 字节对齐的。
虽然这种内在转化为不仅仅是指令(MOVAPS + shuffle)。
【讨论】:
在正常加载后很容易反转 32 位 int 元素:
__m128i v = _mm_load_si128(buff); // MOVDQA
v = _mm_shuffle_epi32(v, _MM_SHUFFLE(0, 1, 2, 3)); // PSHUFD - mask = 00 01 10 11 = 0x1b
您可以对 16 位 short 元素执行相同的操作,但需要更多指令:
__m128i v = _mm_load_si128(buff); // MOVDQA
v = _mm_shuffle_epi32(v, _MM_SHUFFLE(0, 1, 2, 3)); // PSHUFD - mask = 00 01 10 11 = 0x1b
v = _mm_shufflelo_epi16(v, _MM_SHUFFLE(2, 3, 0, 1)); // PSHUFLW - mask = 10 11 00 01 = 0xb1
v = _mm_shufflehi_epi16(v, _MM_SHUFFLE(2, 3, 0, 1)); // PSHUFHW - mask = 10 11 00 01 = 0xb1
请注意,如果 SSSE3 可用,您可以使用更少的指令使用 _mm_shuffle_epi8 (PSHUFB) 执行此操作:
const __m128i vm = _mm_setr_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
// initialise vector mask for use with PSHUFB
// NB: do this once, outside any processing loop
...
__m128i v = _mm_load_si128(buff); // MOVDQA
v = _mm_shuffle_epi8(v, vm); // PSHUFB
【讨论】:
PSHUFB 示例,用于反转向量中 16 位整数的顺序。