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

use*_*122 8 c sse

_mm_shuffle_ps()固有允许一个交织浮子投入低2个浮纱和高2个漂浮的输出.

例如:

R = _mm_shuffle_ps(L1, H1, _MM_SHUFFLE(3,2,3,2))
Run Code Online (Sandbox Code Playgroud)

将导致:

R[0] = L1[2];
R[1] = L1[3];
R[2] = H1[2];
R[3] = H1[3]
Run Code Online (Sandbox Code Playgroud)

我想知道整数数据类型是否有类似的内在可用?有两个__m128i变量和掩码进行交错的东西?

_mm_shuffle_epi32()内在的,只需一个128位向量,而不是两个.

Mys*_*ial 11

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

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

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

这是SSE4.1解决方案,包含3条指令:

__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);
Run Code Online (Sandbox Code Playgroud)

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

__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);
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • @Zboson:对整数数据使用 FP 洗牌没有额外的旁路延迟。(在某些 CPU 上,情况并非如此。在其他 CPU 上,例如 AMD,甚至 FP shuffle 也会发生在 ivec 域中,并对 `addps` / `shufps` / `addps` 施加旁路延迟。)相同的 shuffle 硬件处理FP 和 int 洗牌;这只是接线问题。显然,硬件设计者仍然可以使 FP 洗牌的结果在整数转发网络和 FP 转发网络上可用。 (3认同)