Skip to content

Blocked BitPacked: fuse FoR decode over blocked children - #10251

Merged
joseph-isaacs merged 3 commits into
developfrom
mk/for-bitpacked-blocked-fused
Oct 14, 2026
Merged

joseph-isaacs merged 3 commits into
developfrom
mk/for-bitpacked-blocked-fused

Conversation

@mhk197

@mhk197 mhk197 commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Tracking Issue: #10167

Summary

FoR now decodes a blocked BitPacked child in one pass, the same as a global-width child. Before, the child was decoded to a primitive array first and the references were added in a second pass.

A block and a FoR chunk are both 1024 values, so each block unpacks at its own width and adds its chunk's reference directly.

Changes

  • unpack_chunks walks the blocks of a blocked child, each at its own width.
  • execute_block_offsets and for_each_packed_block are shared with the blocked BitPacked decoder.
  • Block offsets widen to u64 directly instead of through a lazy cast.

Benchmarks

for_decode, per-chunk references, local M5 Max:

Global width Blocked, before Blocked, after
u32 9.62 µs 18.54 µs 9.87 µs
i64 11.95 µs 20.04 µs 12.29 µs

Testing

  • fused_decode_is_wrapping_add draws a bit width per block.
  • for_fuses_blocked_child covers partial blocks, zero and native widths, and constant and per-chunk references.

Follow-up

FoRScheme still bit-packs its child with BITPACKING_V1, so the compressor doesn't write this combination yet. That needs #10245.

@mhk197 mhk197 added the changelog/performance A performance improvement label Oct 2, 2026
@codspeed

codspeed Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Merging this PR will improve performance by 11.2%

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

⚠️ 1 benchmark measured no execution time

Nothing ran under measurement, usually because the compiler removed the code under test. This result is not comparable, so it counts as unchanged.

Preventing compiler optimizations

⚠️ 11 benchmarks spent significant time in system calls

System calls cannot be consistently instrumented, so they are not included in the measure, which understates the real cost. Please switch to the Walltime instrument to accurately measure system calls.

Measurement and system calls

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 2 improved benchmarks
✅ 2211 untouched benchmarks
🆕 6 new benchmarks

Performance Changes

Mode Benchmark BASE HEAD Efficiency
⚡ WallTime bitpack_blocked_decompress_neon[u32] 14.3 µs 12.7 µs +12.38%
⚡ WallTime bitpack_blocked_decompress_avx512[u32] 9.4 µs 8.6 µs +10.04%
🆕 WallTime decode_blocked_bitpacked_chunked_avx2[i64, 524288] N/A 20.8 µ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 µs N/A
🆕 WallTime decode_blocked_bitpacked_chunked_avx512[u32, 524288] N/A 17.5 µs N/A
🆕 WallTime decode_blocked_bitpacked_chunked_neon[i64, 524288] N/A 27.7 µs N/A
🆕 WallTime decode_blocked_bitpacked_chunked_neon[u32, 524288] N/A 26.7 µs N/A

Tip

Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.


Comparing mk/for-bitpacked-blocked-fused (8f30906) with develop (d42e7c9)

Open in CodSpeed

@mhk197
mhk197 force-pushed the mk/bitpacked-v2-scheme branch 6 times, most recently from 8da23f9 to 3711acb Compare October 12, 2026 18:30
@mhk197
mhk197 changed the base branch from mk/bitpacked-v2-scheme to develop October 12, 2026 19:36
@mhk197
mhk197 force-pushed the mk/for-bitpacked-blocked-fused branch from 0b18f5c to 8f30906 Compare October 12, 2026 19:36
@mhk197
mhk197 marked this pull request as ready for review October 12, 2026 19:55
// `range` counts from the start of the first chunk, and the output starts at `offset`.
let skip = offset.saturating_sub(range.start);
let dst = &mut output[range.start + skip - offset..range.end - offset];
if dst.len() == FL_CHUNK_SIZE {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly, the issue may be that dst.len() may be less than chunk size. If it's greater, we currently copy to a scratch buffer although we can copy it to dst as there's sufficient capacity.

When exactly can dst.len() be less than a chunk size? When we are exporting the tail?

This is not exactly related to your change, but the exiting code seems suspicious to me

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are three cases when dst.len() < FL_CHUNK_SIZE:

  1. offset > 0, which happens for an array that has been sliced. so head.len() < FL_CHUNK_SIZE
  2. tail.len() < FL_CHUNK_SIZE
  3. both of the above

e.g.:

offset = 100, len = 2500

                   chunk 0                chunk 1                 chunk 2
position  0                       1024                   2048          2600       3072
          ┌───────────────────────┬──────────────────────┬────────────────────────┐
packed    │ offset ┆     924      │         1024         │     552     ┆  unused  │
          └───────────────────────┴──────────────────────┴────────────────────────┘
                   ▼              ▼                      ▼             ▼
output             0              924                    1948          2500
                   ├──────────────┼──────────────────────┼─────────────┤
                       dst: 924          dst: 1024          dst: 552
                     via scratch      unpack in place      via scratch

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will never be greater

@joseph-isaacs
joseph-isaacs merged commit 9c8a995 into develop Oct 14, 2026
117 checks passed
@joseph-isaacs
joseph-isaacs deleted the mk/for-bitpacked-blocked-fused branch October 14, 2026 11:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog/performance A performance improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants