Pixie
Loading...
Searching...
No Matches
packed_prefix_multishift.h
1#pragma once
2
3#include <pixie/rank_select/detail/compressed/packed_prefix_search.h>
4
5namespace pixie::experimental {
6
7// Four 14-bit values occupy seven bytes. Gather each group into a 64-bit
8// lane; the eighth byte is ignored after the final 14-bit mask.
9alignas(64) inline constexpr auto kPrefixGroupBytes = [] {
10 std::array<std::uint8_t, 64> indexes{};
11 for (std::size_t i = 0; i < 64; ++i) {
12 indexes[i] = (8 + (i / 8) * 7 + i % 8) & 63;
13 }
14 return indexes;
15}();
16
24template <bool Zero>
25inline std::optional<detail::compressed::PackedPrefixLocation>
26packed_prefix_search_multishift(const std::uint64_t* record,
27 std::uint64_t target,
28 std::size_t valid_bits) {
29#if defined(PIXIE_AVX512_SUPPORT) && defined(__AVX512VBMI__)
30 const auto packed = _mm512_loadu_si512(record);
31 const auto groups = _mm512_permutexvar_epi8(
32 _mm512_load_si512(kPrefixGroupBytes.data()), packed);
33 auto ends =
34 _mm512_and_si512(_mm512_multishift_epi64_epi8(
35 _mm512_set1_epi64(0x322a241c160e0800ULL), groups),
36 _mm512_set1_epi16(0x3fff));
37 if constexpr (Zero) {
38 const auto positions = _mm512_set_epi16(
39 16384, 15872, 15360, 14848, 14336, 13824, 13312, 12800, 12288, 11776,
40 11264, 10752, 10240, 9728, 9216, 8704, 8192, 7680, 7168, 6656, 6144,
41 5632, 5120, 4608, 4096, 3584, 3072, 2560, 2048, 1536, 1024, 512);
42 ends = _mm512_sub_epi16(
43 _mm512_min_epu16(positions, _mm512_set1_epi16(valid_bits)), ends);
44 }
45 const std::uint32_t matches =
46 _mm512_cmpge_epu16_mask(ends, _mm512_set1_epi16(target));
47 assert(matches != 0);
48 const std::uint32_t basic = std::countr_zero(matches);
49 const auto indexes =
50 _mm512_set1_epi32((basic << 16) | ((basic - 1) & 0xffff));
51 const std::uint32_t bounds = _mm_cvtsi128_si32(
52 _mm512_castsi512_si128(_mm512_permutexvar_epi16(indexes, ends)));
54 basic, basic == 0 ? 0 : bounds & 0xffff, bounds >> 16};
55#else
56 (void)record;
57 (void)target;
58 (void)valid_bits;
59 return std::nullopt;
60#endif
61}
62
63} // namespace pixie::experimental
Definition excess.h:90
std::optional< detail::compressed::PackedPrefixLocation > packed_prefix_search_multishift(const std::uint64_t *record, std::uint64_t target, std::size_t valid_bits)
Experimental AVX-512 VBMI multishift search of packed rank prefixes.
Definition packed_prefix_multishift.h:26
Definition packed_prefix_search.h:18