Skip to content

Add arm64 NEON acceleration#32

Open
mgomes wants to merge 7 commits into
zeebo:masterfrom
mgomes:mgomes/neon
Open

Add arm64 NEON acceleration#32
mgomes wants to merge 7 commits into
zeebo:masterfrom
mgomes:mgomes/neon

Conversation

@mgomes

@mgomes mgomes commented Jul 11, 2026

Copy link
Copy Markdown

On arm64 every input fell back to the pure-Go implementation. This adds a cgo-free NEON backend for chunk and parent hashing, processing four chunks/parents per pass in 128-bit vector lanes, dispatched with the same thresholds as AVX2. The committed impl_arm64.s is emitted by a small generator in avo/neon (mirroring how the avo-generated amd64 assembly is treated) and is verified against hash_pure by the same property tests used for AVX2.

Apple M4, benchstat n=6:

Benchmark pure Go NEON delta
BLAKE3/Entire/1024_kib 1.05 GB/s 2.29 GB/s +118%
BLAKE3/Entire/0064_kib 1.05 GB/s 2.26 GB/s +114%
BLAKE3/Entire/0004_kib 1.02 GB/s 1.94 GB/s +91%
HashF_8K 1.14 GB/s 2.48 GB/s +117%
HashP/4 1.11 GB/s 2.59 GB/s +133%
HashP/8 1.12 GB/s 2.59 GB/s +132%

Unfortunately NEON is fixed at 128 bits by the ARM architecture, so four chunks per pass is the ceiling (versus eight for 256-bit AVX2). ARM's wider SVE extension is optional and not implemented on Apple Silicon yet. Happy to follow up with a PR that interleaves the two independent 4-lane passes into one instruction stream (still single-threaded). That should fill idle NEON slots and boost perf a bit more.

mgomes added 7 commits July 11, 2026 01:24
Four chunks/parents per pass in 128-bit vector lanes, generated Go
assembly (no cgo) following the upstream C NEON implementation. The
generator lives in avo/neon and the committed impl_arm64.s is verified
against hash_pure by the same property tests used for AVX2.
Same thresholds as the AVX2 path: HashF for inputs over two chunks,
HashP for two or more parents. Below the HashF threshold the 4-lane
kernel cannot beat the scalar loop since it always runs 16 blocks.
Bumping the go directive would change loop variable semantics for the
existing avx2/sse41 generators; write the neon generator in 1.13-compatible
style instead.
Write errors were silently discarded, so an ENOSPC during generation
could exit zero and leave truncated assembly behind the redirect.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant