Skip to content

v0.1.2: NEON kernel for arm64, AVX fix, faster loops

Latest

Choose a tag to compare

@go-while go-while released this 23 Oct 02:17
· 3 commits to main since this release
  • Fix: crash on CPUs with AVX but not AVX2 (Intel Sandy Bridge and Ivy Bridge; AMD Bulldozer, Piledriver, Steamroller and Jaguar). With GOEXPERIMENT=simd, the AVX kernel in v0.1.0 and v0.1.1 used an AVX2 instruction (VPBROADCASTB), so decoding died with SIGILL on these CPUs. A new test, TestKernelISA, disassembles every kernel and checks each instruction against the CPU features that the kernel's run-time check requires.
  • NEON kernel for arm64 with GOEXPERIMENT=simd, 64 bytes per step. On GitHub's runners, random data decodes at 6.0–8.0 GB/s on Apple M1 (plain Go: 1.9–2.7 GB/s) and 5.4 GB/s on Neoverse N2 (plain Go: 2.6–2.7 GB/s). The README has the full table.
  • Faster AVX2, AVX and plain Go loops. The Go compiler had left a NOP in the hot loops for each inlined helper call. Without them, in CPU cycles per byte on an AMD EPYC 9B45: AVX2 −17.5% on data that needs no escapes and about −7% on random data; AVX −7% on data that needs no escapes and −10% with an escape in every second byte; plain Go −7% on random data and −9% on data that needs no escapes. The AVX-512 kernel is unchanged.
  • Plain Go on other CPUs: the 16-bytes-per-step loop now loads and stores 8-byte words directly, so it runs only where unaligned little-endian access is fast (amd64, arm64, 386, ppc64le, wasm). On riscv64, mips, 32-bit arm and big-endian CPUs the plain Go decoder now goes a byte at a time (likely slower there than v0.1.1; not measured).
  • yencbench prints the CPU name on arm64 Linux, macOS, the BSDs and Windows, not only on x86 Linux:
    GOEXPERIMENT=simd go run github.com/go-while/go-yenc-simd/cmd/yencbench@v0.1.2
  • Tests: TestBoundaries puts every string of up to four special bytes at every offset of plain data (about 2.8 million inputs per kernel) and compares each kernel with the state machine. The plain Go decoder is now compared with the byte-by-byte state machine instead of with itself. CI tests the NEON kernel on GitHub's arm64 runners (macOS and Linux), with a 60-second fuzz run and the race detector.

Full changes: v0.1.1...v0.1.2