Optimize bit iteration and validity checking with SIMD popcount#8636
Optimize bit iteration and validity checking with SIMD popcount#8636robert3005 wants to merge 1 commit into
Conversation
Merging this PR will improve performance by ×2.4
Performance Changes
Tip Curious why this is faster? Comment Comparing Footnotes
|
839b365 to
7609b8f
Compare
|
@claude review in depth |
|
Claude finished @0ax1's task in 3m 36s —— View job In-depth reviewI reviewed the full diff (
Correctness (verified)
Minor / non-blocking
On the CodSpeed reportThe only regression flagged is Tests & benchesTest coverage is solid: parameterized Suggested checks before merge (I did not run these in-sandbox): cargo nextest run -p vortex-buffer -p vortex-mask -p vortex-runend -p vortex-duckdb
cargo clippy --all-targets --all-featuresVerdict: LGTM. Correct, semantics-preserving, well-tested. Only nits are cosmetic; the flagged regression appears to be runner noise on an unrelated empty-slice benchmark. |
0ax1
left a comment
There was a problem hiding this comment.
should we land the benchmarks upfront. then the codspeed reports could confirm the speedup. i assume this is thoroughly unit tested so this is my main nit.
|
Made #8656. I will rebase this once that merges |
0ax1
left a comment
There was a problem hiding this comment.
Disabled auto-merge. Feel free to land if the benchmarks look good.
`Mask::valid_counts_for_indices` walked the validity bit buffer one bit at a time via `BitIterator::next`, accumulating a running valid count. The pco/zstd slice decoders call it with `[slice_start, slice_stop]`, so the cost was a bit-by-bit scan of the entire prefix up to `slice_stop`. Replace the per-bit walk with an incremental SIMD popcount over each gap between consecutive indices. Total scanned bits are unchanged, but the work now goes through the vectorized `count_ones` path. Add `BitBuffer::count_range(start, end)`, which counts set bits in a range directly over the backing buffer without cloning a sliced `BitBuffer`, so the many-indices case has no per-gap allocation overhead. Benchmark (vortex-mask/benches/valid_counts.rs, median): slice_bounds 16384 8.7us -> 51ns (~170x) slice_bounds 262144 138us -> 310ns (~445x) slice_bounds 1M 554us -> 1.86us (~300x) many_indices 16384 10.1us -> 1.68us (~6x) many_indices 1M 613us -> 3.33us (~185x) Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk> Signed-off-by: Robert Kruszewski <github@robertk.io>
7609b8f to
e53eab2
Compare
|
@robert3005 benchmarks looking good! |
recreation of #8261 which had real performance benefits for iterating valid indices and had guidelines for future agents performance work