是否有与_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/标记wiki以获取更多资源,以帮助您编写高效的代码。