Skip to content

perf: vectorize small u8 table take with NEON - #9571

Open
joseph-isaacs wants to merge 3 commits into
developfrom
ji/small-u8-table-take-neon
Open

perf: vectorize small u8 table take with NEON#9571
joseph-isaacs wants to merge 3 commits into
developfrom
ji/small-u8-table-take-neon

Conversation

@joseph-isaacs

Copy link
Copy Markdown
Contributor

Rationale

Low-cardinality dictionaries with u8 codes and one-byte values can decode through an in-register NEON table instead of arbitrary scalar lookups.

Stacked on benchmark baseline #9566. The x86 implementation is intentionally split into the next PR.

Changes

  • Use NEON TBL on little-endian AArch64.
  • Apply the path to u8 codes, at most 16 one-byte values, and at least 64 rows.
  • Retain bounds checks and the existing fallback.
  • Add correctness and out-of-bounds tests.

CodSpeed wall-time results

Medians over 1,000 samples on Graviton3 metal, compared with #9566:

Rows Baseline NEON Speedup Time reduction
1M 552.4 µs 51.06 µs 10.82× 90.8%
16M 8.786 ms 799.7 µs 10.99× 90.9%

Runs: baseline, optimized.

Checks

  • focused small-table correctness and bounds tests
  • targeted Clippy with warnings denied
  • cargo +nightly fmt --all --check
  • git diff --check

@codspeed-hq

codspeed-hq Bot commented Aug 24, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by ×3

⚠️ 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.

⚡ 5 improved benchmarks
✅ 2188 untouched benchmarks
⏩ 218 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
WallTime dict_canonicalize_gt_u8_neon[16000000] 9,349.5 µs 778.3 µs ×12
WallTime dict_canonicalize_gt_u8_neon[1000000] 559.9 µs 50.6 µs ×11
WallTime arrow_checked_add_u32_neon[16384] 20.4 µs 13.3 µs +53.36%
WallTime words_gather_scalar_avx2[65536] 9.4 µs 8.3 µs +13.45%
WallTime words_gather_dispatch_avx512[1024] 9 ns 8 ns +12.5%

Tip

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


Comparing ji/small-u8-table-take-neon (a5329ec) with develop (2a5b1a7)2

Open in CodSpeed

Footnotes

  1. 218 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.

  2. No successful run was found on develop (9d1b103) during the generation of this report, so 2a5b1a7 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

Base automatically changed from ji/small-u8-table-take-benchmark to develop September 9, 2026 16:21
Use NEON TBL for u8-coded tables with at most 16 one-byte values.

Signed-off-by: Joseph Isaacs <joseph-isaacs@users.noreply.github.com>
@joseph-isaacs
joseph-isaacs force-pushed the ji/small-u8-table-take-neon branch from 21fa748 to e97db31 Compare September 9, 2026 16:21
@joseph-isaacs joseph-isaacs added the changelog/performance A performance improvement label Sep 9, 2026 — with Claude
`take_small_byte_table_rejects_out_of_bounds_index` asserts the NEON small-table
bounds-check message, but the table path only exists on little-endian AArch64.
On other targets `take_values` falls through to the AVX2 or scalar path, whose
panic messages differ, so the test failed on the linux-musl runner (no AVX2:
the scalar path panics with the plain slice message).

Gate the test on the same cfg as the module. `take_small_byte_table` stays
unconditional so every target keeps checking the results.

DCO Remediation Commit for Joe Isaacs <joe.isaacs@live.co.uk>

I, Joe Isaacs <joe.isaacs@live.co.uk>, hereby add my Signed-off-by to this commit: e97db31

Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013YND3Jq47YtL15ob3GEsVY
@joseph-isaacs
joseph-isaacs force-pushed the ji/small-u8-table-take-neon branch from a08892e to adf36d0 Compare September 9, 2026 17:10
…take-neon

Picks up #9819, which fixes the `VarBinBuilder::with_capacity` deprecation
in `vortex-btrblocks` that was failing both `Rust (lint)` jobs on this PR.

Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
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.

2 participants