是否有 simd/avx 指令 return 每个不为 0 的 32 位通道的 u8 掩码

Is there an simd/avx instruction to return a u8 mask for every 32 bit lane that isn't 0

假设我有一个像这样的 256 位宽向量:

00000000 00000000 11100110 00000000
00000000 00000000 00000000 00000000
00000000 00000000 10000101 00000000
00000000 00000000 01111110 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00001100 00000000
00000000 00000000 00000000 00000000 

获得 8 位掩码的最有效方法是什么 看起来有点像这样:10110010 其中每个设置位代表 > 0 的 32 位整数通道 使用 AVX2 以及 amd 和 intel 都支持的一切

假设有符号整数通道:

inline uint8_t positiveMask_epi32( __m256i vec )
{
    // Compare 32-bit integers for i > 0
    const __m256i zero = _mm256_cmpgt_epi32( vec, _mm256_setzero_si256() );
    // Collect high bits
    const int mask = _mm256_movemask_ps( _mm256_castsi256_ps( zero ) );
    // Return that value
    return (uint8_t)mask;
}

如果它们是无符号整数:

inline uint8_t nonZeroMask_epu32( __m256i vec )
{
    // Compare 32-bit integers for i == 0
    const __m256i eqZero = _mm256_cmpeq_epi32( vec, _mm256_setzero_si256() );
    // Collect high bits
    const int mask = _mm256_movemask_ps( _mm256_castsi256_ps( eqZero ) );
    // Flip lowest 8 bits in the result, we want 1 for non-zeros
    return (uint8_t)( mask ^ 0xFF );
}