git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/cpuinfo/os_darwin_arm64.go (about)

     1  // Copyright (c) 2020 Klaus Post, released under MIT License. See LICENSE file.
     2  
     3  package cpuinfo
     4  
     5  import (
     6  	"runtime"
     7  	"strings"
     8  
     9  	"golang.org/x/sys/unix"
    10  )
    11  
    12  func detectOS(c *CPUInfo) bool {
    13  	if runtime.GOOS != "ios" {
    14  		tryToFillCPUInfoFomSysctl(c)
    15  	}
    16  	// There are no hw.optional sysctl values for the below features on Mac OS 11.0
    17  	// to detect their supported state dynamically. Assume the CPU features that
    18  	// Apple Silicon M1 supports to be available as a minimal set of features
    19  	// to all Go programs running on darwin/arm64.
    20  	// TODO: Add more if we know them.
    21  	c.featureSet.setIf(runtime.GOOS != "ios", AESARM, PMULL, SHA1, SHA2)
    22  
    23  	return true
    24  }
    25  
    26  func sysctlGetBool(name string) bool {
    27  	value, err := unix.SysctlUint32(name)
    28  	if err != nil {
    29  		return false
    30  	}
    31  	return value != 0
    32  }
    33  
    34  func sysctlGetString(name string) string {
    35  	value, err := unix.Sysctl(name)
    36  	if err != nil {
    37  		return ""
    38  	}
    39  	return value
    40  }
    41  
    42  func sysctlGetInt(unknown int, names ...string) int {
    43  	for _, name := range names {
    44  		value, err := unix.SysctlUint32(name)
    45  		if err != nil {
    46  			continue
    47  		}
    48  		if value != 0 {
    49  			return int(value)
    50  		}
    51  	}
    52  	return unknown
    53  }
    54  
    55  func sysctlGetInt64(unknown int, names ...string) int {
    56  	for _, name := range names {
    57  		value64, err := unix.SysctlUint64(name)
    58  		if err != nil {
    59  			continue
    60  		}
    61  		if int(value64) != unknown {
    62  			return int(value64)
    63  		}
    64  	}
    65  	return unknown
    66  }
    67  
    68  func setFeature(c *CPUInfo, name string, feature FeatureID) {
    69  	c.featureSet.setIf(sysctlGetBool(name), feature)
    70  }
    71  func tryToFillCPUInfoFomSysctl(c *CPUInfo) {
    72  	c.BrandName = sysctlGetString("machdep.cpu.brand_string")
    73  
    74  	if len(c.BrandName) != 0 {
    75  		c.VendorString = strings.Fields(c.BrandName)[0]
    76  	}
    77  
    78  	c.PhysicalCores = sysctlGetInt(runtime.NumCPU(), "hw.physicalcpu")
    79  	c.ThreadsPerCore = sysctlGetInt(1, "machdep.cpu.thread_count", "kern.num_threads") /
    80  		sysctlGetInt(1, "hw.physicalcpu")
    81  	c.LogicalCores = sysctlGetInt(runtime.NumCPU(), "machdep.cpu.core_count")
    82  	c.Family = sysctlGetInt(0, "machdep.cpu.family", "hw.cpufamily")
    83  	c.Model = sysctlGetInt(0, "machdep.cpu.model")
    84  	c.CacheLine = sysctlGetInt64(0, "hw.cachelinesize")
    85  	c.Cache.L1I = sysctlGetInt64(-1, "hw.l1icachesize")
    86  	c.Cache.L1D = sysctlGetInt64(-1, "hw.l1dcachesize")
    87  	c.Cache.L2 = sysctlGetInt64(-1, "hw.l2cachesize")
    88  	c.Cache.L3 = sysctlGetInt64(-1, "hw.l3cachesize")
    89  
    90  	// from https://developer.arm.com/downloads/-/exploration-tools/feature-names-for-a-profile
    91  	setFeature(c, "hw.optional.arm.FEAT_AES", AESARM)
    92  	setFeature(c, "hw.optional.AdvSIMD", ASIMD)
    93  	setFeature(c, "hw.optional.arm.FEAT_DotProd", ASIMDDP)
    94  	setFeature(c, "hw.optional.arm.FEAT_RDM", ASIMDRDM)
    95  	setFeature(c, "hw.optional.FEAT_CRC32", CRC32)
    96  	setFeature(c, "hw.optional.arm.FEAT_DPB", DCPOP)
    97  	// setFeature(c, "", EVTSTRM)
    98  	setFeature(c, "hw.optional.arm.FEAT_FCMA", FCMA)
    99  	setFeature(c, "hw.optional.arm.FEAT_FP", FP)
   100  	setFeature(c, "hw.optional.arm.FEAT_FP16", FPHP)
   101  	setFeature(c, "hw.optional.arm.FEAT_PAuth", GPA)
   102  	setFeature(c, "hw.optional.arm.FEAT_JSCVT", JSCVT)
   103  	setFeature(c, "hw.optional.arm.FEAT_LRCPC", LRCPC)
   104  	setFeature(c, "hw.optional.arm.FEAT_PMULL", PMULL)
   105  	setFeature(c, "hw.optional.arm.FEAT_SHA1", SHA1)
   106  	setFeature(c, "hw.optional.arm.FEAT_SHA256", SHA2)
   107  	setFeature(c, "hw.optional.arm.FEAT_SHA3", SHA3)
   108  	setFeature(c, "hw.optional.arm.FEAT_SHA512", SHA512)
   109  	// setFeature(c, "", SM3)
   110  	// setFeature(c, "", SM4)
   111  	setFeature(c, "hw.optional.arm.FEAT_SVE", SVE)
   112  
   113  	// from empirical observation
   114  	setFeature(c, "hw.optional.AdvSIMD_HPFPCvt", ASIMDHP)
   115  	setFeature(c, "hw.optional.armv8_1_atomics", ATOMICS)
   116  	setFeature(c, "hw.optional.floatingpoint", FP)
   117  	setFeature(c, "hw.optional.armv8_2_sha3", SHA3)
   118  	setFeature(c, "hw.optional.armv8_2_sha512", SHA512)
   119  	setFeature(c, "hw.optional.armv8_3_compnum", FCMA)
   120  	setFeature(c, "hw.optional.armv8_crc32", CRC32)
   121  }