<story><title>Filtering a vector with SIMD instructions (AVX-2 and AVX-512)</title><url>https://quickwit.io/blog/filtering%20a%20vector%20with%20simd%20instructions%20avx-2%20and%20avx-512</url></story><parent_chain></parent_chain><comment><author>Const-me</author><text>Whenever you need a lookup table with vectors, remember the instructions like _mm256_cvtepu8_epi32 or _mm256_cvtepi8_epi64 can zero extend or sign extend integer lanes, and they can load source directly from memory. The OP needs a vector with int32 lanes in [0..7] range, can use 1 byte per lane and expand to uint32_t while loading with _mm256_cvtepu8_epi32. Reduces table size by a factor of 4, at the cost of a single instruction.&lt;p&gt;Another thing, it’s possible to produce the desired vectors without RAM loads, with a couple of BMI2 instructions. Example in C++:&lt;p&gt;&lt;pre&gt;&lt;code&gt;    &amp;#x2F;&amp;#x2F; Compress int32 lanes according to the mask
    &amp;#x2F;&amp;#x2F; The mask is expected to contain either 0 or UINT_MAX values
    __m256i compress_epi32( __m256i val, __m256i mask )
    {
        uint32_t i32 = (uint32_t)_mm256_movemask_epi8( mask );
        &amp;#x2F;&amp;#x2F; Compress, using 4 bit numbers for lane indices
        constexpr uint32_t identity = 0x76543210;
        i32 = _pext_u32( identity, i32 );
        &amp;#x2F;&amp;#x2F; Expand 4-bit numbers into bytes
        constexpr uint64_t expand = 0x0F0F0F0F0F0F0F0Full;
        uint64_t i64 = _pdep_u64( (uint64_t)i32, expand );
        &amp;#x2F;&amp;#x2F; Move to SSE vector
        __m128i vec = _mm_cvtsi64_si128( (int64_t)i64 );
        &amp;#x2F;&amp;#x2F; Expand bytes to uint32_t
        __m256i perm = _mm256_cvtepu8_epi32( vec );
        &amp;#x2F;&amp;#x2F; Shuffle these elements
        return _mm256_permutevar8x32_epi32( val, perm );
    }
&lt;/code&gt;&lt;/pre&gt;
One downside, these BMI2 instructions are rather slow on Zen 2 and earlier AMD processors. AMD has fixed the performance in Zen 3.</text></comment>
<story><title>Filtering a vector with SIMD instructions (AVX-2 and AVX-512)</title><url>https://quickwit.io/blog/filtering%20a%20vector%20with%20simd%20instructions%20avx-2%20and%20avx-512</url></story><parent_chain></parent_chain><comment><author>eloff</author><text>This takes me back to some blissful days spent optimizing an integer compression scheme in AVX2. It&amp;#x27;s really a difficult instruction set to work with. The authors comment about a set of oddly shaped Legos is very apt. It often doesn&amp;#x27;t have instructions that cross lanes and often lacks the thing you need, so you find yourself hacking around it with bit operations and lookup tables. AVX512 is a huge improvement, but it still hasn&amp;#x27;t caught on in a big way over seven years later.</text></comment>