C 如何使用_m128i执行元素左移?

C 如何使用_m128i执行元素左移?,c,sse,avx,C,Sse,Avx,我发现的SSE移位指令只能在所有元素上移位相同的量: \u mm\u sll\u epi32() \u mm\u slli\u epi32() 有没有办法对不同的元素应用不同的移位?大概是这样的: __m128i a, __m128i b; r0:= a0 << b0; r1:= a1 << b1; r2:= a2 << b2; r3:= a3 << b3; \uuuum128i a、uuuu

我发现的SSE移位指令只能在所有元素上移位相同的量:

  • \u mm\u sll\u epi32()
  • \u mm\u slli\u epi32()

有没有办法对不同的元素应用不同的移位?大概是这样的:

__m128i a,  __m128i b;  

r0:=    a0  <<  b0;
r1:=    a1  <<  b1;
r2:=    a2  <<  b2;
r3:=    a3  <<  b3;
\uuuum128i a、uuuum128i b;

r0:=a0存在的
\u-mm\u-shl\u-epi32()
本质正是这样做的

但是,它需要。只有AMD推土机和Interlagos处理器或更高版本具有此指令。它在任何英特尔处理器上都不可用

如果你想在没有XOP指令的情况下完成它,你需要用一种艰难的方式:把它们拉出来,一个接一个地完成

在没有XOP指令的情况下,您可以使用以下内部函数对SSE4.1执行此操作:

  • \u mm\u insert\u epi32()
  • \u mm\u extract\u epi32()

这将允许您将128位寄存器的一部分提取到常规寄存器中,以进行移位并将其放回原处


如果你使用后一种方法,它的效率会非常低。这就是为什么
\u mm\u shl\u epi32()
首先存在的原因。

没有XOP,您的选择是有限的。如果可以控制移位计数参数的格式,则可以使用
\u mm\u mullo\u pi16
,因为乘以二的幂等于移位该幂


例如,如果您想将SSE寄存器中的8个16位元素移位
,您可以乘以移位计数幂的2,即在某些情况下,通过
,这可以替代
\u mm\u shl\u epi32(a,b)


\u-mm\u-mullo\u-ps(a,1谢谢,我已经用_-mm\u-mullo\u-epi32(SSE4.1)管理了它)。嗯…,有没有更好的方法来使用英特尔cpu?
_mm_mullo_ps(a, 1 << b);