9namespace pixie::detail::compressed {
15inline std::size_t select_loaded_block(
const std::uint64_t* words,
17#ifdef PIXIE_AVX512_SUPPORT
18 auto bits = _mm512_loadu_si512(words);
20 bits = _mm512_xor_si512(bits, _mm512_set1_epi64(-1));
22 const auto zero = _mm512_setzero_si512();
23 auto prefixes = _mm512_popcnt_epi64(bits);
24 prefixes = _mm512_add_epi64(prefixes, _mm512_alignr_epi64(prefixes, zero, 7));
25 prefixes = _mm512_add_epi64(prefixes, _mm512_alignr_epi64(prefixes, zero, 6));
26 prefixes = _mm512_add_epi64(prefixes, _mm512_alignr_epi64(prefixes, zero, 4));
27 const auto candidates =
28 _mm512_cmp_epu64_mask(prefixes, _mm512_set1_epi64(rank), _MM_CMPINT_GT);
29 const auto lane = std::countr_zero(
static_cast<unsigned>(candidates));
30 const auto selector = _mm512_set1_epi64(lane);
31 const auto word =
static_cast<std::uint64_t
>(_mm_cvtsi128_si64(
32 _mm512_castsi512_si128(_mm512_permutexvar_epi64(selector, bits))));
33 const auto end =
static_cast<std::uint64_t
>(_mm_cvtsi128_si64(
34 _mm512_castsi512_si128(_mm512_permutexvar_epi64(selector, prefixes))));
35 const auto before = end - std::popcount(word);
36 return lane * 64 + ::select_64(word, rank - before);
41 return ::select0_512(words, rank);
43 return ::select_512(words, rank);