logo
Kurashizu Blogwhere ideas flow
  • Home
  • News
  • Blog
  • About
  • Home
  • News
  • Blog
  • About

© 2026 Kurashizu. All rights reserved.

Admin·New Post·Service Status
Powered by Cloudflare·01.11.26
← Back to news

Platform-Independent SIMD in Go

Original article
go.dev|247 points|88 comments|by yurivish|Sep 25, 2026

Platform-Independent SIMD in Go

By David Chase and Junyang Shao Originally published: 24 September 2026

With the release of Go 1.26 and Go 1.27, the language introduces experimental APIs designed for Single Instruction Multiple Data (SIMD) operations.

What is SIMD?

SIMD is a hardware capability found in most modern CPUs that enables a single instruction to perform the same operation across a vector of data simultaneously. For instance, instead of adding two numbers, a CPU can add 8 pairs of float64 values in one go.

Mathematically, if we have two vectors A⃗\vec{A}A and B⃗\vec{B}B, SIMD allows us to compute: C⃗=A⃗+B⃗\vec{C} = \vec{A} + \vec{B}C=A+B where each element Ci=Ai+BiC_i = A_i + B_iCi​=Ai​+Bi​ is processed in parallel.

This provides a massive performance boost for computationally heavy workloads, including:

  • AI and Machine Learning
  • Data Processing
  • Cryptography

Interestingly, Go's own Green Tea garbage collector utilizes SIMD to speed up the process of scanning memory for live objects.


The Evolution of SIMD in Go

Historically, accessing SIMD power required writing Go assembly. While effective, this was only feasible for the most critical performance kernels. Consequently, many applications that could have benefited from vectorization simply left CPU resources untapped.

The rollout of new APIs happened in stages:

  1. Go 1.26: Introduced the archsimd API for amd64.
  2. Go 1.27: Expanded archsimd to include arm64 (NEON) and wasm.

The Architecture Gap

The primary hurdle for a universal SIMD API is the extreme diversity of hardware. Platforms differ not just in what they can do, but in how they represent data.

To provide raw access to these differences, Go uses the architecture-specific archsimd package. However, Go 1.27 introduces a higher-level, platform-agnostic simd interface (inspired by the Highway library for C++).

The Goal: Enable "write-once" code that achieves near-assembly performance on supported hardware, while providing a functional emulation for platforms that lack SIMD support.

Currently, the simd package supports:

  • amd64: AVX, AVX2, and AVX512
  • arm64: NEON
  • wasm: SIMD instructions

The Challenge: Hardware Fragmentation

SIMD architectures vary across several critical dimensions:

1. Vector Size

Vector lengths are not standardized across the industry.

ArchitectureVector Size CharacteristicsExamples
Fixed (Single)Always 128 bitswasm, PowerPC, s390x
Fixed (Multiple)Multiple options (128, 256, 512)amd64, loong64
VariableUnspecified (128 to 65536 bits)riscv64
HybridFixed (128) AND Variable (128-2048)arm64 (NEON & SVE)

2. Vector Masking

Masking allows "if-then-else" logic within a vector. If a mask is "true" for an element, the operation is applied; otherwise, it is ignored.

  • Bitmasking: No special registers; uses boolean vector operations (wasm, AVX, AVX2, NEON).
  • Dedicated Registers: Specific mask registers where one bit controls one element (AVX512, RVV).
  • Byte-based: One bit per byte, with the LSB controlling the operation (SVE).
  • Hybrid: AVX2 uses standard vectors as masks for loads/stores (using the MSB).

3. Other Discrepancies

  • Rearrangement: Primitives for shuffling elements vary between constant and variable inputs.
  • Crypto: Support for specialized cryptographic instructions differs by chip.
  • Basic Math: Some platforms lack basic features (e.g., wasm cannot compare 64-bit integer vectors).

Because of these "quirks," the archsimd package—while uniform—still requires developers to handle platform-specific edge cases, making multiplatform development tedious.


The simd Package Overview

The new simd package solves these issues by:

  • Removing fixed-size vectors from the type system.
  • Supporting only the intersection of features available across all platforms.
  • Using efficient emulation to fill the gaps where a platform lacks a specific instruction.

This ensures that code is easy to read, maintainable, and potentially writable by LLMs, without sacrificing the efficiency of the underlying hardware.

Usage and Implementation

To enable this experimental feature, build your program with: GOEXPERIMENT=simd

Vector types are represented as capitalized, pluralized versions of primitive types (e.g., simd.Uint8s, simd.Float32s).

Example: Calculating an Inner Product

// innerProduct computes the dot product of two float32 slices.
func innerProduct(x, y []float32) float32 {
    var a simd.Float32s
    var i int
    
    // Process main chunks of the slices
    for i = 0; i <= len(x)-a.Len(); i += a.Len() {
        u := simd.LoadFloat32s(x[i : i+a.Len()])
        v := simd.LoadFloat32s(y[i : i+a.Len()])
        a = u.MulAdd(v, a)
    }
    
    // Handle remaining elements (the tail)
    if i < len(x) {
        u, _ := simd.LoadFloat32sPart(x[i:])
        v, _ := simd.LoadFloat32sPart(y[i:])
        a = u.MulAdd(v, a)
    }
    
    return sum(a)
}

SIMD Concept Conceptual representation of vector loading and multiplication.