Skip to content

perf(linalg): add NEON f32 L2 kernel for aarch64 - #11077

Open
xixicat wants to merge 2 commits into
lance-format:mainfrom
xixicat:feat/aarch64-neon-l2
Open

xixicat wants to merge 2 commits into
lance-format:mainfrom
xixicat:feat/aarch64-neon-l2

Conversation

@xixicat

@xixicat xixicat commented Nov 14, 2026

Copy link
Copy Markdown

Summary

  • Add an explicit aarch64 NEON f32 L2 kernel: eight float32x4_t accumulators, 32/16/4-wide loops plus a scalar tail.
  • Register it in the L2_F32 and L2_F32_BATCH dispatch tables. NEON is part of the aarch64 baseline, so both dispatches remain compile-time static (no runtime feature check).
  • The kernel is a safe function with length clamping; add pair and batch parity tests against the portable scalar path.

Performance (Kunpeng 920)

Microbenchmark, base vs NEON (ns/vector):

workload dim 64 dim 256 dim 1024 dim 2176
cache-resident pair 1.92x 1.64x 1.55x 1.36x
streaming 64 MiB 1.14x 1.06x 1.04x 1.04x

PQ sub-vector dimensions: 1.12x at dim 8, 2.18x at dim 16 (no regression).

End-to-end (1M x 1024 vectors, IVF nlist=256, 6 GiB index cache, pinned cores 64-79, the same index searched by both wheels, alternating runs, recall@100 unchanged):

index nprobe base QPS NEON QPS speedup
IVF_RQ (bits=1, refine=5) 8 7.35 9.45 1.29x
IVF_RQ 16 4.70 6.50 1.38x
IVF_RQ 32 2.45 3.40 1.39x
IVF_FLAT 8 8.60 11.45 1.33x
IVF_FLAT 16 4.65 6.50 1.40x
IVF_FLAT 32 2.50 3.40 1.36x

Build time: IVF_RQ 65.7s -> 54.7s (1.20x), IVF_FLAT 78.2s -> 64.0s (1.22x).

Test plan

  • cargo test -p lance-linalg --lib distance::l2 (107 passed, including the new NEON parity and batch parity tests)
  • Replacement benchmarks above

Route the aarch64 pair and batch f32 L2 paths to an explicit ASIMD
kernel with eight float32x4_t accumulators, 32/16/4-wide loops and a
scalar tail, instead of relying on LLVM's 4-wide auto-vectorisation.
NEON is part of the aarch64 baseline, so both dispatch tables select
the kernel at compile time.

Verification (Kunpeng 920):
- cargo test -p lance-linalg --lib distance::l2: 107 passed
- new tests: kernel parity vs l2_f32_scalar over random dims 4..4048,
  and batch parity at dims 8/16/100/256/1024

Microbenchmark (pinned core, base vs NEON):
- cache-resident pair: 1.92x @dim64, 1.64x @256, 1.55x @1024,
  1.36x @2176
- streaming 64 MiB: 1.14x @dim64 .. 1.04x @2176
- PQ sub-vector dims: 1.12x @dim8, 2.18x @Dim16 (no regression)

End-to-end (pylance 15.0.0b19 wheel, 1M x 1024 smoke1m, nlist=256,
6 GiB index cache, pinned cores 64-79, same index searched by both
wheels, median of alternating runs, recall@100 unchanged):
- IVF_RQ (bits=1, refine=5) QPS: 7.35->9.45 (1.29x) @nprobe8,
  4.70->6.50 (1.38x) @16, 2.45->3.40 (1.39x) @32
- IVF_FLAT QPS: 8.60->11.45 (1.33x) @nprobe8, 4.65->6.50 (1.40x)
  @16, 2.50->3.40 (1.36x) @32
- IVF_RQ build: 65.7s -> 54.7s (1.20x)
- IVF_FLAT build: 78.2s -> 64.0s (1.22x)

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@github-actions github-actions Bot added A-index Vector index, linalg, tokenizer performance labels Nov 14, 2026

@lance-gatekeeper lance-gatekeeper Bot left a comment

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.

⚠️ Gate recommendation: approve with a non-blocking risk.

No blocking correctness issue found. Pair and batch L2 checks pass on x86_64 and emulated aarch64, including the new NEON parity tests. Native performance remains unverified in this review: the reported gains are from Kunpeng 920, while the kernel becomes the default on all aarch64 targets.

@lance-gatekeeper lance-gatekeeper Bot added K-approved Latest Gatekeeper recommendation permits acceptance. K-risk Latest Gatekeeper recommendation includes a non-blocking risk. labels Nov 14, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-index Vector index, linalg, tokenizer K-approved Latest Gatekeeper recommendation permits acceptance. K-risk Latest Gatekeeper recommendation includes a non-blocking risk. performance

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant