// Copyright 2025 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.//go:build 386 || amd64package cpu// DataCacheSizes returns the size of each data cache from lowest// level in the hierarchy to highest.//// Unlike other parts of this package's public API, it is not safe// to reference early in runtime initialization because it allocates.// It's intended for testing only.func () []uintptr { , , , := cpuid(0, 0)if < 1 {returnnil }switch {// Check for "GenuineIntel"case == 0x756E6547 && == 0x6C65746E && == 0x49656E69:returngetDataCacheSizesIntel()// Check for "AuthenticAMD"case == 0x68747541 && == 0x444D4163 && == 0x69746E65:returngetDataCacheSizesAMD() }returnnil}func extractBits( uint32, int, int) uint32 {if > {panic("bad bit range") }return ( >> ) & ((1 << ( - + 1)) - 1)}func getDataCacheSizesIntel( uint32) []uintptr {// Constants for cache typesconst ( = 0 = 1 = 2 = 3 )if < 4 {returnnil }// Iterate through CPUID leaf 4 (deterministic cache parameters)var []uintptrfor := uint32(0); < 0xFFFF; ++ { , , , := cpuid(4, ) := & 0xF// EAX bits 4-0: Cache Typeif == 0 {break }// Report only data caches.if !( == || == ) {continue }// Guaranteed to always start counting from 1. := ( >> 5) & 0x7 := extractBits(, 0, 11) + 1// Bits 11-0: Line size in bytes - 1 := extractBits(, 12, 21) + 1// Bits 21-12: Physical line partitions - 1 := extractBits(, 22, 31) + 1// Bits 31-22: Ways of associativity - 1 := uint64() + 1// Number of sets - 1 := uint64(**) * // Calculate cache size in bytes = append(, uintptr())// If we see more than one cache described per level, or they appear // out of order, crash. // // Going by the SDM, it's not clear whether this is actually possible, // so this code is purely defensive.if != uint32(len()) {panic("expected levels to be in order and for there to be one data/unified cache per level") } }return}func getDataCacheSizesAMD() []uintptr { , , , := cpuid(0x80000000, 0)if < 0x80000006 {returnnil }var []uintptr , , , := cpuid(0x80000005, 0) , , , := cpuid(0x80000006, 0)// The size is return in kb, turning into bytes. := uintptr(extractBits(, 24, 31) << 10) = append(, )// Check that L2 cache is present.if := extractBits(, 12, 15); == 0 {return } := uintptr(extractBits(, 16, 31) << 10) = append(, )// Check that L3 cache is present.if := extractBits(, 12, 15); == 0 {return }// Specifies the L3 cache size is within the following range: // (L3Size[31:18] * 512KB) <= L3 cache size < ((L3Size[31:18]+1) * 512KB). := uintptr(extractBits(, 18, 31) * (512 << 10)) = append(, )return}
The pages are generated with Goldsv0.8.3-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.