Skip to content

perf: NEON kernel for 5/6-bit widths — scalar path is ~4.6x slower than the 4-bit NEON path #40

Description

@ajianaz

Found during #39 implementation (E2E bench, real EmbeddingGemma d=768, n=2000, 100 queries, release)

mode B/vec r@1 r@10 ms/q
plain 4-bit (NEON) 514 0.910 0.958 0.92
plain 5-bit (scalar) 642 0.970 0.979 4.27
plain 6-bit (scalar) 770 0.960 0.980 4.29
4-bit+residual (NEON) 1028 0.990 0.984 1.80

Recall/size goals of #39 are met, but 5/6-bit scoring currently runs the portable scalar unpack loop instead of the batch-4 NEON kernel, costing ~4.6x query latency vs 4-bit.

Scope

  • score_neon_wide on aarch64: unpack 5/6-bit codes to bytes (or 16-bit indices), LUT gather from 32/64-entry centroid tables, widen+accumulate — keep bit-identity with score_wide_scalar (existing bitwise parity test pattern).
  • Wire into the batch-4 slot loop next to score_neon4 when bits != 4.
  • Optional AVX2 variant (use_avx2 && bits != 4 gate already exists).
  • Acceptance: 5/6-bit ms/q within ~1.5x of the 4-bit path on the same bench; neon_matches_scalar_bitwise-style parity test extended to 5/6-bit.

Notes

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions