From 412aa2a80f015142936e1af884acf6a4c7752697 Mon Sep 17 00:00:00 2001 From: Baptiste Canton Date: Sat, 2 Jul 2022 16:59:02 +0200 Subject: [PATCH 1/5] fill CPUInfo on darwin arm64 --- os_darwin_arm64.go | 112 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 107 insertions(+), 5 deletions(-) diff --git a/os_darwin_arm64.go b/os_darwin_arm64.go index 8d2cb03..3a0a371 100644 --- a/os_darwin_arm64.go +++ b/os_darwin_arm64.go @@ -2,18 +2,120 @@ package cpuid -import "runtime" +import ( + "runtime" + "strings" + + "golang.org/x/sys/unix" +) func detectOS(c *CPUInfo) bool { + if runtime.GOOS != "ios" { + fillCPUInfo(c) + } // There are no hw.optional sysctl values for the below features on Mac OS 11.0 // to detect their supported state dynamically. Assume the CPU features that // Apple Silicon M1 supports to be available as a minimal set of features // to all Go programs running on darwin/arm64. // TODO: Add more if we know them. c.featureSet.setIf(runtime.GOOS != "ios", AESARM, PMULL, SHA1, SHA2) - c.PhysicalCores = runtime.NumCPU() - // For now assuming 1 thread per core... - c.ThreadsPerCore = 1 - c.LogicalCores = c.PhysicalCores + return true } + +func sysctlGetBool(name string) bool { + value, err := unix.SysctlUint32(name) + if err != nil { + return false + } + return value != 0 +} + +func sysctlGetString(name string) string { + value, err := unix.Sysctl(name) + if err != nil { + return "" + } + return value +} + +func sysctlGetInt(unknown int, names ...string) int { + for _, name := range names { + value, err := unix.SysctlUint32(name) + if err != nil { + continue + } + if value != 0 { + return int(value) + } + } + return unknown +} + +func sysctlGetInt64(unknown int, names ...string) int { + for _, name := range names { + value64, err := unix.SysctlUint64(name) + if err != nil { + continue + } + if int(value64) != unknown { + return int(value64) + } + } + return unknown +} + +func setFeature(c *CPUInfo, name string, feature FeatureID) { + c.featureSet.setIf(sysctlGetBool(name), feature) +} +func fillCPUInfo(c *CPUInfo) { + c.BrandName = sysctlGetString("machdep.cpu.brand_string") + + if len(c.BrandName) != 0 { + c.VendorString = strings.Fields(c.BrandName)[0] + } + + c.PhysicalCores = sysctlGetInt(0, "hw.physicalcpu") + c.ThreadsPerCore = sysctlGetInt(0, "machdep.cpu.thread_count", "kern.num_threads") / + sysctlGetInt(1, "hw.physicalcpu") + c.LogicalCores = sysctlGetInt(0, "machdep.cpu.core_count") + c.Family = sysctlGetInt(0, "machdep.cpu.family", "hw.cpufamily") + c.Model = sysctlGetInt(0, "machdep.cpu.model", "hw.cputype") + c.CacheLine = sysctlGetInt64(0, "hw.cachelinesize") + c.Cache.L1I = sysctlGetInt64(-1, "hw.l1icachesize") + c.Cache.L1D = sysctlGetInt64(-1, "hw.l1icachesize") + c.Cache.L2 = sysctlGetInt64(-1, "hw.l2cachesize") + c.Cache.L3 = sysctlGetInt64(-1, "hw.l3cachesize") + + // from https://developer.arm.com/downloads/-/exploration-tools/feature-names-for-a-profile + setFeature(c, "hw.optional.arm.FEAT_AES", AESARM) + setFeature(c, "hw.optional.AdvSIMD", ASIMD) + setFeature(c, "hw.optional.arm.FEAT_DotProd", ASIMDDP) + setFeature(c, "hw.optional.arm.FEAT_RDM", ASIMDRDM) + setFeature(c, "hw.optional.FEAT_CRC32", CRC32) + setFeature(c, "hw.optional.arm.FEAT_DPB", DCPOP) + // setFeature(c, "", EVTSTRM) + setFeature(c, "hw.optional.arm.FEAT_FCMA", FCMA) + setFeature(c, "hw.optional.arm.FEAT_FP", FP) + setFeature(c, "hw.optional.arm.FEAT_FP16", FPHP) + setFeature(c, "hw.optional.arm.FEAT_PAuth", GPA) + setFeature(c, "hw.optional.arm.FEAT_JSCVT", JSCVT) + setFeature(c, "hw.optional.arm.FEAT_LRCPC", LRCPC) + setFeature(c, "hw.optional.arm.FEAT_PMULL", PMULL) + setFeature(c, "hw.optional.arm.FEAT_SHA1", SHA1) + setFeature(c, "hw.optional.arm.FEAT_SHA256", SHA2) + setFeature(c, "hw.optional.arm.FEAT_SHA3", SHA3) + setFeature(c, "hw.optional.arm.FEAT_SHA512", SHA512) + // setFeature(c, "", SM3) + // setFeature(c, "", SM4) + setFeature(c, "hw.optional.arm.FEAT_SVE", SVE) + + // from empirical observation + setFeature(c, "hw.optional.AdvSIMD_HPFPCvt", ASIMDHP) + setFeature(c, "hw.optional.armv8_1_atomics", ATOMICS) + setFeature(c, "hw.optional.floatingpoint", FP) + setFeature(c, "hw.optional.armv8_2_sha3", SHA3) + setFeature(c, "hw.optional.armv8_2_sha3", SHA512) + setFeature(c, "hw.optional.armv8_3_compnum", FCMA) + setFeature(c, "hw.optional.armv8_crc32", CRC32) +} From 78ec393dc7a7532c79ee4e6e267b639dec7bf28c Mon Sep 17 00:00:00 2001 From: Baptiste Canton Date: Thu, 7 Jul 2022 12:15:14 +0200 Subject: [PATCH 2/5] Apple arm (#2) * add some cleanup * add x/sys/unix for sysctl() --- go.mod | 2 ++ os_darwin_arm64.go | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 3ad3f84..68f47a5 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module github.com/klauspost/cpuid/v2 go 1.15 + +require golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e diff --git a/os_darwin_arm64.go b/os_darwin_arm64.go index 3a0a371..72c0faf 100644 --- a/os_darwin_arm64.go +++ b/os_darwin_arm64.go @@ -11,7 +11,7 @@ import ( func detectOS(c *CPUInfo) bool { if runtime.GOOS != "ios" { - fillCPUInfo(c) + tryToFillCPUInfoFomSysctl(c) } // There are no hw.optional sysctl values for the below features on Mac OS 11.0 // to detect their supported state dynamically. Assume the CPU features that @@ -68,19 +68,19 @@ func sysctlGetInt64(unknown int, names ...string) int { func setFeature(c *CPUInfo, name string, feature FeatureID) { c.featureSet.setIf(sysctlGetBool(name), feature) } -func fillCPUInfo(c *CPUInfo) { +func tryToFillCPUInfoFomSysctl(c *CPUInfo) { c.BrandName = sysctlGetString("machdep.cpu.brand_string") if len(c.BrandName) != 0 { c.VendorString = strings.Fields(c.BrandName)[0] } - c.PhysicalCores = sysctlGetInt(0, "hw.physicalcpu") - c.ThreadsPerCore = sysctlGetInt(0, "machdep.cpu.thread_count", "kern.num_threads") / + c.PhysicalCores = sysctlGetInt(runtime.NumCPU(), "hw.physicalcpu") + c.ThreadsPerCore = sysctlGetInt(1, "machdep.cpu.thread_count", "kern.num_threads") / sysctlGetInt(1, "hw.physicalcpu") - c.LogicalCores = sysctlGetInt(0, "machdep.cpu.core_count") + c.LogicalCores = sysctlGetInt(runtime.NumCPU(), "machdep.cpu.core_count") c.Family = sysctlGetInt(0, "machdep.cpu.family", "hw.cpufamily") - c.Model = sysctlGetInt(0, "machdep.cpu.model", "hw.cputype") + c.Model = sysctlGetInt(0, "machdep.cpu.model") c.CacheLine = sysctlGetInt64(0, "hw.cachelinesize") c.Cache.L1I = sysctlGetInt64(-1, "hw.l1icachesize") c.Cache.L1D = sysctlGetInt64(-1, "hw.l1icachesize") From 300fcf5bdb25092081a6db6c19afbfe29f5290e6 Mon Sep 17 00:00:00 2001 From: Baptiste Canton Date: Thu, 7 Jul 2022 12:21:51 +0200 Subject: [PATCH 3/5] Apple arm (#3) * add some cleanup * add x/sys/unix for sysctl() * add 'hw.cputype' as Model From 0050ba2f4b3443b760083fa4a8c8ac5067830754 Mon Sep 17 00:00:00 2001 From: Baptiste Canton Date: Fri, 8 Jul 2022 20:21:17 +0200 Subject: [PATCH 4/5] add go.sum --- go.sum | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 go.sum diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..0ece415 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e h1:CsOuNlbOuf0mzxJIefr6Q4uAUetRUwZE4qt7VfzP+xo= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= From 1a4ea4da476f4e8e458f01a6f629a2cc89bc3027 Mon Sep 17 00:00:00 2001 From: Baptiste Canton Date: Fri, 8 Jul 2022 20:35:32 +0200 Subject: [PATCH 5/5] fix hw.optional.armv8_2_sha512 --- os_darwin_arm64.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/os_darwin_arm64.go b/os_darwin_arm64.go index 72c0faf..d91d021 100644 --- a/os_darwin_arm64.go +++ b/os_darwin_arm64.go @@ -115,7 +115,7 @@ func tryToFillCPUInfoFomSysctl(c *CPUInfo) { setFeature(c, "hw.optional.armv8_1_atomics", ATOMICS) setFeature(c, "hw.optional.floatingpoint", FP) setFeature(c, "hw.optional.armv8_2_sha3", SHA3) - setFeature(c, "hw.optional.armv8_2_sha3", SHA512) + setFeature(c, "hw.optional.armv8_2_sha512", SHA512) setFeature(c, "hw.optional.armv8_3_compnum", FCMA) setFeature(c, "hw.optional.armv8_crc32", CRC32) }