簡體   English   中英

比較總訂單的兩個__m128i值

[英]Compare two __m128i values for total order

我需要一種方法來比較類型的值__m128i在C ++類型的任何值之間的總順序__m128i 只要在__m128i類型的所有值之間建立總順序,訂單類型就__m128i 因此,只要提供總訂單,比較可能小於128位整數或其他整數。

我嘗試使用<運算符,但是沒有返回bool ,而是似乎比較了__m128i (即SIMD)的向量組件:

#include <emmintrin.h>

inline bool isLessThan(__m128i a, __m128i b) noexcept {
     // error: cannot convert '__vector(2) long int' to 'bool' in return
     return a < b;
}

另一種可能性是使用memcmp / strcmp或類似的,但這很可能不是最佳的。 針對至少具有SSE4.2和AVX2的現代Intel x86-64 CPU,我可以使用任何內在/指令進行此類比較嗎? 怎么做?

PS:已經要求類似的問題檢查相等性,但不是為了訂購:

干得好。

inline bool isLessThan( __m128i a, __m128i b )
{
    /* Compare 8-bit lanes for ( a < b ), store the bits in the low 16 bits of the
       scalar value: */
    const int less = _mm_movemask_epi8( _mm_cmplt_epi8( a, b ) );

    /* Compare 8-bit lanes for ( a > b ), store the bits in the low 16 bits of the
       scalar value: */
    const int greater = _mm_movemask_epi8( _mm_cmpgt_epi8( a, b ) );

    /* It's counter-intuitive, but this scalar comparison does the right thing.
       Essentially, integer comparison searches for the most significant bit that
       differs... */
    return less > greater;
}

順序不太理想'coz pcmpgtb將這些字節視為有符號整數,但是你說它對你的用例並不重要。


更新:這是一個稍微慢一點的uint128_t排序順序版本。

// True if a < b, for unsigned 128 bit integers
inline bool cmplt_u128( __m128i a, __m128i b )
{
    // Flip the sign bits in both arguments.
    // Transforms 0 into -128 = minimum for signed bytes,
    // 0xFF into +127 = maximum for signed bytes
    const __m128i signBits = _mm_set1_epi8( (char)0x80 );
    a = _mm_xor_si128( a, signBits );
    b = _mm_xor_si128( b, signBits );

    // Now the signed byte comparisons will give the correct order
    const int less = _mm_movemask_epi8( _mm_cmplt_epi8( a, b ) );
    const int greater = _mm_movemask_epi8( _mm_cmpgt_epi8( a, b ) );
    return less > greater;
}

我們構建無符號比較,通過將無符號輸入的范圍轉換為有符號(通過翻轉高位=減去128)進行范圍轉換。

暫無
暫無

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

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