Skip to content

go-simd documentation

Pure-Go SIMD drop-ins for the Go standard library — byte-identical fast paths for encoding/base64, encoding/base32, encoding/hex, encoding/ascii85, unicode/utf8, hash/adler32, hash/crc32, hash/crc64, strconv, encoding/json.Valid, ASCII case folding, and the SIMD-amenable primitives under and around them — 21 repositories in all, plus a proof-of-concept 7th (wasm-SIMD v128) target for matchlen in matchlen-wasm (not a kernel package with a docs page of its own).

Every hot loop is real SIMD assembly generated by go-asmgen across all six of Go's 64-bit SIMD targets — amd64, arm64, riscv64, loong64, ppc64le (VSX) and s390x (vector facility, big-endian) — on plain go build, CGO_ENABLED=0, stable Go, no GOEXPERIMENT. Each package is a drop-in: the same signatures and byte-identical output (and, where applicable, byte-identical errors) as the stdlib package it accelerates, with the short tail delegated back to the standard library so results match exactly.

Six SIMD targets, validated on seven architectures. A single go-asmgen builder (v0.5.0) over a shared ABI0 layout emits the kernels for all six targets; cmd/asm encodes them. As of 2026-06, ppc64le (real POWER9), riscv64 (real SpacemiT X60, RVV 1.0) and loong64 (real Loongson 3A5000) are natively measured on the GCC Compile Farm — not just qemu-validated — and the portable scalar fallback is additionally build+test-validated on a seventh arch, ppc64 (big-endian), on real POWER9. Most repos are now natively measured on real IBM z15 (VXE2, 2026-07-03, -count=6) — the vector-facility kernels post clear wins (bitpack ~34×, streamvbyte decode ~20×, hex encode ~18×, matchlen ~9.2×, crc64 ~9.1×). Two repos — jsonvalidate and ascii85 — still carry the older qemu-validated-for-correctness framing, native z15 throughput pending for those two. Headline numbers come from native measurement and are never extrapolated. Two results stand out: base32 gets real SIMD on ppc64le (VSRH) and s390x (VMLHH) where the arm64 NEON port could not on stable Go (Go's arm64 assembler gained the register-variable shift and integer vector multiply only in Go 1.27), and every kernel is bit-exact on big-endian s390x — a genuine cross-endian validation.

The honesty policy

These numbers are benchmarked, not hand-waved. Every page reports the honest headline — the wins and the parities and the cases where SIMD genuinely does not help. A multi-table scalar loop that beats the vector unit (histogram), or a checksum that lands ~7% behind the best competitor (adler32), is reported as such. The credibility is the honesty.

Stdlib drop-ins

Package Accelerates Honest headline
base64 encoding/base64 encode ~17× stdlib; beats emmansun/base64 ~5–6%
base32 encoding/base32 encode ~7.9× stdlib (AVX2); real SIMD on ppc64le VSRH + s390x VMLHH where arm64 can't; no prior pure-Go SIMD base32
hex encoding/hex beats tmthrgd/go-hex both ways — encode 20.4×, decode 6.24× stdlib
utf8 unicode/utf8 Valid ~19× stdlib, edges stuartcarnie/go-simd ~3.5%
ascii85 encoding/ascii85 first SIMD ascii85, SIMD encode and decode on all 6 arches; arm64 NEON kernel on Go 1.27 (~3.0×; fused-scalar ~1.9× on stable Go ≤ 1.26); native ppc64le POWER9 ~2.9×, riscv64 X60 ~4.0×, loong64 ~4.3×
ascii ASCII case (bytes/strings) branchless vector case-fold, byte-identical to stdlib; real SIMD on all 6 arches incl. arm64; ~4.9× stdlib (ToUpper)
adler32 hash/adler32 ~12–14× stdlib, but ~7% behind mhr3/adler32-simd — honest
crc64 hash/crc64 first pure-Go SIMD crc64 (CLMUL folding); arm64 ~4.2× stdlib
crc32 hash/crc32 arm64-only, deliberately: stdlib IEEE path is already hardware-assisted elsewhere; PMULL/PMULL2 fold-by-eight beats arm64's serial CRC32X
strconv strconv (base-10 parse + ParseFloat) ParseInt/Atoi ~2.2–2.7×; added SIMD ParseFloat (~1.1–1.36×); never regresses
jsonvalidate encoding/json.Valid byte-identical verdict; only SIMD JSON validator on 6 arches; ~1.4× on string-heavy JSON (number/structure-heavy stays scalar)

Primitives

Package Accelerates Honest headline
matchlen LZ match-finder ~10× scalar (NEON); real SIMD on all 6 arches; native ppc64le POWER9 ~6.3×, riscv64 X60 ~5.8×, loong64 ~11.4×
bitpack FastPFOR / simdcomp ~21–32× scalar — byte-exact vs Lemire's simdcomp; native ppc64le POWER9 Pack ~7.0× / Unpack ~11.3×
popcount Hamming weight over []byte size-dependent: ~9–12× in-cache, memory-bound out-of-cache; native loong64 ~6.1×, ppc64le POWER9 ~2.9×
histogram byte-value histogram multi-table scalar — SIMD doesn't help (no scatter)
streamvbyte Stream VByte uint32 codec first Go port on all 6 arches; full codec — SIMD encode and decode, decode arm64 ~10×; native ppc64le POWER9 ~11.6×, riscv64 X60 ~4.5×, loong64 ~11.8×
xxhash XXH3-64 first Go XXH3 on all 6 arches, bit-exact; honest: zeebo faster on arm64 — but riscv64 RVV ~2.5–3.5× zeebo and ppc64le ~0.91× on real silicon (zeebo has no kernel there)
floats float32/64 reductions (vector search) only pure-Go full vector-search API on all 6 arches; arm64 ~2× scalar; native ppc64le POWER9 f32 ~1.55–1.61× (f64 routes to gc-autovectorized scalar — honest)
bitset bulk []uint64 set ops SIMD And/Or/AndNot/Xor + fused Count; amd64 Count ~3–3.9×; logical ops bandwidth-bound (honest)
int8dot int8 quantized dot (ML embeddings) bit-exact INT8 MAC; amd64 AVX2 ~4×; arm64 NEON on Go 1.27 (~2.4×, scalar below); native riscv64 X60 ~9.1× (biggest RVV win), loong64 ~8.9×, ppc64le POWER9 ~4.1×
levenshtein edit distance Myers bit-parallel, 62–142× vs agnivade; honest: pure-Go bit-parallel, not vector-SIMD

Five repos — ascii, levenshtein, bitset, int8dot and jsonvalidate — rounded the suite out to 20, and crc32 makes 21. jsonvalidate is the only SIMD JSON validator covering all six arches (byte-identical to encoding/json.Valid); levenshtein is honestly pure-Go bit-parallel, not vector-SIMD — its word-serial Myers column has no lane parallelism (documented) — yet still 62–142× vs agnivade; bitset and int8dot are vector primitives (int8dot's arm64 NEON kernel needs Go 1.27, scalar below); ascii runs real SIMD case-folding on arm64 too, via a multiply-free sign-bit predicate (~4.9× stdlib); and crc32 is the deliberate exception to the six-arch pattern — arm64-only, since stdlib already hardware-accelerates IEEE crc32 elsewhere. As elsewhere in the org, ppc64le, riscv64 and loong64 are now natively measured on real silicon (GCC Compile Farm — POWER9, SpacemiT X60 RVV 1.0, Loongson 3A5000); most repos are now natively measured on real IBM z15 (VXE2, 2026-07-03) — jsonvalidate and ascii85 are the two still pending a follow-up z15 run — see the per-repo pages for the vector-facility speedups.

Read the methodology for the check-existing → go-asmgen → llvm-mca → real-hardware → 100%-coverage pipeline every repo follows.

Source lives under github.com/go-simd. Assembly is generated by go-asmgen.