Go 1.27 SIMD benchmarks against NumPy cache performance
Go 1.27's new experimental SIMD package ties with NumPy outside cache bounds, but trails when data fits into L3 cache.

Stock photo for illustration only, not from the actual event
- Go 1.27 introduces an experimental SIMD package in standard library.
- Performance comparison against NumPy depends on cache, not language.
- Both implementations tie when data size exceeds cache capacity.
- Strict core pinning and thread control are vital for accurate benchmarks.
Go version 1.27 has shipped with a brand-new experimental SIMD package nestled behind a flag in its standard library. While most write-ups have focused solely on exploring the API surface, few have explored the exact conditions under which it actually accelerates workloads. To find out, a developer benchmarked it directly against NumPy using a practical task: a speaker-search index containing 346,000 vectors of 192 dimensions, executing 66 million multiplications per query.
As it turned out, the underlying performance story had very little to do with Go or NumPy specifically. At 253 megabytes, the dataset exceeds any cache capacity, forcing both programs to spend the vast majority of their runtime waiting on memory access. Once applications hit this memory wall, raw code quality takes a back seat. A modest twenty-line portable package managed to match hand-tuned assembly optimized across microarchitectures over many years.

Stock photo for illustration only, not from the actual event
The dynamic shifts entirely when the dataset shrinks to 31 megabytes, allowing the data to reside comfortably within the L3 cache. Here, the primary bottleneck pivots back to pure arithmetic, enabling OpenBLAS to leverage years of dedicated micro-optimizations immediately. Ultimately, the deciding factor is not the choice of programming language, but rather whether your working dataset fits inside the CPU cache.
From a computer architecture perspective, L3 cache plays a critical role in mitigating the latency penalty of fetching data from main system memory. Optimizing software for cache locality allows execution units to process instructions continuously without stalling for memory transactions. When memory bandwidth becomes the primary bottleneck, language-level execution differences diminish significantly.
Achieving reliable benchmark results required careful iteration. Initial runs showed NumPy doubling Go's speed because OpenBLAS implicitly distributed work across all available cores while the Go application ran single-threaded. Setting environment variables to restrict thread counts and implementing strict core pinning via taskset were necessary to eliminate background interference and hardware-level noise.
Source: Dev.to
Found something wrong in this article? Report an issue with this article
Comments
Leave a Comment