是否有与_mm_insert_epi32等价的SSE2?
问题描述:
我正在移植一些代码,这会大量使用SSE4内在函数。它有一个非SSE实现,但是我希望只有SSE2的CPU仍然能够使用更快的功能。是否有与_mm_insert_epi32等价的SSE2?
可能有人建议为_mm_insert_epi32
的有效替代 - 我想,我得到了一切覆盖已经......其实,第二和函数的第三个参数是在我的情况下,零:
foo = _mm_insert_epi32(vec, 0, 0);
答
所以你实际上想要零矢量的低元素?对于_mm_insert_epi32
来说这是一个糟糕的用例。这是英特尔CPU上的2个微软,其中一个需要shuffle端口。
在您的SSE4.1和SSE2两种版本,使用
foo = _mm_and_si128(vec, _mm_set_epi32(-1,-1,-1, 0)); // mask off the low element
另外,使用movss
从归零向量,但是这可能会导致旁路延迟使用两个整数指令之间的FP洗牌。在C intrinsics版本中有一个令人讨厌的强制转换,所以它更容易被读作asm。
# vec in xmm0
pxor xmm1, xmm1 ; _mm_setzero_si128()
movss xmm0, xmm1 ; zero the low 32 bits of xmm0
2X _mm_insert_epi16
几乎肯定不是这样做的最佳方式,即使你想更换比可变内容的低元素之外的元素。这是一个2-uop指令,但对于很多情况,你可以用少于4个uops完成工作。
对于变量内容,最好使用_mm_cvtsi32_si128
(movd
)并将两个向量混洗在一起。解压缩指令适用于组合来自两个寄存器的数据,因此shufps
(是的,您可以在整数数据上使用它)。
你也可以洗牌vec
所以要替换的元素是低元素,然后用movss
(或与/或)替换它。
也许2x 2x pinsrw
对于一般情况并不可怕,但是大多数情况下应该让你想出更好的东西。请参阅http://agner.org/optimize/和x86标记wiki以获取更多资源,以帮助您编写高效的代码。