Extract bits with SIMD

I want to extract 8 bits from the __mm256i src register variable with 8 positions given by another __mm256i offset , which consists of 8 integers. For example: if offset is [1,3,5,21,100,200,201,202] , I want to get the 1, 3, 5, 100, 200, 201, 202nd bits from src and pack them in int8 .

This question is similar to Extracting bits using bit manipulation , but I want a solution with SIMD instructions, as it is much faster.

+5
source share
1 answer
  • Select a maximum of 3 bits in each element and select the desired 32-bit element using the built-in _mm256_permutevar8x32_epi32 ().
  • Select a minimum of 5 bits in each element of the vector and create a bitmask using the built-in _mm256_sllv_epi32 ().
  • Compose the result in int8 using _mm256_movemask_ps () (cast __m256i to __m256).

The following is an example:

 uint8_t Select(__m256i offset, __m256i src) { __m256i permutedSrc = _mm256_permutevar8x32_epi32(src, _mm256_srli_epi32(offset, 5)); __m256i shift = _mm256_and_si256(offset, _mm256_set1_epi32(31)); __m256i bitmask = _mm256_sllv_epi32(_mm256_set1_epi32(1), shift); __m256i mask = _mm256_cmpeq_epi32(_mm256_and_si256(permutedSrc, bitmask), _mm256_setzero_si256()); return ~_mm256_movemask_ps(_mm256_castsi256_ps(mask)); } 
+4
source

Source: https://habr.com/ru/post/1272737/


All Articles