_mm_cvtepi16_epi32
(pmovsxwd
)需要SSE4.1
我们如何仅用SSE3或SSE2签署扩展向量元素?
SSSE3答案可能也很有趣。
答案 0 :(得分:3)
使用解压缩复制每个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
很遗憾不会这样做。