Repository navigation
Conversation
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
…ked.v2 is allowed Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Merging this PR will regress 1 benchmark
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | WallTime | bitpack_blocked_compress_avx2 |
6.8 µs | 7.7 µs | -11.74% |
| ⚡ | WallTime | bitpack_blocked_decompress_avx512[u32] |
9.9 µs | 8.7 µs | +14.44% |
| ⚡ | WallTime | bitpack_blocked_decompress_avx2[u32] |
11.2 µs | 10.1 µs | +11.83% |
| ⚡ | WallTime | bitpack_blocked_decompress_avx512[u64] |
20.1 µs | 18 µs | +11.56% |
| ⚡ | WallTime | bitpack_blocked_decompress_neon[u32] |
14.1 µs | 12.7 µs | +10.72% |
| 🆕 | WallTime | decode_blocked_bitpacked_chunked_avx2[i64, 524288] |
N/A | 20.9 µs | N/A |
| 🆕 | WallTime | decode_blocked_bitpacked_chunked_avx2[u32, 524288] |
N/A | 20.6 µs | N/A |
| 🆕 | WallTime | decode_blocked_bitpacked_chunked_avx512[i64, 524288] |
N/A | 18.3 µs | N/A |
| 🆕 | WallTime | decode_blocked_bitpacked_chunked_avx512[u32, 524288] |
N/A | 17.8 µs | N/A |
| 🆕 | WallTime | decode_blocked_bitpacked_chunked_neon[i64, 524288] |
N/A | 28.1 µs | N/A |
| 🆕 | WallTime | decode_blocked_bitpacked_chunked_neon[u32, 524288] |
N/A | 27.1 µs | N/A |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing mk/for-bitpacked-blocked-fused (0b18f5c) with mk/bitpacked-v2-scheme (c98cb99)
Footnotes
-
503 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
c98cb99 to
f638117
Compare
Tracking Issue: #10167
Stacked on #10245; this PR targets
mk/bitpacked-v2-scheme.Summary
FoRdecodes a blockedBitPackedchild through the fused unpack, with a single reference or with per-chunk references. Before,FoR::executerequired a global bit width for the fused path, so a blocked child was decoded to a primitive array first and the references were added in a second pass.Design
unpack_chunksinfor_decompress.rsmatches onbit_widths(). A global width walks the chunks withfor_each_packed_chunkas before. Blocked widths walk the blocks with a new crate-privatefor_each_packed_block, and both feed the same unpack-and-add closure, so each block unpacks at its own width withunchecked_unfor_pack.execute_block_offsets, which is extracted fromunpack_into_primitive_builder_blockedso that both decoders check the boundaries the same way before unpacking without bounds checks.FoR::executedrops theis_global()condition from its fused predicate. The chunk alignment condition is unchanged: blocks line up with FoR chunks when the reference is constant or the offsets match.execute_block_offsetswidens the executed offsets tou64directly instead of executing a lazycast. The block loop still compiles once per value type. This removes a fixed cost of about 0.25 µs per array, which also speeds up blockedBitPackeddecoding on its own.Benchmarks
Local walltime on an M5 Max, median of 7–9 interleaved runs against the parent commit. The machine was under load, so differences up to about 5% are noise.
for_decode(in this PR): FoR with per-chunk references over 512 KiB of values. The blocked child packs every block at the global child's width, so the packed bytes are the same.decode_bitpacked_chunked/u32(global width)decode_blocked_bitpacked_chunked/u32decode_bitpacked_chunked/i64(global width)decode_blocked_bitpacked_chunked/i64bitpack_blocked_decompress(from #10202, blockedBitPackedwithout FoR): u32 5.17 → 4.92 µs, u64 12.12 → 11.49 µs, from the offset widening.A local matrix (not committed) decoded FoR over BitPacked for every combination of global or per-chunk references and global or per-block widths, for u32 and i64. With 64 blocks of u32, blocked widths now decode in 0.50–0.58x of the time they took before:
Small arrays isolate the fixed cost per array. For one block of u32 with per-chunk references, a blocked child took 0.79 µs before, 0.50 µs with the fused path alone, and 0.25 µs once the offsets skip the cast. A global-width child takes 0.24 µs.
Testing
for_::tests::fused_decode_is_wrapping_add(hegel) also draws a width per block, from zero to the native width, so blocked children cover every integer type with patches, nulls, a constant or per-chunk references, and slices.blocked::tests::for_fuses_blocked_childbuilds blocked children that start within their first block, hold zero and native width blocks and have FoR-encoded offsets, under constant and per-chunk references.unpack_chunksfails both tests and the existingfor_decodes_blocked_child.cargo nextest run -p vortex-fastlanes -p vortex-btrblocks: 755 passed.cargo clippy -p vortex-fastlanes --all-targets --all-features -- -D warningspasses.cargo +nightly-2026-09-10 fmt -p vortex-fastlanes --checkreports onlybenches/bitpack_blocked_decompress.rs, which comes from the base branch and is already formatted further down the stack.Follow-ups
FoRSchemestill bit-packs its child withBITPACKING_V1, so the compressor never writes FoR over blockedBitPackedyet. This PR makes that combination decode as fast as a global width.