cpuid

Detects CPU features and topology across x86, ARM64, and RISC-V64 without cgo, giving Go programs fast, cached access to hardware capabilities.

Library
Go
vv2.4.0
1,220stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
64/100Good
Development Activity44
Maintenance52
Community72
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
83/100Excellent
Architecture82
Code Quality85
Innovation84
Learning Curve80

cpuid is a pure-Go library that identifies the CPU features available on the machine a program is running on. It detects instruction-set extensions (AVX-512, AES-NI, SHA, AMX, and dozens more), microarchitecture levels (x86-64-v2/v3/v4), SGX and AMD memory-encryption support, and hypervisor identity, then exposes the results through a single cached cpuid.CPU variable so the check only happens once at startup.

The package spans x86/amd64, ARM64, and RISC-V64 without any cgo dependency, and ships a companion topology package that models a system’s cores, cache hierarchy, and package/group/core/thread layout — useful for pinning goroutines or sizing cache-aware algorithms. A standalone cpuid CLI binary and a Flags() helper for wiring detection into flag.Parse() round out the toolkit.

What You Get

  • Cached feature detection - CPU features are probed once at process start and stored on the shared cpuid.CPU value for zero-cost repeated checks.
  • Cross-architecture support - Works on x86/amd64, ARM64 (including Apple Silicon and Linux/FreeBSD), and RISC-V64 with architecture-specific detection paths.
  • Topology package - A separate topology package models System → Package → Group → Core → Thread layout with per-level cache attribution.
  • Command-line tool - go install github.com/klauspost/cpuid/v2/cmd/cpuid@latest gives a standalone binary with human-readable and JSON output plus microarchitecture-level checks.
  • Safe fallback modes - A noasm build tag and OS-specific safe/unsafe ARM64 detection paths let you trade off detection completeness for portability.

Common Use Cases

  • Dispatching to SIMD code paths - Libraries pick AVX2/AVX-512/NEON-optimized routines at runtime instead of shipping separate binaries per CPU.
  • Feature-gating in CLIs and servers - Applications call cpuid.CPU.Supports() at startup to warn or fall back when running on hardware that lacks required instructions.
  • Cache-aware scheduling - Programs use the topology package to group goroutines by shared L3 cache or physical core for NUMA/cache-locality tuning.
  • Cloud/VM detection - Services check HypervisorVendorID to adapt behavior when running under KVM, Hyper-V, VMware, or Xen.

Under The Hood

Architecture Detection is split into build-tag-gated files per architecture — detect_x86.go wires up assembly-backed asmCpuid/asmCpuidex/asmXgetbv calls (defined in cpuid_386.s/cpuid_amd64.s), detect_arm64.go (with cpuid_arm64.s) handles ARM64, detect_riscv64.go covers RISC-V, and detect_ref.go/detect_ref_arm64.go provide a pure-Go fallback for unsupported combinations — all converging on a single addInfo() call that populates one CPUInfo struct at init. OS-specific files (os_darwin_arm64.go, os_linux_arm64.go, os_safe_linux_arm64.go vs os_unsafe_linux_arm64.go) split ARM64 feature interception into safe (signal-handler-based) and unsafe variants. The topology package is intentionally one-directional: it defines its own System→Package→Group→Core→Thread hierarchy and is populated by the cpuid package, but has no dependency back on it — a clean layered design that keeps the CPUID-parsing internals separate from the public topology model.

Tech Stack A pure Go module (go 1.24, package path github.com/klauspost/cpuid/v2) with a single external dependency, golang.org/x/sys v0.41.0. Low-level CPUID/XGETBV opcodes are implemented in hand-written Go assembly (.s files) for 386/amd64/arm64 rather than cgo, keeping the library cgo-free and cross-compilable. Build tags select the amd64/386, arm64, riscv64, or generic-fallback code path at compile time. A goreleaser config cross-builds the cmd/cpuid CLI (built on the standard flag package) into release binaries, and a Homebrew formula distributes it as a standalone tool.

Code Quality Tests live in cpuid_test.go (22 test functions), topology/topology_test.go plus topology/example_test.go, and os_darwin_test.go. mockcpu_test.go supplies synthetic CPUID leaf responses so vendor/family/feature-parsing logic can be exercised deterministically without needing the actual hardware being tested. CI (.github/workflows/go.yml) runs a matrix across three Go versions and four OS/arch combinations, executing go vet, go test ./..., and a noasm-tagged test pass, plus a dedicated job that fails on any gofmt or go fix diff and cross-compiles a GOOS=linux GOARCH=386 build. No third-party test framework is used — the stdlib testing package is sufficient for the surface area.

API Design The single package-level cpuid.CPU value keeps call sites to one line (CPU.Supports(...) or the compiler-inlinable CPU.Has(...)) without callers managing detection state themselves. FeatureID constants are self-documenting and stringer-generated (go:generate stringer), and Flags()/Detect() are deliberately split so consumers can register CPU-related command-line overrides before their own flag.Parse() runs. The topology package mirrors real hardware structure (System→Package→Group→Core→Thread with per-level cache attribution) instead of exposing a flat core count, giving cache-aware code a model that matches how CPUs are actually built.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search