_mm_cvtepi16_epi32 (pmovsxwd)需要SSE4.1
SSSE3的答案可能也很有趣。
发布于 2016-02-25 22:35:07
用解包方法复制每个16位元素(从下半部分开始),然后使用算术右移位在每个32b元素的上半部分留下一个符号位的副本。
__m128i v16 = ...;
v32 = _mm_unpacklo_epi16(v16, v16); // [ a a b b c c d d ]
v32 = _mm_srai_epi32(v32, 16);这只是SSE2。这是两条快速指令,所以我不认为从SSE3或SSSE3中能得到任何东西,也想不出任何东西。唯一比这更好的是一种非破坏性的方式(这样如果我们仍然需要的话,编译器就不必复制v16 )。
如果您已经可以在一条指令中做到这一点,那么可能还没有引入pmovsxwd。(尽管为了与其他pmovsx表单保持一致,它可能无论如何都要这样做。pmovsx真正闪亮的地方是从字节到双字,或者从字节到qword。此外,它的加载形式也很好,尽管内部机制使得它很难用作加载。)
对于其他元素大小,有一个psraw,所以8->16也是有效的,但没有psraq (只有64位元素的逻辑左/右移位)。pmovsxdq更难模仿。pblendw也是SSE4.1。我在想也许可以用零来解包,然后算术右移。然后,您可以通过另一种方式与未打包为零的向量进行OR运算。
这样做的好处是可以使用_mm_unpackhi获取上半部分,而不幸的是pmovsz/pmovzx不能这样做。
https://stackoverflow.com/questions/35629857
复制相似问题