我正在移植一些代碼,這會大量使用SSE4內在函數。它有一個非SSE實現,但是我希望只有SSE2的CPU仍然能夠使用更快的功能。是否有與_mm_insert_epi32等價的SSE2?
可能有人建議爲_mm_insert_epi32
的有效替代 - 我想,我得到了一切覆蓋已經......其實,第二和函數的第三個參數是在我的情況下,零:
foo = _mm_insert_epi32(vec, 0, 0);
我正在移植一些代碼,這會大量使用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以獲取更多資源,以幫助您編寫高效的代碼。