网页 综合 更新时间 2026-11-14 05:16:30

Arch-specific SIMD in Go - The Go Programming Language

自动蜘蛛 go.dev 正文约 6000 字
Common problems companies solve with Go
Stories about how and why companies use Go
How Go can help keep you secure by default
The official Go language specification
A complete introduction to building software with Go
Reference documentation for Go's standard library
Learn what's new in each Go release
Tips for writing clear, performant, and idiomatic Go code
Videos from prior events
Meet other local Go developers
Learn and network with Go developers from around the world
The Go project's official blog.
Get help and stay informed from Go
Junyang Shao and David Chase 2 October 2026
Since Go 1.26, we have supported an experimental amd64 SIMD API. Now in Go 1.27, we support two more architectures: arm64 and wasm.
The new APIs can be accessed by setting GOEXPERIMENT=simd when building a program. They are defined in the simd/archsimd package.
archsimd is the lower-level infrastructure that simd builds on, essentially the intrinsics layer in other languages. For exotic operations that only exist on a specific architecture, users can access them by transitioning from simd to archsimd (via ToArch and <Types>FromArch). For details, please refer to the simd blog post.
For readers with prior knowledge of SIMD intrinsics in other languages, you might find that our archsimd API does not directly mirror the underlying hardware instructions:
These design decisions make our APIs smaller and more accessible, and they also happily make the simd implementation much easier.
For readers without prior knowledge of SIMD intrinsics, we hope our low-level API is a natural and pleasant journey for you.
Please share your feedback and comments. Anything about usability, performance, etc., is appreciated. The parent issue for this project is #73787.
SIMD stands for Single Instruction, Multiple Data. SIMD instructions operate on wide registers (128-bit, 256-bit, or more) containing multiple 8- to 64-bit elements, performing operations across all elements in parallel. Wider registers and parallel execution provide a significant performance boost to algorithms that can take advantage of them.
Until now, anyone who wanted to use SIMD in Go had to endure the friction of writing assembly language. The new archsimd package is here to change that.
The goal is to support as many SIMD instructions across different architectures as possible. Currently, we have amd64, arm64, and wasm available. Our amd64 support has the largest API surface, covering AVX, AVX2, and many AVX-512 extensions. Our arm64 support currently covers NEON, with SVE and some SVE2 already on the way. Our wasm support is also mostly complete, thanks to its well-defined 128-bit SIMD abstraction.
Some users might be interested in matrix extensions on certain architectures, such as AMX and SME. We haven’t fully settled on how to represent matrices effectively in Go, so they are not yet supported, but we might support them in the future.
The architecture-specific SIMD API is imported from simd/archsimd. archsimd uses distinct struct types, such as Float32x4, Int32x8, or Uint8x16, to signal the shape and element type of each vector, and defines operations as methods on those types. At this moment, archsimd supports only fixed-width vector extensions. Scalable vector extensions like arm64 SVE and RVV will have different struct types to represent vectors. Mask types also come with vector-like shapes, e.g., Mask32x4.
Across different vector widths, element types, and architectures, we use the same method name whenever operations are semantically identical:
Methods require a receiver value, which doesn’t work for creating a vector from memory or a scalar. For those, archsimd provides package-level functions named with the target vector type:
Reinterpretations are type casts without any cost. SIMD algorithms frequently reinterpret bits across element types and widths.
In the Go 1.26 experiment, we implemented this with As<Type> methods, which suffered from a quadratic explosion of type pairs and couldn’t generalize to width-agnostic vectors in simd or SVE.
In Go 1.27, we replace them with composable zero-cost conversions:
Different architectures encode vector masks very differently, e.g. k mask registers on AVX-512, full vector bitmasks on AVX/AVX2, NEON, and wasm, and predicate registers on SVE. To hide this hardware detail, archsimd provides opaque Mask types (such as Mask32x4) matching each vector shape:
Portable algorithms like inner product can easily be implemented using the portable simd package, as shown in the companion simd blog post. However, we still expose archsimd to tap into exotic, architecture-specific instructions that do not fit into a portable intersection API, or instructions that can simply do things faster than what simd provides.
On amd64, the GFNI extension exposes GaloisFieldAffineTransform operations. Putting aside what a Galois Field is, these operations do a simple thing:
Each 8x8 bit matrix A is packed row-by-row into a single uint64. Because any linear combination or permutation of the 8 bits within a byte can be written as an 8x8 bit matrix, this single instruction is a Swiss Army knife for byte-level bit manipulation.
For example, reversing the bit order of every byte (bits.Reverse8) normally requires nibble lookup tables, masks, shifts, and ORs in SIMD. With GaloisFieldAffineTransform, we can simply multiply each byte by the 8x8 anti-diagonal identity matrix (0x8040201008040201) to reverse all 8 bits of 64 bytes at a time in a single instruction:
Another example is matrix transpose. On amd64, the permutation instructions are shaped in a non-portable way, so using simd is cumbersome and might incur emulations. An efficient implementation can be written more directly in archsimd. The example below transposes an 8-by-8 matrix of 32-bit integers in registers on amd64 using AVX2’s 128-bit lane-grouped interleaves (InterleaveLoGrouped, InterleaveHiGrouped) and cross-lane permutations (ConcatPermuteScalarsGrouped, ConcatPermute128Scalars):
W
访问原文 返回搜索 https://go.dev/blog/archsimd
本页为82搜索生成的网页快照,内容来自站内索引;演示数据的原文链接仅作示例。