12#if defined(PIXIE_AVX512_SUPPORT) && defined(__AVX512VBMI__)
16namespace pixie::detail::compressed {
26alignas(64)
inline constexpr auto kPrefixLowBytes = [] {
27 std::array<std::uint8_t, 64> indexes{};
28 for (std::size_t i = 0; i < 32; ++i) {
29 indexes[2 * i] = 8 + i * 14 / 8;
30 indexes[2 * i + 1] = indexes[2 * i] + 1;
35alignas(64)
inline constexpr auto kPrefixHighBytes = [] {
36 std::array<std::uint8_t, 64> indexes{};
37 for (std::size_t i = 0; i < 32; ++i) {
38 indexes[2 * i] = (10 + i * 14 / 8) & 63;
47inline std::optional<PackedPrefixLocation> packed_prefix_search(
48 const std::uint64_t* record,
50 std::size_t valid_bits) {
51#if defined(PIXIE_AVX512_SUPPORT) && defined(__AVX512VBMI__)
52 const auto packed = _mm512_loadu_si512(record);
53 const auto low = _mm512_permutexvar_epi8(
54 _mm512_load_si512(kPrefixLowBytes.data()), packed);
55 const auto high = _mm512_permutexvar_epi8(
56 _mm512_load_si512(kPrefixHighBytes.data()), packed);
57 const auto offsets = _mm512_set1_epi64(0x0002000400060000);
58 auto ends = _mm512_and_si512(
60 _mm512_srlv_epi16(low, offsets),
61 _mm512_sllv_epi16(high,
62 _mm512_sub_epi16(_mm512_set1_epi16(16), offsets))),
63 _mm512_set1_epi16(0x3fff));
65 const auto positions = _mm512_set_epi16(
66 16384, 15872, 15360, 14848, 14336, 13824, 13312, 12800, 12288, 11776,
67 11264, 10752, 10240, 9728, 9216, 8704, 8192, 7680, 7168, 6656, 6144,
68 5632, 5120, 4608, 4096, 3584, 3072, 2560, 2048, 1536, 1024, 512);
69 ends = _mm512_sub_epi16(
70 _mm512_min_epu16(positions, _mm512_set1_epi16(valid_bits)), ends);
72 const std::uint32_t matches =
73 _mm512_cmpge_epu16_mask(ends, _mm512_set1_epi16(target));
75 const std::uint32_t basic = std::countr_zero(matches);
77 _mm512_set1_epi32((basic << 16) | ((basic - 1) & 0xffff));
78 const std::uint32_t bounds = _mm_cvtsi128_si32(
79 _mm512_castsi512_si128(_mm512_permutexvar_epi16(indexes, ends)));
Definition packed_prefix_search.h:18