2016-07-14 100 views
0

我正在移植一些代碼,這會大量使用SSE4內在函數。它有一個非SSE實現,但是我希望只有SSE2的CPU仍然能夠使用更快的功能。是否有與_mm_insert_epi32等價的SSE2?

可能有人建議爲_mm_insert_epi32的有效替代 - 我想,我得到了一切覆蓋已經......其實,第二和函數的第三個參數是在我的情況下,零:

foo = _mm_insert_epi32(vec, 0, 0); 

回答

2

所以你實際上想要零矢量的低元素?對於_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以獲取更多資源,以幫助您編寫高效的代碼。

相關問題