_mm_shuffle_ps()等效于整数向量(__m128i)?

时间:2012-10-31 08:05:43

标签: c sse

_mm_shuffle_ps()内在函数允许将浮点输入交错为输出的低2浮点数和高2浮点数。

例如:

R = _mm_shuffle_ps(L1, H1, _MM_SHUFFLE(3,2,3,2))

将导致:

R[0] = L1[2];
R[1] = L1[3];
R[2] = H1[2];
R[3] = H1[3]

我想知道整数数据类型是否存在类似的内在函数?有两个__m128i变量和一个掩码用于交错?

_mm_shuffle_epi32()内在函数只需要一个128位向量而不是两个向量。

1 个答案:

答案 0 :(得分:11)

不,没有相当于此的整数。所以你必须要么模仿它,要么作弊。

一种方法是在_mm_shuffle_epi32()A上使用B。然后掩盖所需的术语并将它们重新组合在一起。

这往往是凌乱的,有大约5条指令。 (如果您使用SSE4.1混合说明,则为3。)

以下是带有3条指令的SSE4.1解决方案:

__m128i A = _mm_set_epi32(13,12,11,10);
__m128i B = _mm_set_epi32(23,22,21,20);

A = _mm_shuffle_epi32(A,2*1 + 3*4 + 2*16 + 3*64);
B = _mm_shuffle_epi32(B,2*1 + 3*4 + 2*16 + 3*64);

__m128i C = _mm_blend_epi16(A,B,0xf0);

我更喜欢的方法是实际作弊 - 以及像这样的浮点随机播放:

__m128i Ai,Bi,Ci;
__m128  Af,Bf,Cf;

Af = _mm_castsi128_ps(Ai);
Bf = _mm_castsi128_ps(Bi);
Cf = _mm_shuffle_ps(Af,Bf,_MM_SHUFFLE(3,2,3,2));
Ci = _mm_castps_si128(Cf);

这样做是为了将数据类型转换为浮点数,以便它可以使用float-shuffle。然后将其转换回来。

请注意,这些“转化”是按位转换(也称为重新解释)。实际上没有进行转换,也没有映射到任何指令。在汇编中,整数或浮点SSE寄存器之间没有区别。这些演员内在函数只是为了解决C / C ++强加的类型安全问题。

但是,请注意,此方法会导致在整数和浮点SIMD执行单元之间来回移动数据的额外延迟。所以它会比洗牌指令更昂贵。