簡體   English   中英

比較並交換SIMD內部函數

[英]Compare and swap with SIMD intrinsics

如果發生某種情況,是否可以在SIMD指令中進行比較並交換值。 換句話說,我有4個整數:

(100 5) (1 42)

我想收到:

(5 100) (1 42)

即我想成對比較(第一個值與第二個,第三個與第四個),並在左操作數較大的情況下-交換值。 只能使用1張SIMD嗎?

PS:這是我第一次嘗試SIMD,可能是我使用了錯誤的術語-如果我輸入錯了,請修復我。

對於支持AVX2的系統,有一個使用最小/最大並與imm混合的解決方案(其延遲為1個周期,而變量1為2個周期)。

以下代碼具有3個周期的延遲,並且在HSW +上的吞吐量應小於2個周期

__m128i tmp = _mm_shuffle_epi32(in, _MM_SHUFFLE(2,3,0,1));
__m128i min = _mm_min_epi32(in, tmp);
__m128i max = _mm_max_epi32(in, tmp);
// __m128i res = _mm_blend_epi32(min, max, 0xA); // AVX2 only
__m128i res = _mm_blend_epi16(min, max, 0xCC);   // SSE4.1

我已經在我的HSW系統上對其進行了測試(處理了20000對,進行了10萬次),它的性能比stgatilov的代碼高約26%。

CMP + VARIABLE BLEND    1.18sec
MIN/MAX + BLEND_32      0.87sec // AVX2 only code
MIN/MAX + BLEND_PS      0.86sec // SSE
MIN/MAX + PLEND_16      0.88sec // Preferred for SSE

更新 :Per stgatilov在下面的評論。 所有的MIN / MAX實現幾乎都具有相同的性能(很可能只是卡在了內存中,黑白)

似乎您想在單個XMM寄存器中對32位整數對進行排序。 當然,尚無現成的說明,但是您可以使用SSE4.1編寫一些說明( 請注意:未經測試的代碼):

//input = [100, 5, 1, 42]
__m128i swapped = _mm_shuffle_epi32(input, _MM_SHUFFLE(2,3,0,1)); // [5, 100, 42, 1]
__m128i comp = _mm_cmplt_epi32(input, swapped);                   // [0, -1, -1, 0]
comp = _mm_xor_si128(comp, _mm_set_epi32(-1, 0, -1, 0));          // [0, 0, -1, -1]
input = _mm_blendv_epi8(swapped, input, comp);                    // [5, 100, 1, 42]

在Ivy Bridge上,似乎是7微秒,需要2個CPU周期(吞吐量)。

如果需要,可以輕松將其移植到AVX2。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM