如何使用 SIMD 比较两个向量并获得类似 strncmp 的结果?

How to compare two vectors using SIMD and get a strncmp like result?

我想实现类似 strncmp 结果但没那么复杂 我试图阅读 https://code.woboq.org/userspace/glibc/sysdeps/x86_64/multiarch/strcmp-avx2.S.html 源代码,但未能理解它

假设我们需要 256 位向量 我如何根据 8 位比较来比较这两个以获得像 strncmp

这样的结果

我知道有一个图书馆,但我想了解基础知识。

如何 return -1,0,1 结果与 _mm256_cmpeq_epi8_mm256_min_epu8

我会那样做。

inline int compareBytes( __m256i a, __m256i b )
{
    // Compare for both a <= b and a >= b
    __m256i min = _mm256_min_epu8( a, b );
    __m256i le = _mm256_cmpeq_epi8( a, min );
    __m256i ge = _mm256_cmpeq_epi8( b, min );

    // Reverse bytes within 16-byte lanes
    const __m128i rev16 = _mm_set_epi8( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 );
    const __m256i rev32 = _mm256_broadcastsi128_si256( rev16 );
    le = _mm256_shuffle_epi8( le, rev32 );
    ge = _mm256_shuffle_epi8( ge, rev32 );

    // Move the masks to scalar registers
    uint32_t lessMask = (uint32_t)_mm256_movemask_epi8( le );
    uint32_t greaterMask = (uint32_t)_mm256_movemask_epi8( ge );

    // Flip high/low 16-bit pieces in the masks.
    // Apparently, modern compilers are smart enough to emit ROR instructions for that code
    lessMask = ( lessMask >> 16 ) | ( lessMask << 16 );
    greaterMask = ( greaterMask >> 16 ) | ( greaterMask << 16 );

    // Produce the desired result
    if( lessMask > greaterMask )
        return -1;
    else if( lessMask < greaterMask )
        return +1;
    else
        return 0;
}

该方法之所以有效,整数比较本质上是寻找不同的最高有效位,比较结果等于最高有效不同位的差异。因为我们颠倒了被测试字节的顺序,向量中的第一个字节对应于掩码中的最高有效位。因此,当源向量中的第一个不同字节 ( a < b ) 评估为真时,( lessMask > greaterMask ) 表达式评估为真。