go-simd

Pure-Go SIMD drop-ins for the standard library โ€” base64, base32, hex, ascii85, utf8, adler32, crc32, crc64, strconv and the primitives under them, with byte-identical output on plain go build.

CGO_ENABLED=0 go-asmgen-generated 6 architectures amd64 ยท arm64 ยท riscv64 ยท loong64 ยท ppc64le ยท s390x llvm-mca cycle-modelled 100% coverage honest benchmarks
Documentation GitHub

Each package is a drop-in: the same signatures and byte-identical output (and errors) as the stdlib package it accelerates. The hot loop is real SIMD assembly emitted by go-asmgen (v0.5.0) for all six 64-bit Go targets — amd64, arm64, riscv64, loong64, ppc64le (VSX) and s390x (vector facility, big-endian) — and encoded by cmd/asm; the short tail delegates back to the standard library so results match exactly. The numbers are measured and honest โ€” wins, parities, and the cases where SIMD genuinely does not help.

Six architectures, one generator. The amd64/arm64 throughput figures below are native measurements. Most repos are now measured on real IBM z15 (VXE2, native execution, 2026-07-03, -count=6) — the vector-facility kernels post clear wins (e.g. bitpack ~34×, streamvbyte decode ~20×, hex encode ~18×, matchlen ~9.2×, crc64 ~9.1×) and are bit-exact on big-endian (jsonvalidate and ascii85 still await a follow-up z15 run). ppc64le kernels are measured on real POWER9 where a GCC Compile Farm runner is available, otherwise qemu-validated for correctness. Two highlights: base32 gets real SIMD on ppc64le (VSRH) and s390x (VMLHH) precisely where Go's arm64 assembler lacks the register-variable shift and integer vector multiply it needs; and every kernel is byte-for-byte correct on big-endian s390x.

Beyond these six native targets, matchlen-wasm is a proof-of-concept 7th target — wasm-SIMD (v128) — callable from browsers and WASI hosts via //go:wasmimport, since the Go compiler does not emit v128 from Go source. It is a standalone companion repo, not one of the 21 packages below.

Repositories

base64 drop-in

encoding/base64

encode ~17ร— stdlib; beats emmansun/base64 ~5โ€“6% (cycle-model-guided).

CI coverage 100%

base32 drop-in

encoding/base32

encode ~7.9ร— stdlib (AVX2), now SIMD decode too + arm64 NEON encode on Go 1.27. Real SIMD on ppc64le VSRH + s390x VMLHH where arm64 can't; ppc64le now measured on real POWER9 (decode ~5.5ร—). No prior pure-Go SIMD base32.

CI coverage 100%

hex drop-in

encoding/hex

beats tmthrgd/go-hex both ways โ€” encode 20.4ร—, decode 6.24ร— stdlib.

CI coverage 100%

utf8 drop-in

unicode/utf8

Valid ~19ร— stdlib, edges stuartcarnie/go-simd ~3.5% (Lemire/Keiser).

CI coverage 100%

adler32 drop-in

hash/adler32

~12โ€“14ร— stdlib, but ~7% behind mhr3/adler32-simd โ€” near-parity, honest.

CI coverage 100%

strconv drop-in

strconv (base-10 parse + ParseFloat)

ParseInt/Atoi ~2.2โ€“2.7ร— on long inputs; added SIMD ParseFloat (Eisel-Lemire, ~1.1โ€“1.36ร—); never regresses (delegates short/uncertain).

CI coverage 100%

matchlen primitive

LZ match-finder primitive

~10ร— scalar (NEON); real SIMD on all 6 arches; AVX2 ~2.08ร— SSE2. Measured native: ppc64le POWER9 ~6.3ร—, riscv64 X60 ~5.8ร—, loong64 ~11.4ร— scalar.

CI coverage 100%

bitpack primitive

FastPFOR / simdcomp bit-packing

~21โ€“32ร— scalar โ€” byte-exact vs Lemire's simdcomp. ppc64le measured on real POWER9: Pack ~7.0ร—, Unpack ~11.3ร— (overturns the earlier ~1.1ร— llvm-mca estimate).

CI coverage 100%

popcount primitive

Hamming weight over []byte

size-dependent: ~9โ€“12ร— in-cache, converges to memory-bound out-of-cache. Measured native: loong64 LSX ~6.1ร—, ppc64le POWER9 ~2.9ร— scalar (riscv64 stays scalar โ€” no per-element vector popcount in Go's RVV asm).

CI coverage 100%

histogram primitive

byte-value histogram

multi-table scalar โ€” measured, SIMD does NOT help (no scatter on AVX2/NEON).

CI coverage 100%

crc64 drop-in

hash/crc64

first pure-Go SIMD crc64 (stdlib + all Go libs are scalar); CLMUL folding, arm64 ~4.2ร— stdlib; all 6 arches (riscv64/loong64 scalar).

CI coverage 100%

crc32 drop-in

hash/crc32

arm64-only, deliberately: stdlib IEEE path is already hardware-assisted on amd64/ppc64le/s390x, so only arm64's serial CRC32X fallback is worth beating; PMULL/PMULL2 fold-by-eight does that, every other arch and non-IEEE polynomial just calls hash/crc32.

CI coverage 100%

ascii85 drop-in

encoding/ascii85

first SIMD ascii85, SIMD encode AND decode; real SIMD on all 6 arches incl. an arm64 NEON kernel on Go 1.27. Measured native: ppc64le POWER9 ~2.9ร— encode, riscv64 X60 ~4.0ร—, loong64 ~4.3ร—; arm64 NEON ~3.0ร— / fused-scalar ~1.9ร— on stable Go.

CI coverage 100%

floats primitive

Dot/Sum/Min/Max/Distance/CosineSimilarity (float32 + float64)

only pure-Go lib with the full vector-search API on all 6 arches (gonum/vek/kelindar are amd64-centric or partial); arm64 ~2ร— scalar. ppc64le measured on real POWER9: f32 VSX kernel ~1.55โ€“1.61ร— over naive, f64 routes to the gc-autovectorized scalar loop (it beats VSX there โ€” honest).

CI coverage 100%

xxhash primitive

XXH3-64

first Go XXH3 on all 6 SIMD arches, bit-exact vs official vectors. Honest: zeebo faster on arm64 (~22 vs ~15 GB/s), amd64 block-at-a-time kernel reaches ~0.94ร— zeebo. Where zeebo has no kernel we win big: riscv64 RVV ~2.5โ€“3.5ร— zeebo on real X60 silicon; ppc64le near-parity (~0.91ร—) on real POWER9.

CI coverage 100%

streamvbyte primitive

Stream VByte uint32 codec

first Go port on all 6 arches (others amd64-only); full codec โ€” SIMD encode and decode, byte-identical to lemire/streamvbyte; decode arm64 ~10ร— scalar. Measured native: ppc64le POWER9 decode ~11.6ร—, riscv64 X60 ~4.5ร—, loong64 ~11.8ร— scalar.

CI coverage 100%

ascii drop-in

ASCII case (ToUpper/ToLower/EqualFold)

branchless vector case-fold, byte-identical to bytes/strings; real SIMD on all 6 arches incl. arm64 (multiply-free sign-bit predicate); arm64 ~4.9ร— stdlib (ToUpper).

CI coverage 100%

levenshtein primitive

edit distance (Distance)

Myers bit-parallel edit distance, 62โ€“142ร— vs agnivade/levenshtein on long inputs. Honest: pure-Go bit-parallel, not vector-SIMD (word-serial column, no lane parallelism); endian-clean on all 6 arches.

CI coverage 100%

bitset primitive

bulk []uint64 set ops

SIMD And/Or/AndNot/Xor + fused Count/IntersectionCount; amd64 Count ~3โ€“3.9ร—. Honest: logical ops are bandwidth-bound (converge to scalar out-of-cache), popcount wins across the board.

CI coverage 100%

int8dot primitive

int8 quantized dot (Dot/DotUint8/DotU8S8)

INT8 multiply-accumulate for ML embeddings, bit-exact vs scalar; amd64 AVX2 ~4ร—; arm64 NEON kernel on Go 1.27 (~2.4ร—; scalar on stable Go โ‰ค 1.26). Measured native: riscv64 X60 ~9.1ร— (biggest RVV win in the suite), loong64 ~8.9ร— (DotUint8 ~13.8ร—), ppc64le POWER9 ~4.1ร—.

CI coverage 100%

jsonvalidate drop-in

encoding/json.Valid

byte-identical verdict to encoding/json.Valid; only SIMD JSON validator on all 6 arches (simdjson-go is amd64-only); SIMD string/space scans, ~1.4ร— on string-heavy JSON (number-/structure-heavy stays scalar). Measured native on string-heavy: ppc64le POWER9 ~8.5ร— stdlib, riscv64 X60 ~5.2ร—.

CI coverage 100%

Every kernel is generated by go-asmgen (v0.5.0) over a shared ABI0 layout (amd64 SSE2/AVX2, arm64 NEON, loong64 LSX/LASX, riscv64 RVV, ppc64le VSX, s390x vector facility), cycle-modelled with llvm-mca, validated on real AVX2 / native arm64 / QEMU riscv64+loong64+ppc64le+s390x, and held at 100% statement coverage as a CI gate. The headline benchmarks come from native CI; s390x is measured on real IBM z15 (VXE2, 2026-07-03) and ppc64le on real POWER9 where a GCC Compile Farm runner is available.