From 5173aaf292d9a9819210e1742d5eb82dd4bb524a Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Wed, 22 Oct 2025 15:09:30 -0700 Subject: [PATCH] recognize DMR, refactor to handle multiple Intel families Signed-off-by: Harper, Jason M --- cmd/config/config.go | 3 +- cmd/config/set.go | 57 ++--- cmd/metrics/metadata.go | 25 ++- cmd/metrics/metrics.go | 5 +- cmd/metrics/summary.go | 3 +- internal/common/targets.go | 5 +- internal/{report => cpus}/cpu_defs.go | 128 +++++++---- internal/{report => cpus}/cpu_defs_test.go | 12 +- internal/report/table.go | 20 +- internal/report/table_defs.go | 86 ++++--- internal/report/table_helpers.go | 19 +- internal/report/table_helpers_cache.go | 3 +- internal/script/script.go | 20 +- internal/script/script_defs.go | 248 +++++++++------------ 14 files changed, 321 insertions(+), 313 deletions(-) rename internal/{report => cpus}/cpu_defs.go (53%) rename internal/{report => cpus}/cpu_defs_test.go (92%) diff --git a/cmd/config/config.go b/cmd/config/config.go index 3545badb..b304b550 100644 --- a/cmd/config/config.go +++ b/cmd/config/config.go @@ -9,6 +9,7 @@ import ( "log/slog" "os" "perfspect/internal/common" + "perfspect/internal/cpus" "perfspect/internal/progress" "perfspect/internal/report" "perfspect/internal/script" @@ -158,7 +159,7 @@ func prepareTarget(myTarget target.Target, localTempDir string) (err error) { Name: "prepare-target", ScriptTemplate: "exit 0", Superuser: true, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, Depends: []string{"wrmsr", "rdmsr"}, Lkms: []string{"msr"}, } diff --git a/cmd/config/set.go b/cmd/config/set.go index fb74ef1d..8324d8d1 100644 --- a/cmd/config/set.go +++ b/cmd/config/set.go @@ -4,6 +4,7 @@ import ( "fmt" "log/slog" "math" + "perfspect/internal/cpus" "perfspect/internal/report" "perfspect/internal/script" "perfspect/internal/target" @@ -132,7 +133,7 @@ func setLlcSize(desiredLlcSize float64, myTarget target.Target, localTempDir str } uarch := report.UarchFromOutput(outputs) - cpu, err := report.GetCPUByMicroArchitecture(uarch) + cpu, err := cpus.GetCPUByMicroArchitecture(uarch) if err != nil { completeChannel <- setOutput{goRoutineID: goRoutineId, err: fmt.Errorf("failed to get CPU by microarchitecture: %w", err)} return @@ -176,7 +177,7 @@ func setLlcSize(desiredLlcSize float64, myTarget target.Target, localTempDir str Name: "set LLC size", ScriptTemplate: fmt.Sprintf("wrmsr -a 0xC90 %d", msrVal), Superuser: true, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, // Depends: []string{"wrmsr"}, // Lkms: []string{"msr"}, } @@ -203,7 +204,7 @@ func setCoreFrequency(coreFrequency float64, myTarget target.Target, localTempDi completeChannel <- setOutput{goRoutineID: goRoutineId, err: fmt.Errorf("failed to get target vendor: %w", err)} return } - if targetVendor != "GenuineIntel" { + if targetVendor != cpus.IntelVendor { completeChannel <- setOutput{goRoutineID: goRoutineId, err: fmt.Errorf("core frequency setting not supported on %s due to vendor mismatch", myTarget.GetName())} return } @@ -214,7 +215,7 @@ func setCoreFrequency(coreFrequency float64, myTarget target.Target, localTempDi getScript := script.ScriptDefinition{ Name: "get pstate driver", ScriptTemplate: "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver", - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, } output, err := runScript(myTarget, getScript, localTempDir) if err != nil { @@ -231,7 +232,7 @@ func setCoreFrequency(coreFrequency float64, myTarget target.Target, localTempDi Name: "set frequency bins", ScriptTemplate: fmt.Sprintf("wrmsr 0x774 %d", value), Superuser: true, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, // Depends: []string{"wrmsr"}, // Lkms: []string{"msr"}, } @@ -241,7 +242,7 @@ func setCoreFrequency(coreFrequency float64, myTarget target.Target, localTempDi Name: "set frequency bins", ScriptTemplate: fmt.Sprintf("wrmsr 0x199 %d", value), Superuser: true, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, // Depends: []string{"wrmsr"}, // Lkms: []string{"msr"}, } @@ -256,7 +257,7 @@ func setCoreFrequency(coreFrequency float64, myTarget target.Target, localTempDi Name: "set frequency bins", ScriptTemplate: fmt.Sprintf("wrmsr -a 0x1AD %d", value), Superuser: true, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, // Depends: []string{"wrmsr"}, // Lkms: []string{"msr"}, } @@ -326,7 +327,7 @@ func setUncoreDieFrequency(maxFreq bool, computeDie bool, uncoreFrequency float6 setScript := script.ScriptDefinition{ Name: "write max and min uncore frequency TPMI", ScriptTemplate: fmt.Sprintf("pcm-tpmi 2 0x18 -d -b %s -w %d -i %s -e %s", bits, value, die.instance, die.entry), - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, Depends: []string{"pcm-tpmi"}, Superuser: true, } @@ -348,7 +349,7 @@ func setUncoreFrequency(maxFreq bool, uncoreFrequency float64, myTarget target.T scripts = append(scripts, script.ScriptDefinition{ Name: "get uncore frequency MSR", ScriptTemplate: "rdmsr 0x620", - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, Superuser: true, // Depends: []string{"rdmsr"}, // Lkms: []string{"msr"}, @@ -394,7 +395,7 @@ func setUncoreFrequency(maxFreq bool, uncoreFrequency float64, myTarget target.T Name: "set uncore frequency MSR", ScriptTemplate: fmt.Sprintf("wrmsr -a 0x620 %d", newVal), Superuser: true, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, // Depends: []string{"wrmsr"}, // Lkms: []string{"msr"}, } @@ -410,7 +411,7 @@ func setTDP(power int, myTarget target.Target, localTempDir string, completeChan Name: "get power MSR", ScriptTemplate: "rdmsr 0x610", Superuser: true, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, // Lkms: []string{"msr"}, // Depends: []string{"rdmsr"}, } @@ -433,7 +434,7 @@ func setTDP(power int, myTarget target.Target, localTempDir string, completeChan Name: "set tdp", ScriptTemplate: fmt.Sprintf("wrmsr -a 0x610 %d", newVal), Superuser: true, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, // Depends: []string{"wrmsr"}, // Lkms: []string{"msr"}, } @@ -472,7 +473,7 @@ func setEPB(epb int, myTarget target.Target, localTempDir string, completeChanne readScript := script.ScriptDefinition{ Name: "read " + msr, ScriptTemplate: "rdmsr " + msr, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, Superuser: true, // Lkms: []string{"msr"}, // Depends: []string{"rdmsr"}, @@ -496,7 +497,7 @@ func setEPB(epb int, myTarget target.Target, localTempDir string, completeChanne Name: "set epb", ScriptTemplate: fmt.Sprintf("wrmsr -a %s %d", msr, msrValue), Superuser: true, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, // Depends: []string{"wrmsr"}, // Lkms: []string{"msr"}, } @@ -515,7 +516,7 @@ func setEPP(epp int, myTarget target.Target, localTempDir string, completeChanne getScript := script.ScriptDefinition{ Name: "get epp msr", ScriptTemplate: "rdmsr 0x774", // IA32_HWP_REQUEST - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, Superuser: true, // Lkms: []string{"msr"}, // Depends: []string{"rdmsr"}, @@ -539,7 +540,7 @@ func setEPP(epp int, myTarget target.Target, localTempDir string, completeChanne Name: "set epp", ScriptTemplate: fmt.Sprintf("wrmsr -a 0x774 %d", eppValue), Superuser: true, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, // Depends: []string{"wrmsr"}, // Lkms: []string{"msr"}, } @@ -552,7 +553,7 @@ func setEPP(epp int, myTarget target.Target, localTempDir string, completeChanne getScript = script.ScriptDefinition{ Name: "get epp pkg msr", ScriptTemplate: "rdmsr 0x772", // IA32_HWP_REQUEST_PKG - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, Superuser: true, // Lkms: []string{"msr"}, // Depends: []string{"rdmsr"}, @@ -576,7 +577,7 @@ func setEPP(epp int, myTarget target.Target, localTempDir string, completeChanne Name: "set epp", ScriptTemplate: fmt.Sprintf("wrmsr -a 0x772 %d", eppValue), Superuser: true, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, // Depends: []string{"wrmsr"}, // Lkms: []string{"msr"}, } @@ -612,12 +613,12 @@ func setELC(elc string, myTarget target.Target, localTempDir string, completeCha return } setScript := script.ScriptDefinition{ - Name: "set elc", - ScriptTemplate: fmt.Sprintf("bhs-power-mode.sh --%s", mode), - Superuser: true, - Vendors: []string{"GenuineIntel"}, - Models: []string{"173", "174", "175", "221"}, // GNR, GNR-D, SRF, CWF - Depends: []string{"bhs-power-mode.sh", "pcm-tpmi"}, + Name: "set elc", + ScriptTemplate: fmt.Sprintf("bhs-power-mode.sh --%s", mode), + Superuser: true, + Vendors: []string{cpus.IntelVendor}, + MicroArchitectures: []string{"GNR", "GNR-D", "SRF", "CWF"}, + Depends: []string{"bhs-power-mode.sh", "pcm-tpmi"}, } _, err := runScript(myTarget, setScript, localTempDir) if err != nil { @@ -657,7 +658,7 @@ func setPrefetcher(enableDisable string, myTarget target.Target, localTempDir st getScript := script.ScriptDefinition{ Name: "get prefetcher msr", ScriptTemplate: fmt.Sprintf("rdmsr %d", pf.Msr), - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, Superuser: true, // Lkms: []string{"msr"}, // Depends: []string{"rdmsr"}, @@ -692,7 +693,7 @@ func setPrefetcher(enableDisable string, myTarget target.Target, localTempDir st Name: "set prefetcher" + prefetcherType, ScriptTemplate: fmt.Sprintf("wrmsr -a %d %d", pf.Msr, newVal), Superuser: true, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, // Depends: []string{"wrmsr"}, // Lkms: []string{"msr"}, } @@ -762,7 +763,7 @@ func setC1Demotion(enableDisable string, myTarget target.Target, localTempDir st getScript := script.ScriptDefinition{ Name: "get C1 demotion", ScriptTemplate: "rdmsr 0xe2", - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, Superuser: true, // Lkms: []string{"msr"}, // Depends: []string{"rdmsr"}, @@ -797,7 +798,7 @@ func setC1Demotion(enableDisable string, myTarget target.Target, localTempDir st setScript := script.ScriptDefinition{ Name: "set C1 demotion", ScriptTemplate: fmt.Sprintf("wrmsr -a %d %d", 0xe2, newVal), - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, Superuser: true, // Depends: []string{"wrmsr"}, // Lkms: []string{"msr"}, diff --git a/cmd/metrics/metadata.go b/cmd/metrics/metadata.go index 166f3fad..d53fcd4f 100644 --- a/cmd/metrics/metadata.go +++ b/cmd/metrics/metadata.go @@ -18,6 +18,7 @@ import ( "strings" "time" + "perfspect/internal/cpus" "perfspect/internal/report" "perfspect/internal/script" "perfspect/internal/target" @@ -93,9 +94,9 @@ type MetadataCollector interface { func NewMetadataCollector(architecture string) (MetadataCollector, error) { switch architecture { - case "x86_64": + case cpus.X86Architecture: return &X86MetadataCollector{}, nil - case "aarch64": + case cpus.ARMArchitecture: return &ARMMetadataCollector{}, nil default: return nil, fmt.Errorf("unsupported architecture: %s", architecture) @@ -145,7 +146,7 @@ func (c *X86MetadataCollector) CollectMetadata(myTarget target.Target, noRoot bo // Vendor (from cpuInfo) metadata.Vendor = cpuInfo[0]["vendor_id"] // CPU microarchitecture (from cpuInfo) - cpu, err := report.GetCPU(cpuInfo[0]["cpu family"], cpuInfo[0]["model"], cpuInfo[0]["stepping"]) + cpu, err := cpus.GetCPU(cpuInfo[0]["cpu family"], cpuInfo[0]["model"], cpuInfo[0]["stepping"]) if err != nil { return Metadata{}, err } @@ -261,7 +262,7 @@ func (c *X86MetadataCollector) CollectMetadata(myTarget target.Target, noRoot bo metadata.TSC = metadata.SocketCount * metadata.CoresPerSocket * metadata.ThreadsPerCore * metadata.TSCFrequencyHz } // uncore device IDs and uncore support - isAMDArchitecture := metadata.Vendor == "AuthenticAMD" + isAMDArchitecture := metadata.Vendor == cpus.AMDVendor if metadata.UncoreDeviceIDs, err = getUncoreDeviceIDs(isAMDArchitecture, scriptOutputs); err != nil { return Metadata{}, fmt.Errorf("failed to retrieve uncore device IDs: %v", err) } else { @@ -330,7 +331,7 @@ func (c *ARMMetadataCollector) CollectMetadata(myTarget target.Target, noRoot bo if err != nil { return Metadata{}, fmt.Errorf("failed to parse stepping: %v", err) } - cpu, err := report.GetCPU(family, model, stepping) + cpu, err := cpus.GetCPU(family, model, stepping) if err != nil { return Metadata{}, err } @@ -412,7 +413,7 @@ func getMetadataScripts(noRoot bool, perfPath string, noSystemSummary bool, numG Name: "list uncore devices", ScriptTemplate: "find /sys/bus/event_source/devices/ \\( -name uncore_* -o -name amd_* \\)", Superuser: !noRoot, - Architectures: []string{"x86_64"}, + Architectures: []string{cpus.X86Architecture}, }, { Name: "perf stat instructions", @@ -428,19 +429,19 @@ func getMetadataScripts(noRoot bool, perfPath string, noSystemSummary bool, numG Name: "perf stat pebs", ScriptTemplate: perfPath + " stat -a -e INT_MISC.UNKNOWN_BRANCH_CYCLES sleep 1", Superuser: !noRoot, - Architectures: []string{"x86_64"}, + Architectures: []string{cpus.X86Architecture}, }, { Name: "perf stat ocr", ScriptTemplate: perfPath + " stat -a -e OCR.READS_TO_CORE.LOCAL_DRAM sleep 1", Superuser: !noRoot, - Architectures: []string{"x86_64"}, + Architectures: []string{cpus.X86Architecture}, }, { Name: "perf stat tma", ScriptTemplate: perfPath + " stat -a -e '{topdown.slots, topdown-bad-spec}' sleep 1", Superuser: !noRoot, - Architectures: []string{"x86_64"}, + Architectures: []string{cpus.X86Architecture}, }, { Name: "perf stat fixed instructions", @@ -467,7 +468,7 @@ func getMetadataScripts(noRoot bool, perfPath string, noSystemSummary bool, numG ScriptTemplate: "tsc && echo", Depends: []string{"tsc"}, Superuser: !noRoot, - Architectures: []string{"x86_64"}, + Architectures: []string{cpus.X86Architecture}, }, { Name: "kernel version", @@ -478,13 +479,13 @@ func getMetadataScripts(noRoot bool, perfPath string, noSystemSummary bool, numG Name: "arm slots", ScriptTemplate: "cat /sys/bus/event_source/devices/armv8_pmuv3_0/caps/slots", Superuser: !noRoot, - Architectures: []string{"aarch64"}, + Architectures: []string{cpus.ARMArchitecture}, }, { Name: "arm cpuid", ScriptTemplate: "cat /sys/devices/system/cpu/cpu0/regs/identification/midr_el1", Superuser: !noRoot, - Architectures: []string{"aarch64"}, + Architectures: []string{cpus.ARMArchitecture}, }, } // replace script template vars diff --git a/cmd/metrics/metrics.go b/cmd/metrics/metrics.go index d1b88015..585e0875 100644 --- a/cmd/metrics/metrics.go +++ b/cmd/metrics/metrics.go @@ -24,6 +24,7 @@ import ( "time" "perfspect/internal/common" + "perfspect/internal/cpus" "perfspect/internal/progress" "perfspect/internal/script" "perfspect/internal/target" @@ -1146,7 +1147,7 @@ func prepareTarget(targetContext *targetContext, localTempDir string, localPerfP var err error _ = statusUpdate(myTarget.GetName(), "configuring target") // are PMUs being used on target? - if family, err := myTarget.GetFamily(); err == nil && family == "6" { + if family, err := myTarget.GetFamily(); err == nil && cpus.IsIntelCPUFamilyStr(family) { output, err := script.RunScript(myTarget, script.GetScriptByName(script.PMUBusyScriptName), localTempDir) if err != nil { err = fmt.Errorf("failed to check if PMUs are in use: %w", err) @@ -1197,7 +1198,7 @@ func prepareTarget(targetContext *targetContext, localTempDir string, localPerfP if useDefaultMuxInterval { // set the default mux interval to 16ms for AMD architecture vendor, err := myTarget.GetVendor() - if err == nil && vendor == "AuthenticAMD" { + if err == nil && vendor == cpus.AMDVendor { perfMuxInterval = 16 } } diff --git a/cmd/metrics/summary.go b/cmd/metrics/summary.go index a5605ac2..4573f59d 100644 --- a/cmd/metrics/summary.go +++ b/cmd/metrics/summary.go @@ -15,6 +15,7 @@ import ( "math" "os" "path/filepath" + "perfspect/internal/cpus" "regexp" "slices" "strconv" @@ -384,7 +385,7 @@ func (mg *MetricGroup) loadHTMLTemplateValues(metadata Metadata, metricDefinitio //0 -> Intel, 1 -> AMD, 2 -> ARM archIndex := 0 switch metadata.Vendor { - case "AuthenticAMD": + case cpus.AMDVendor: archIndex = 1 case "ARM": archIndex = 2 diff --git a/internal/common/targets.go b/internal/common/targets.go index a4e9c95d..94b44d3a 100644 --- a/internal/common/targets.go +++ b/internal/common/targets.go @@ -10,6 +10,7 @@ import ( "os/exec" "os/user" "path" + "perfspect/internal/cpus" "perfspect/internal/script" "perfspect/internal/target" "perfspect/internal/util" @@ -403,9 +404,9 @@ func getPassword(prompt string) (string, error) { func getHostArchitecture() (string, error) { switch runtime.GOARCH { case "amd64": - return "x86_64", nil + return cpus.X86Architecture, nil case "arm64": - return "aarch64", nil + return cpus.ARMArchitecture, nil default: slog.Error("unsupported architecture", slog.String("architecture", runtime.GOARCH)) err := fmt.Errorf("unsupported architecture: %s", runtime.GOARCH) diff --git a/internal/report/cpu_defs.go b/internal/cpus/cpu_defs.go similarity index 53% rename from internal/report/cpu_defs.go rename to internal/cpus/cpu_defs.go index 55c20e15..f37af735 100644 --- a/internal/report/cpu_defs.go +++ b/internal/cpus/cpu_defs.go @@ -1,14 +1,39 @@ -package report +// Package cpus provides CPU definitions and lookup utilities for microarchitecture, +// family, model, and stepping, supporting both x86 and ARM architectures. +package cpus + +// Copyright (C) 2021-2025 Intel Corporation +// SPDX-License-Identifier: BSD-3-Clause import ( "fmt" "regexp" + "slices" "strconv" "strings" ) -// Copyright (C) 2021-2025 Intel Corporation -// SPDX-License-Identifier: BSD-3-Clause +const IntelVendor = "GenuineIntel" +const AMDVendor = "AuthenticAMD" + +const X86Architecture = "x86_64" +const ARMArchitecture = "aarch64" + +var IntelFamilies = []int{6, 19} + +// IsIntelCPUFamily checks if the CPU family corresponds to Intel CPUs. +func IsIntelCPUFamily(family int) bool { + return slices.Contains(IntelFamilies, family) +} + +// IsIntelCPUFamilyStr checks if the CPU family string corresponds to Intel CPUs. +func IsIntelCPUFamilyStr(familyStr string) bool { + family, err := strconv.Atoi(familyStr) + if err != nil { + return false + } + return IsIntelCPUFamily(family) +} // CPUDefinition - used to lookup micro architecture and channels by family, model, and stepping // @@ -25,61 +50,70 @@ type CPUDefinition struct { CacheWayCount int } +func (c CPUDefinition) GetMicroArchitecture() string { + return c.MicroArchitecture +} + +func (c CPUDefinition) GetShortMicroArchitecture() string { + return strings.Split(c.MicroArchitecture, "_")[0] +} + // GetCPU retrieves the CPU structure that matches the provided args func GetCPU(family, model, stepping string) (cpu CPUDefinition, err error) { - return getCPUExtended(family, model, stepping, "", "") + return GetCPUExtended(family, model, stepping, "", "") } var cpuDefinitions = []CPUDefinition{ // Intel Core CPUs - {MicroArchitecture: "HSW", Family: "6", Model: "(50|69|70)", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 2, LogicalThreadCount: 2, CacheWayCount: 0}, // Haswell - {MicroArchitecture: "BDW", Family: "6", Model: "(61|71)", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 2, LogicalThreadCount: 2, CacheWayCount: 0}, // Broadwell - {MicroArchitecture: "SKL", Family: "6", Model: "(78|94)", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 2, LogicalThreadCount: 2, CacheWayCount: 0}, // Skylake - {MicroArchitecture: "KBL", Family: "6", Model: "(142|158)", Stepping: "9", Architecture: "x86_64", MemoryChannelCount: 2, LogicalThreadCount: 2, CacheWayCount: 0}, // Kabylake - {MicroArchitecture: "CFL", Family: "6", Model: "(142|158)", Stepping: "(10|11|12|13)", Architecture: "x86_64", MemoryChannelCount: 2, LogicalThreadCount: 2, CacheWayCount: 0}, // Coffeelake - {MicroArchitecture: "RKL", Family: "6", Model: "167", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 2, LogicalThreadCount: 2, CacheWayCount: 0}, // Rocket Lake - {MicroArchitecture: "TGL", Family: "6", Model: "(140|141)", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 2, LogicalThreadCount: 2, CacheWayCount: 0}, // Tiger Lake - {MicroArchitecture: "ADL", Family: "6", Model: "(151|154)", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 2, LogicalThreadCount: 2, CacheWayCount: 0}, // Alder Lake - {MicroArchitecture: "MTL", Family: "6", Model: "170", Stepping: "4", Architecture: "x86_64", MemoryChannelCount: 2, LogicalThreadCount: 2, CacheWayCount: 0}, // Meteor Lake - {MicroArchitecture: "ARL", Family: "6", Model: "197", Stepping: "2", Architecture: "x86_64", MemoryChannelCount: 2, LogicalThreadCount: 2, CacheWayCount: 0}, // Arrow Lake + {MicroArchitecture: "HSW", Family: "6", Model: "(50|69|70)", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 2, LogicalThreadCount: 2, CacheWayCount: 0}, // Haswell + {MicroArchitecture: "BDW", Family: "6", Model: "(61|71)", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 2, LogicalThreadCount: 2, CacheWayCount: 0}, // Broadwell + {MicroArchitecture: "SKL", Family: "6", Model: "(78|94)", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 2, LogicalThreadCount: 2, CacheWayCount: 0}, // Skylake + {MicroArchitecture: "KBL", Family: "6", Model: "(142|158)", Stepping: "9", Architecture: X86Architecture, MemoryChannelCount: 2, LogicalThreadCount: 2, CacheWayCount: 0}, // Kabylake + {MicroArchitecture: "CFL", Family: "6", Model: "(142|158)", Stepping: "(10|11|12|13)", Architecture: X86Architecture, MemoryChannelCount: 2, LogicalThreadCount: 2, CacheWayCount: 0}, // Coffeelake + {MicroArchitecture: "RKL", Family: "6", Model: "167", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 2, LogicalThreadCount: 2, CacheWayCount: 0}, // Rocket Lake + {MicroArchitecture: "TGL", Family: "6", Model: "(140|141)", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 2, LogicalThreadCount: 2, CacheWayCount: 0}, // Tiger Lake + {MicroArchitecture: "ADL", Family: "6", Model: "(151|154)", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 2, LogicalThreadCount: 2, CacheWayCount: 0}, // Alder Lake + {MicroArchitecture: "MTL", Family: "6", Model: "170", Stepping: "4", Architecture: X86Architecture, MemoryChannelCount: 2, LogicalThreadCount: 2, CacheWayCount: 0}, // Meteor Lake + {MicroArchitecture: "ARL", Family: "6", Model: "197", Stepping: "2", Architecture: X86Architecture, MemoryChannelCount: 2, LogicalThreadCount: 2, CacheWayCount: 0}, // Arrow Lake // Intel Xeon CPUs - {MicroArchitecture: "HSX", Family: "6", Model: "63", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 4, LogicalThreadCount: 2, CacheWayCount: 20}, // Haswell - {MicroArchitecture: "BDX", Family: "6", Model: "(79|86)", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 4, LogicalThreadCount: 2, CacheWayCount: 20}, // Broadwell - {MicroArchitecture: "SKX", Family: "6", Model: "85", Stepping: "(0|1|2|3|4)", Architecture: "x86_64", MemoryChannelCount: 6, LogicalThreadCount: 2, CacheWayCount: 11}, // Skylake - {MicroArchitecture: "CLX", Family: "6", Model: "85", Stepping: "(5|6|7)", Architecture: "x86_64", MemoryChannelCount: 6, LogicalThreadCount: 2, CacheWayCount: 11}, // Cascadelake - {MicroArchitecture: "CPX", Family: "6", Model: "85", Stepping: "11", Architecture: "x86_64", MemoryChannelCount: 6, LogicalThreadCount: 2, CacheWayCount: 11}, // Cooperlake - {MicroArchitecture: "ICX", Family: "6", Model: "(106|108)", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 12}, // Icelake - {MicroArchitecture: "SPR", Family: "6", Model: "143", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 15}, // Sapphire Rapids - generic - {MicroArchitecture: "SPR_MCC", Family: "6", Model: "143", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 15}, // Sapphire Rapids - MCC - {MicroArchitecture: "SPR_XCC", Family: "6", Model: "143", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 15}, // Sapphire Rapids - XCC - {MicroArchitecture: "EMR", Family: "6", Model: "207", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 15}, // Emerald Rapids - generic - {MicroArchitecture: "EMR_MCC", Family: "6", Model: "207", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 15}, // Emerald Rapids - MCC - {MicroArchitecture: "EMR_XCC", Family: "6", Model: "207", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 20}, // Emerald Rapids - XCC - {MicroArchitecture: "SRF", Family: "6", Model: "175", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 0, LogicalThreadCount: 1, CacheWayCount: 12}, // Sierra Forest - {MicroArchitecture: "SRF_SP", Family: "6", Model: "175", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 8, LogicalThreadCount: 1, CacheWayCount: 12}, // Sierra Forest - {MicroArchitecture: "SRF_AP", Family: "6", Model: "175", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 12, LogicalThreadCount: 1, CacheWayCount: 12}, // Sierra Forest - {MicroArchitecture: "GNR", Family: "6", Model: "173", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 0, LogicalThreadCount: 2, CacheWayCount: 16}, // Granite Rapids - generic - {MicroArchitecture: "GNR_X1", Family: "6", Model: "173", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 16}, // Granite Rapids - SP (MCC/LCC) - {MicroArchitecture: "GNR_X2", Family: "6", Model: "173", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 16}, // Granite Rapids - SP (XCC) - {MicroArchitecture: "GNR_X3", Family: "6", Model: "173", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 12, LogicalThreadCount: 2, CacheWayCount: 16}, // Granite Rapids - AP (UCC) - {MicroArchitecture: "GNR_D", Family: "6", Model: "174", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 0, LogicalThreadCount: 2, CacheWayCount: 16}, // Granite Rapids - D - {MicroArchitecture: "CWF", Family: "6", Model: "221", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 12, LogicalThreadCount: 1, CacheWayCount: 0}, // Clearwater Forest - generic + {MicroArchitecture: "HSX", Family: "6", Model: "63", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 4, LogicalThreadCount: 2, CacheWayCount: 20}, // Haswell + {MicroArchitecture: "BDX", Family: "6", Model: "(79|86)", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 4, LogicalThreadCount: 2, CacheWayCount: 20}, // Broadwell + {MicroArchitecture: "SKX", Family: "6", Model: "85", Stepping: "(0|1|2|3|4)", Architecture: X86Architecture, MemoryChannelCount: 6, LogicalThreadCount: 2, CacheWayCount: 11}, // Skylake + {MicroArchitecture: "CLX", Family: "6", Model: "85", Stepping: "(5|6|7)", Architecture: X86Architecture, MemoryChannelCount: 6, LogicalThreadCount: 2, CacheWayCount: 11}, // Cascadelake + {MicroArchitecture: "CPX", Family: "6", Model: "85", Stepping: "11", Architecture: X86Architecture, MemoryChannelCount: 6, LogicalThreadCount: 2, CacheWayCount: 11}, // Cooperlake + {MicroArchitecture: "ICX", Family: "6", Model: "(106|108)", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 12}, // Icelake + {MicroArchitecture: "SPR", Family: "6", Model: "143", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 15}, // Sapphire Rapids - generic + {MicroArchitecture: "SPR_MCC", Family: "6", Model: "143", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 15}, // Sapphire Rapids - MCC + {MicroArchitecture: "SPR_XCC", Family: "6", Model: "143", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 15}, // Sapphire Rapids - XCC + {MicroArchitecture: "EMR", Family: "6", Model: "207", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 15}, // Emerald Rapids - generic + {MicroArchitecture: "EMR_MCC", Family: "6", Model: "207", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 15}, // Emerald Rapids - MCC + {MicroArchitecture: "EMR_XCC", Family: "6", Model: "207", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 20}, // Emerald Rapids - XCC + {MicroArchitecture: "SRF", Family: "6", Model: "175", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 0, LogicalThreadCount: 1, CacheWayCount: 12}, // Sierra Forest + {MicroArchitecture: "SRF_SP", Family: "6", Model: "175", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 8, LogicalThreadCount: 1, CacheWayCount: 12}, // Sierra Forest + {MicroArchitecture: "SRF_AP", Family: "6", Model: "175", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 12, LogicalThreadCount: 1, CacheWayCount: 12}, // Sierra Forest + {MicroArchitecture: "GNR", Family: "6", Model: "173", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 0, LogicalThreadCount: 2, CacheWayCount: 16}, // Granite Rapids - generic + {MicroArchitecture: "GNR_X1", Family: "6", Model: "173", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 16}, // Granite Rapids - SP (MCC/LCC) + {MicroArchitecture: "GNR_X2", Family: "6", Model: "173", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 16}, // Granite Rapids - SP (XCC) + {MicroArchitecture: "GNR_X3", Family: "6", Model: "173", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 12, LogicalThreadCount: 2, CacheWayCount: 16}, // Granite Rapids - AP (UCC) + {MicroArchitecture: "GNR_D", Family: "6", Model: "174", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 0, LogicalThreadCount: 2, CacheWayCount: 16}, // Granite Rapids - D + {MicroArchitecture: "CWF", Family: "6", Model: "221", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 12, LogicalThreadCount: 1, CacheWayCount: 0}, // Clearwater Forest - generic + {MicroArchitecture: "DMR", Family: "19", Model: "1", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 16, LogicalThreadCount: 1, CacheWayCount: 0}, // Diamond Rapids // AMD CPUs - {MicroArchitecture: "Naples", Family: "23", Model: "1", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 0}, // Naples - {MicroArchitecture: "Rome", Family: "23", Model: "49", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 0}, // Rome - {MicroArchitecture: "Milan", Family: "25", Model: "1", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 0}, // Milan - {MicroArchitecture: "Genoa", Family: "25", Model: "(1[6-9]|2[0-9]|3[01])", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 12, LogicalThreadCount: 2, CacheWayCount: 0}, // Genoa, model 16-31 - {MicroArchitecture: "Bergamo", Family: "25", Model: "(16[0-9]|17[0-5])", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 12, LogicalThreadCount: 2, CacheWayCount: 0}, // Bergamo, model 160-175 - {MicroArchitecture: "Turin (Zen 5)", Family: "26", Model: "2", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 12, LogicalThreadCount: 2, CacheWayCount: 0}, // Turin (Zen 5) - {MicroArchitecture: "Turin (Zen 5c)", Family: "26", Model: "17", Stepping: "", Architecture: "x86_64", MemoryChannelCount: 12, LogicalThreadCount: 2, CacheWayCount: 0}, // Turin (Zen 5c) + {MicroArchitecture: "Naples", Family: "23", Model: "1", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 0}, // Naples + {MicroArchitecture: "Rome", Family: "23", Model: "49", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 0}, // Rome + {MicroArchitecture: "Milan", Family: "25", Model: "1", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 8, LogicalThreadCount: 2, CacheWayCount: 0}, // Milan + {MicroArchitecture: "Genoa", Family: "25", Model: "(1[6-9]|2[0-9]|3[01])", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 12, LogicalThreadCount: 2, CacheWayCount: 0}, // Genoa, model 16-31 + {MicroArchitecture: "Bergamo", Family: "25", Model: "(16[0-9]|17[0-5])", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 12, LogicalThreadCount: 2, CacheWayCount: 0}, // Bergamo, model 160-175 + {MicroArchitecture: "Turin (Zen 5)", Family: "26", Model: "2", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 12, LogicalThreadCount: 2, CacheWayCount: 0}, // Turin (Zen 5) + {MicroArchitecture: "Turin (Zen 5c)", Family: "26", Model: "17", Stepping: "", Architecture: X86Architecture, MemoryChannelCount: 12, LogicalThreadCount: 2, CacheWayCount: 0}, // Turin (Zen 5c) // ARM CPUs - {MicroArchitecture: "Neoverse-N1", Family: "", Model: "1", Stepping: "r3p1", Architecture: "aarch64", MemoryChannelCount: 8, LogicalThreadCount: 1, CacheWayCount: 0}, // AWS Graviton 2 ([m|c|r]6g) - {MicroArchitecture: "Neoverse-V1", Family: "", Model: "1", Stepping: "r1p1", Architecture: "aarch64", MemoryChannelCount: 8, LogicalThreadCount: 1, CacheWayCount: 0}, // AWS Graviton 3 ([m|c|r]7g) - {MicroArchitecture: "Neoverse-V2", Family: "", Model: "1", Stepping: "r0p1", Architecture: "aarch64", MemoryChannelCount: 8, LogicalThreadCount: 1, CacheWayCount: 0}, // AWS Graviton 4 ([m|c|r]8g), GCP Axion (c4a) + {MicroArchitecture: "Neoverse-N1", Family: "", Model: "1", Stepping: "r3p1", Architecture: ARMArchitecture, MemoryChannelCount: 8, LogicalThreadCount: 1, CacheWayCount: 0}, // AWS Graviton 2 ([m|c|r]6g) + {MicroArchitecture: "Neoverse-V1", Family: "", Model: "1", Stepping: "r1p1", Architecture: ARMArchitecture, MemoryChannelCount: 8, LogicalThreadCount: 1, CacheWayCount: 0}, // AWS Graviton 3 ([m|c|r]7g) + {MicroArchitecture: "Neoverse-V2", Family: "", Model: "1", Stepping: "r0p1", Architecture: ARMArchitecture, MemoryChannelCount: 8, LogicalThreadCount: 1, CacheWayCount: 0}, // AWS Graviton 4 ([m|c|r]8g), GCP Axion (c4a) } -// getCPUExtended retrieves the CPU structure that matches the provided args +// GetCPUExtended retrieves the CPU structure that matches the provided args // capid4 needed to differentiate EMR MCC from EMR XCC // // capid4: $ lspci -s $(lspci | grep 325b | awk 'NR==1{{print $1}}') -xxx | awk '$1 ~ /^90/{{print $9 $8 $7 $6; exit}}' @@ -87,7 +121,7 @@ var cpuDefinitions = []CPUDefinition{ // devices needed to differentiate GNR X1/2/3 // // devices: $ lspci -d 8086:3258 | wc -l -func getCPUExtended(family, model, stepping, capid4, devices string) (cpu CPUDefinition, err error) { +func GetCPUExtended(family, model, stepping, capid4, devices string) (cpu CPUDefinition, err error) { for _, info := range cpuDefinitions { // if family matches if info.Family == family { diff --git a/internal/report/cpu_defs_test.go b/internal/cpus/cpu_defs_test.go similarity index 92% rename from internal/report/cpu_defs_test.go rename to internal/cpus/cpu_defs_test.go index 77def284..92dfa758 100644 --- a/internal/report/cpu_defs_test.go +++ b/internal/cpus/cpu_defs_test.go @@ -1,4 +1,4 @@ -package report +package cpus // Copyright (C) 2021-2025 Intel Corporation // SPDX-License-Identifier: BSD-3-Clause @@ -55,7 +55,7 @@ func TestGetCPU(t *testing.T) { t.Fatal(fmt.Errorf("Found the wrong CPU: %s", cpu.MicroArchitecture)) } - cpu, err = getCPUExtended("6", "173", "", "", "10") // GNR_X3 + cpu, err = GetCPUExtended("6", "173", "", "", "10") // GNR_X3 if err != nil { t.Fatal(err) } @@ -66,7 +66,7 @@ func TestGetCPU(t *testing.T) { t.Fatal(fmt.Errorf("Incorrect channel count: %d", cpu.MemoryChannelCount)) } - cpu, err = getCPUExtended("6", "173", "", "", "8") // GNR_X2 + cpu, err = GetCPUExtended("6", "173", "", "", "8") // GNR_X2 if err != nil { t.Fatal(err) } @@ -77,7 +77,7 @@ func TestGetCPU(t *testing.T) { t.Fatal(fmt.Errorf("Incorrect channel count: %d", cpu.MemoryChannelCount)) } - cpu, err = getCPUExtended("6", "173", "", "", "6") // GNR_X1 + cpu, err = GetCPUExtended("6", "173", "", "", "6") // GNR_X1 if err != nil { t.Fatal(err) } @@ -96,7 +96,7 @@ func TestGetCPU(t *testing.T) { t.Fatal(fmt.Errorf("Found the wrong CPU: %s", cpu.MicroArchitecture)) } - cpu, err = getCPUExtended("6", "207", "", "c0", "") // EMR XCC + cpu, err = GetCPUExtended("6", "207", "", "c0", "") // EMR XCC if err != nil { t.Fatal(err) } @@ -107,7 +107,7 @@ func TestGetCPU(t *testing.T) { t.Fatal(fmt.Errorf("Incorrect channel count: %d", cpu.MemoryChannelCount)) } - cpu, err = getCPUExtended("6", "207", "", "40", "") // EMR MCC + cpu, err = GetCPUExtended("6", "207", "", "40", "") // EMR MCC if err != nil { t.Fatal(err) } diff --git a/internal/report/table.go b/internal/report/table.go index c3f24501..55f5f840 100644 --- a/internal/report/table.go +++ b/internal/report/table.go @@ -8,6 +8,7 @@ package report import ( "fmt" "log/slog" + "perfspect/internal/cpus" "perfspect/internal/script" "perfspect/internal/target" "slices" @@ -44,23 +45,28 @@ func IsTableForTarget(tableName string, myTarget target.Target) bool { return false } } - if len(table.Families) > 0 { + if len(table.MicroArchitectures) > 0 { family, err := myTarget.GetFamily() if err != nil { slog.Error("failed to get family for target", slog.String("target", myTarget.GetName()), slog.String("error", err.Error())) return false } - if !slices.Contains(table.Families, family) { - return false - } - } - if len(table.Models) > 0 { model, err := myTarget.GetModel() if err != nil { slog.Error("failed to get model for target", slog.String("target", myTarget.GetName()), slog.String("error", err.Error())) return false } - if !slices.Contains(table.Models, model) { + stepping, err := myTarget.GetStepping() + if err != nil { + slog.Error("failed to get stepping for target", slog.String("target", myTarget.GetName()), slog.String("error", err.Error())) + return false + } + cpu, err := cpus.GetCPU(family, model, stepping) + if err != nil { + slog.Error("failed to get CPU for target", slog.String("target", myTarget.GetName()), slog.String("error", err.Error())) + return false + } + if !slices.Contains(table.MicroArchitectures, cpu.GetMicroArchitecture()) && !slices.Contains(table.MicroArchitectures, cpu.GetShortMicroArchitecture()) { return false } } diff --git a/internal/report/table_defs.go b/internal/report/table_defs.go index c2b33b78..cf0f7e49 100644 --- a/internal/report/table_defs.go +++ b/internal/report/table_defs.go @@ -15,6 +15,7 @@ import ( "strings" "time" + "perfspect/internal/cpus" "perfspect/internal/script" "github.com/xuri/excelize/v2" @@ -49,12 +50,11 @@ type XlsxTableRenderer func(TableValues, *excelize.File, string, *int) // TableDefinition defines the structure of a table in the report type TableDefinition struct { - Name string - ScriptNames []string - Architectures []string // architectures, i.e., x86_64, aarch64. If empty, it will be present for all architectures. - Vendors []string // vendors, e.g., GenuineIntel, AuthenticAMD. If empty, it will be present for all vendors. - Families []string // families, e.g., 6, 7. If empty, it will be present for all families. - Models []string // models, e.g., 62, 63. If empty, it will be present for all models. + Name string + ScriptNames []string + Architectures []string // architectures, i.e., x86_64, aarch64. If empty, it will be present for all architectures. + Vendors []string // vendors, e.g., GenuineIntel, AuthenticAMD. If empty, it will be present for all vendors. + MicroArchitectures []string // microarchitectures, e.g., EMR, ICX. If empty, it will be present for all microarchitectures. // Fields function is called to retrieve field values from the script outputs FieldsFunc FieldsRetriever MenuLabel string // add to tables that will be displayed in the menu @@ -236,7 +236,7 @@ var tableDefinitions = map[string]TableDefinition{ PrefetcherTableName: { Name: PrefetcherTableName, HasRows: true, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, ScriptNames: []string{ script.LscpuScriptName, script.LspciBitsScriptName, @@ -248,14 +248,14 @@ var tableDefinitions = map[string]TableDefinition{ FieldsFunc: prefetcherTableValues}, ISATableName: { Name: ISATableName, - Architectures: []string{"x86_64"}, + Architectures: []string{cpus.X86Architecture}, ScriptNames: []string{script.CpuidScriptName}, FieldsFunc: isaTableValues}, AcceleratorTableName: { - Name: AcceleratorTableName, - Vendors: []string{"GenuineIntel"}, - Models: []string{"143", "207", "173", "174", "175", "221"}, // Sapphire Rapids, Emerald Rapids, Granite Rapids, Granite Rapids D, Sierra Forest, Clearwater Forest - HasRows: true, + Name: AcceleratorTableName, + Vendors: []string{cpus.IntelVendor}, + MicroArchitectures: []string{"SPR", "EMR", "GNR", "SRF", "CWF", "DMR"}, + HasRows: true, ScriptNames: []string{ script.LshwScriptName, script.IaaDevicesScriptName, @@ -264,7 +264,7 @@ var tableDefinitions = map[string]TableDefinition{ InsightsFunc: acceleratorTableInsights}, PowerTableName: { Name: PowerTableName, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, HasRows: false, MenuLabel: PowerMenuLabel, ScriptNames: []string{ @@ -287,7 +287,7 @@ var tableDefinitions = map[string]TableDefinition{ FieldsFunc: cstateTableValues}, MaximumFrequencyTableName: { Name: MaximumFrequencyTableName, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, HasRows: true, ScriptNames: []string{ script.SpecCoreFrequenciesScriptName, @@ -298,7 +298,7 @@ var tableDefinitions = map[string]TableDefinition{ FieldsFunc: maximumFrequencyTableValues}, UncoreTableName: { Name: UncoreTableName, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, HasRows: false, ScriptNames: []string{ script.UncoreMaxFromMSRScriptName, @@ -312,29 +312,26 @@ var tableDefinitions = map[string]TableDefinition{ script.LspciDevicesScriptName}, FieldsFunc: uncoreTableValues}, ElcTableName: { - Name: ElcTableName, - Families: []string{"6"}, // Intel CPUs only - Models: []string{"173", "174", "175", "221"}, // Granite Rapids, Granite Rapids D, Sierra Forest, Clearwater Forest - HasRows: true, + Name: ElcTableName, + MicroArchitectures: []string{"GNR", "SRF", "CWF", "DMR"}, + HasRows: true, ScriptNames: []string{ script.ElcScriptName, }, FieldsFunc: elcTableValues, InsightsFunc: elcTableInsights}, SSTTFHPTableName: { - Name: SSTTFHPTableName, - Families: []string{"6"}, // Intel CPUs only - Models: []string{"173", "174", "175", "221"}, // Granite Rapids, Granite Rapids D, Sierra Forest, Clearwater Forest - HasRows: true, + Name: SSTTFHPTableName, + MicroArchitectures: []string{"GNR", "SRF", "CWF", "DMR"}, + HasRows: true, ScriptNames: []string{ script.SSTTFHPScriptName, }, FieldsFunc: sstTFHPTableValues}, SSTTFLPTableName: { - Name: SSTTFLPTableName, - Families: []string{"6"}, // Intel CPUs only - Models: []string{"173", "174", "175", "221"}, // Granite Rapids, Granite Rapids D, Sierra Forest, Clearwater Forest - HasRows: true, + Name: SSTTFLPTableName, + MicroArchitectures: []string{"GNR", "SRF", "CWF", "DMR"}, + HasRows: true, ScriptNames: []string{ script.SSTTFLPScriptName, }, @@ -416,7 +413,7 @@ var tableDefinitions = map[string]TableDefinition{ FieldsFunc: gpuTableValues}, GaudiTableName: { Name: GaudiTableName, - Architectures: []string{"x86_64"}, + Architectures: []string{cpus.X86Architecture}, HasRows: true, ScriptNames: []string{ script.GaudiInfoScriptName, @@ -471,7 +468,7 @@ var tableDefinitions = map[string]TableDefinition{ FieldsFunc: chassisStatusTableValues}, PMUTableName: { Name: PMUTableName, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, HasRows: false, ScriptNames: []string{ script.PMUBusyScriptName, @@ -562,7 +559,7 @@ var tableDefinitions = map[string]TableDefinition{ // ConfigurationTableName: { Name: ConfigurationTableName, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, HasRows: false, ScriptNames: []string{ script.LscpuScriptName, @@ -605,7 +602,7 @@ var tableDefinitions = map[string]TableDefinition{ PowerBenchmarkTableName: { Name: PowerBenchmarkTableName, MenuLabel: PowerBenchmarkTableName, - Architectures: []string{"x86_64"}, + Architectures: []string{cpus.X86Architecture}, HasRows: false, ScriptNames: []string{ script.IdlePowerBenchmarkScriptName, @@ -615,7 +612,7 @@ var tableDefinitions = map[string]TableDefinition{ TemperatureBenchmarkTableName: { Name: TemperatureBenchmarkTableName, MenuLabel: TemperatureBenchmarkTableName, - Architectures: []string{"x86_64"}, + Architectures: []string{cpus.X86Architecture}, HasRows: false, ScriptNames: []string{ script.PowerBenchmarkScriptName, @@ -624,7 +621,7 @@ var tableDefinitions = map[string]TableDefinition{ FrequencyBenchmarkTableName: { Name: FrequencyBenchmarkTableName, MenuLabel: FrequencyBenchmarkTableName, - Architectures: []string{"x86_64"}, + Architectures: []string{cpus.X86Architecture}, HasRows: true, ScriptNames: []string{ script.SpecCoreFrequenciesScriptName, @@ -638,7 +635,7 @@ var tableDefinitions = map[string]TableDefinition{ MemoryBenchmarkTableName: { Name: MemoryBenchmarkTableName, MenuLabel: MemoryBenchmarkTableName, - Architectures: []string{"x86_64"}, + Architectures: []string{cpus.X86Architecture}, HasRows: true, ScriptNames: []string{ script.MemoryBenchmarkScriptName, @@ -650,7 +647,7 @@ var tableDefinitions = map[string]TableDefinition{ NUMABenchmarkTableName: { Name: NUMABenchmarkTableName, MenuLabel: NUMABenchmarkTableName, - Architectures: []string{"x86_64"}, + Architectures: []string{cpus.X86Architecture}, HasRows: true, ScriptNames: []string{ script.NumaBenchmarkScriptName, @@ -689,7 +686,7 @@ var tableDefinitions = map[string]TableDefinition{ IPCTelemetryTableName: { Name: IPCTelemetryTableName, MenuLabel: IPCTelemetryMenuLabel, - Architectures: []string{"x86_64"}, + Architectures: []string{cpus.X86Architecture}, HasRows: true, ScriptNames: []string{ script.TurbostatTelemetryScriptName, @@ -699,7 +696,7 @@ var tableDefinitions = map[string]TableDefinition{ C6TelemetryTableName: { Name: C6TelemetryTableName, MenuLabel: C6TelemetryMenuLabel, - Architectures: []string{"x86_64"}, + Architectures: []string{cpus.X86Architecture}, HasRows: true, ScriptNames: []string{ script.TurbostatTelemetryScriptName, @@ -709,7 +706,7 @@ var tableDefinitions = map[string]TableDefinition{ FrequencyTelemetryTableName: { Name: FrequencyTelemetryTableName, MenuLabel: FrequencyTelemetryMenuLabel, - Architectures: []string{"x86_64"}, + Architectures: []string{cpus.X86Architecture}, HasRows: true, ScriptNames: []string{ script.TurbostatTelemetryScriptName, @@ -755,7 +752,7 @@ var tableDefinitions = map[string]TableDefinition{ PowerTelemetryTableName: { Name: PowerTelemetryTableName, MenuLabel: PowerTelemetryMenuLabel, - Architectures: []string{"x86_64"}, + Architectures: []string{cpus.X86Architecture}, HasRows: true, ScriptNames: []string{ script.TurbostatTelemetryScriptName, @@ -765,7 +762,7 @@ var tableDefinitions = map[string]TableDefinition{ TemperatureTelemetryTableName: { Name: TemperatureTelemetryTableName, MenuLabel: TemperatureTelemetryMenuLabel, - Architectures: []string{"x86_64"}, + Architectures: []string{cpus.X86Architecture}, HasRows: true, ScriptNames: []string{ script.TurbostatTelemetryScriptName, @@ -775,7 +772,7 @@ var tableDefinitions = map[string]TableDefinition{ InstructionTelemetryTableName: { Name: InstructionTelemetryTableName, MenuLabel: InstructionTelemetryMenuLabel, - Architectures: []string{"x86_64"}, + Architectures: []string{cpus.X86Architecture}, HasRows: true, ScriptNames: []string{ script.InstructionTelemetryScriptName, @@ -785,7 +782,7 @@ var tableDefinitions = map[string]TableDefinition{ GaudiTelemetryTableName: { Name: GaudiTelemetryTableName, MenuLabel: GaudiTelemetryMenuLabel, - Architectures: []string{"x86_64"}, + Architectures: []string{cpus.X86Architecture}, HasRows: true, ScriptNames: []string{ script.GaudiTelemetryScriptName, @@ -1091,7 +1088,7 @@ func cpuTableInsights(outputs map[string]script.ScriptOutput, tableValues TableV slog.Warn(err.Error()) } else { family := tableValues.Fields[familyIndex].Values[0] - if family == "6" { // Intel + if cpus.IsIntelCPUFamilyStr(family) { // Intel uarchIndex, err := getFieldIndex("Microarchitecture", tableValues) if err != nil { slog.Warn(err.Error()) @@ -1107,6 +1104,7 @@ func cpuTableInsights(outputs map[string]script.ScriptOutput, tableValues TableV "SRF": 8, "CWF": 8, "GNR": 8, + "DMR": 9, } uarch := tableValues.Fields[uarchIndex].Values[0] if len(uarch) >= 3 { @@ -1458,7 +1456,7 @@ func memoryTableInsights(outputs map[string]script.ScriptOutput, tableValues Tab if populatedChannels != "" { uarch := UarchFromOutput(outputs) if uarch != "" { - cpu, err := GetCPUByMicroArchitecture(uarch) + cpu, err := cpus.GetCPUByMicroArchitecture(uarch) if err != nil { slog.Warn(err.Error()) } else { diff --git a/internal/report/table_helpers.go b/internal/report/table_helpers.go index 338474e7..a0d8b3a1 100644 --- a/internal/report/table_helpers.go +++ b/internal/report/table_helpers.go @@ -15,6 +15,7 @@ import ( "strings" "time" + "perfspect/internal/cpus" "perfspect/internal/script" "perfspect/internal/util" "slices" @@ -144,7 +145,7 @@ func UarchFromOutput(outputs map[string]script.ScriptOutput) string { stepping := valFromRegexSubmatch(outputs[script.LscpuScriptName].Stdout, `^Stepping:\s*(.+)$`) capid4 := valFromRegexSubmatch(outputs[script.LspciBitsScriptName].Stdout, `^([0-9a-fA-F]+)`) devices := valFromRegexSubmatch(outputs[script.LspciDevicesScriptName].Stdout, `^([0-9]+)`) - cpu, err := getCPUExtended(family, model, stepping, capid4, devices) + cpu, err := cpus.GetCPUExtended(family, model, stepping, capid4, devices) if err == nil { return cpu.MicroArchitecture } @@ -453,11 +454,11 @@ func hyperthreadingFromOutput(outputs map[string]script.ScriptOutput) string { stepping := valFromRegexSubmatch(outputs[script.LscpuScriptName].Stdout, `^Stepping:\s*(.+)$`) sockets := valFromRegexSubmatch(outputs[script.LscpuScriptName].Stdout, `^Socket\(s\):\s*(.+)$`) coresPerSocket := valFromRegexSubmatch(outputs[script.LscpuScriptName].Stdout, `^Core\(s\) per socket:\s*(.+)$`) - cpus := valFromRegexSubmatch(outputs[script.LscpuScriptName].Stdout, `^CPU\(.*:\s*(.+?)$`) + cpuCount := valFromRegexSubmatch(outputs[script.LscpuScriptName].Stdout, `^CPU\(.*:\s*(.+?)$`) onlineCpus := valFromRegexSubmatch(outputs[script.LscpuScriptName].Stdout, `^On-line CPU\(s\) list:\s*(.+)$`) threadsPerCore := valFromRegexSubmatch(outputs[script.LscpuScriptName].Stdout, `^Thread\(s\) per core:\s*(.+)$`) - numCPUs, err := strconv.Atoi(cpus) // logical CPUs + numCPUs, err := strconv.Atoi(cpuCount) // logical CPUs if err != nil { slog.Error("error parsing cpus from lscpu") return "" @@ -483,7 +484,7 @@ func hyperthreadingFromOutput(outputs map[string]script.ScriptOutput) string { slog.Error("error parsing cores per sockets from lscpu") return "" } - cpu, err := getCPUExtended(family, model, stepping, "", "") + cpu, err := cpus.GetCPUExtended(family, model, stepping, "", "") if err != nil { return "" } @@ -542,7 +543,7 @@ func channelsFromOutput(outputs map[string]script.ScriptOutput) string { stepping := valFromRegexSubmatch(outputs[script.LscpuScriptName].Stdout, `^Stepping:\s*(.+)$`) capid4 := valFromRegexSubmatch(outputs[script.LspciBitsScriptName].Stdout, `^([0-9a-fA-F]+)`) devices := valFromRegexSubmatch(outputs[script.LspciDevicesScriptName].Stdout, `^([0-9]+)`) - cpu, err := getCPUExtended(family, model, stepping, capid4, devices) + cpu, err := cpus.GetCPUExtended(family, model, stepping, capid4, devices) if err != nil { slog.Error("error getting CPU from CPUdb", slog.String("error", err.Error())) return "" @@ -553,7 +554,7 @@ func channelsFromOutput(outputs map[string]script.ScriptOutput) string { func turboEnabledFromOutput(outputs map[string]script.ScriptOutput) string { vendor := valFromRegexSubmatch(outputs[script.LscpuScriptName].Stdout, `^Vendor ID:\s*(.+)$`) switch vendor { - case "GenuineIntel": + case cpus.IntelVendor: val := valFromRegexSubmatch(outputs[script.CpuidScriptName].Stdout, `^Intel Turbo Boost Technology\s*= (.+?)$`) if val == "true" { return "Enabled" @@ -562,7 +563,7 @@ func turboEnabledFromOutput(outputs map[string]script.ScriptOutput) string { return "Disabled" } return "" // unknown value - case "AuthenticAMD": + case cpus.AMDVendor: val := valFromRegexSubmatch(outputs[script.LscpuScriptName].Stdout, `^Frequency boost.*:\s*(.+?)$`) if val != "" { return val + " (AMD Frequency Boost)" @@ -1832,7 +1833,7 @@ func systemSummaryFromOutput(outputs map[string]script.ScriptOutput) string { vendor := valFromRegexSubmatch(outputs[script.LscpuScriptName].Stdout, `^Vendor ID:\s*(.+)$`) // hyperthreading htLabel = "HT" - if vendor == "AuthenticAMD" { + if vendor == cpus.AMDVendor { htLabel = "SMT" } htOnOff = hyperthreadingFromOutput(outputs) @@ -1848,7 +1849,7 @@ func systemSummaryFromOutput(outputs map[string]script.ScriptOutput) string { } // turbo turboLabel = "Turbo" - if vendor == "AuthenticAMD" { + if vendor == cpus.AMDVendor { turboLabel = "Boost" } turboOnOff = turboEnabledFromOutput(outputs) diff --git a/internal/report/table_helpers_cache.go b/internal/report/table_helpers_cache.go index 2c883f57..16f3bf5c 100644 --- a/internal/report/table_helpers_cache.go +++ b/internal/report/table_helpers_cache.go @@ -7,6 +7,7 @@ import ( "encoding/json" "fmt" "log/slog" + "perfspect/internal/cpus" "perfspect/internal/script" "perfspect/internal/util" "strconv" @@ -19,7 +20,7 @@ import ( // cache size, even if some ways are disabled. func GetL3MSRMB(outputs map[string]script.ScriptOutput) (instance float64, total float64, err error) { uarch := UarchFromOutput(outputs) - cpu, err := GetCPUByMicroArchitecture(uarch) + cpu, err := cpus.GetCPUByMicroArchitecture(uarch) if err != nil { return 0, 0, err } diff --git a/internal/script/script.go b/internal/script/script.go index 51a598b1..598e9580 100644 --- a/internal/script/script.go +++ b/internal/script/script.go @@ -15,6 +15,7 @@ import ( "strconv" "strings" + "perfspect/internal/cpus" "perfspect/internal/target" "perfspect/internal/util" ) @@ -223,23 +224,28 @@ func scriptForTarget(script ScriptDefinition, myTarget target.Target) bool { return false } } - if len(script.Families) > 0 { + if len(script.MicroArchitectures) > 0 { family, err := myTarget.GetFamily() if err != nil { slog.Error("failed to get family for target", slog.String("target", myTarget.GetName()), slog.String("error", err.Error())) return false } - if !slices.Contains(script.Families, family) { - return false - } - } - if len(script.Models) > 0 { model, err := myTarget.GetModel() if err != nil { slog.Error("failed to get model for target", slog.String("target", myTarget.GetName()), slog.String("error", err.Error())) return false } - if !slices.Contains(script.Models, model) { + stepping, err := myTarget.GetStepping() + if err != nil { + slog.Error("failed to get stepping for target", slog.String("target", myTarget.GetName()), slog.String("error", err.Error())) + return false + } + cpu, err := cpus.GetCPU(family, model, stepping) + if err != nil { + slog.Error("failed to get CPU for target", slog.String("target", myTarget.GetName()), slog.String("error", err.Error())) + return false + } + if !slices.Contains(script.MicroArchitectures, cpu.GetMicroArchitecture()) && !slices.Contains(script.MicroArchitectures, cpu.GetShortMicroArchitecture()) { return false } } diff --git a/internal/script/script_defs.go b/internal/script/script_defs.go index 7b1fd36d..c71866dc 100644 --- a/internal/script/script_defs.go +++ b/internal/script/script_defs.go @@ -2,6 +2,7 @@ package script import ( "bytes" + "perfspect/internal/cpus" texttemplate "text/template" // nosemgrep ) @@ -11,17 +12,16 @@ import ( // script_defs.go defines the bash scripts that are used to collect information from target systems type ScriptDefinition struct { - Name string // just a name - ScriptTemplate string // the bash script that will be run - Architectures []string // architectures, i.e., x86_64, aarch64. If empty, it will run on all architectures. - Vendors []string // vendors, i.e., GenuineIntel, AuthenticAMD. If empty, it will run on all vendors. - Families []string // families, e.g., 6, 7. If empty, it will run on all families. - Models []string // models, e.g., 62, 63. If empty, it will run on all models. - Lkms []string // loadable kernel modules - Depends []string // binary dependencies that must be available for the script to run - Superuser bool // requires sudo or root - Sequential bool // run script sequentially (not at the same time as others) - NeedsKill bool // process/script needs to be killed after run without a duration specified, i.e., it doesn't stop through SIGINT + Name string // just a name + ScriptTemplate string // the bash script that will be run + Architectures []string // architectures, i.e., x86_64, aarch64. If empty, it will run on all architectures. + Vendors []string // vendors, i.e., GenuineIntel, AuthenticAMD. If empty, it will run on all vendors. + MicroArchitectures []string // microarchitectures, e.g., SPR, EMR. If empty, it will run on all microarchitectures. + Lkms []string // loadable kernel modules + Depends []string // binary dependencies that must be available for the script to run + Superuser bool // requires sudo or root + Sequential bool // run script sequentially (not at the same time as others) + NeedsKill bool // process/script needs to be killed after run without a duration specified, i.e., it doesn't stop through SIGINT } // script names, these must be unique @@ -122,10 +122,6 @@ const ( ProfileKernelLockScriptName = "profile kernel lock" ) -const ( - x86_64 = "x86_64" -) - // GetScriptByName returns the script definition with the given name. It will panic if the script is not found. func GetScriptByName(name string) ScriptDefinition { return GetParameterizedScriptByName(name, nil) @@ -180,19 +176,17 @@ var scriptDefinitions = map[string]ScriptDefinition{ ScriptTemplate: `lscpu -C -J`, }, LspciBitsScriptName: { - Name: LspciBitsScriptName, - ScriptTemplate: `lspci -s $(lspci | grep 325b | awk 'NR==1{{"{"}}print $1{{"}"}}') -xxx | awk '$1 ~ /^90/{{"{"}}print $9 $8 $7 $6; exit{{"}"}}'`, - Families: []string{"6"}, // Intel - Models: []string{"143", "207"}, // SPR, EMR - Superuser: true, - Depends: []string{"lspci"}, + Name: LspciBitsScriptName, + ScriptTemplate: `lspci -s $(lspci | grep 325b | awk 'NR==1{{"{"}}print $1{{"}"}}') -xxx | awk '$1 ~ /^90/{{"{"}}print $9 $8 $7 $6; exit{{"}"}}'`, + MicroArchitectures: []string{"SPR", "EMR"}, + Superuser: true, + Depends: []string{"lspci"}, }, LspciDevicesScriptName: { - Name: LspciDevicesScriptName, - ScriptTemplate: "lspci -d 8086:3258 | wc -l", - Families: []string{"6"}, // Intel - Models: []string{"173", "174", "175", "221"}, // GNR, GNR-D, SRF, CWF - Depends: []string{"lspci"}, + Name: LspciDevicesScriptName, + ScriptTemplate: "lspci -d 8086:3258 | wc -l", + MicroArchitectures: []string{"GNR", "GNR-D", "SRF", "CWF", "DMR"}, + Depends: []string{"lspci"}, }, LspciVmmScriptName: { Name: LspciVmmScriptName, @@ -305,24 +299,18 @@ else exit 1 fi `, - Architectures: []string{x86_64}, - Vendors: []string{"GenuineIntel"}, - Lkms: []string{"msr"}, - Depends: []string{"rdmsr"}, - Superuser: true, + Vendors: []string{cpus.IntelVendor}, + Lkms: []string{"msr"}, + Depends: []string{"rdmsr"}, + Superuser: true, }, SpecCoreFrequenciesScriptName: { Name: SpecCoreFrequenciesScriptName, ScriptTemplate: `lscpu=$(lscpu) family=$(echo "$lscpu" | grep -E "^CPU family:" | awk '{print $3}') model=$(echo "$lscpu" | grep -E "^Model:" | awk '{print $2}') -vendor=$(echo "$lscpu" | grep -E "^Vendor ID:" | awk '{print $3}') -# if vendor isn't Intel -if [ "$vendor" != "GenuineIntel" ]; then - exit 1 -fi -# if cpu is GNR get the frequencies from tpmi -if [ "$family" -eq 6 ] && [ "$model" -eq 173 ]; then # GNR +# if cpu is GNR, GNR-D, or DMR get the frequencies from tpmi +if ( [ "$family" -eq 6 ] && [ "$model" -eq 173 ] ) || ( [ "$family" -eq 6 ] && [ "$model" -eq 174 ] ) || ( [ "$family" -eq 19 ] && [ "$model" -eq 1 ] ); then # GNR, GNR-D, DMR cores=$(pcm-tpmi 0x5 0xD8 -i 0 -e 0 | tail -n 2 | head -n 1 | awk '{print $3}') # SST_PP_INFO_10 # this works unless the TRL is overridden on MSR 0x1AD --> sse=$(pcm-tpmi 0x5 0xA8 -i 0 -e 0 | tail -n 2 | head -n 1 | awk '{print $3}') # SST_PP_INFO_4 sse=$(rdmsr 0x1ad) # MSR_TURBO_RATIO_LIMIT: Maximum Ratio Limit of Turbo Mode @@ -353,17 +341,15 @@ else # not SRF, CWF or GNR fi echo "cores sse avx2 avx512 avx512h amx" echo "$cores" "$sse" "$avx2" "$avx512" "$avx512h" "$amx"`, - Architectures: []string{x86_64}, - Vendors: []string{"GenuineIntel"}, - Lkms: []string{"msr"}, - Depends: []string{"rdmsr", "pcm-tpmi"}, - Superuser: true, + Vendors: []string{cpus.IntelVendor}, + Lkms: []string{"msr"}, + Depends: []string{"rdmsr", "pcm-tpmi"}, + Superuser: true, }, PPINName: { Name: PPINName, ScriptTemplate: "rdmsr -a 0x4f", // MSR_PPIN: Protected Processor Inventory Number - Architectures: []string{x86_64}, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, Lkms: []string{"msr"}, Depends: []string{"rdmsr"}, Superuser: true, @@ -371,8 +357,7 @@ echo "$cores" "$sse" "$avx2" "$avx512" "$avx512h" "$amx"`, PrefetchControlName: { Name: PrefetchControlName, ScriptTemplate: "rdmsr -f 7:0 0x1a4", // MSR_PREFETCH_CONTROL: L2, DCU, and AMP Prefetchers enabled/disabled - Architectures: []string{x86_64}, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, Lkms: []string{"msr"}, Depends: []string{"rdmsr"}, Superuser: true, @@ -380,27 +365,24 @@ echo "$cores" "$sse" "$avx2" "$avx512" "$avx512h" "$amx"`, PrefetchersName: { Name: PrefetchersName, ScriptTemplate: "rdmsr 0x6d", // TODO: get name, used to read prefetchers - Architectures: []string{x86_64}, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, Lkms: []string{"msr"}, Depends: []string{"rdmsr"}, Superuser: true, }, PrefetchersAtomName: { - Name: PrefetchersAtomName, - ScriptTemplate: "rdmsr 0x1320", // Atom Pref_tuning1 - Architectures: []string{x86_64}, - Vendors: []string{"GenuineIntel"}, - Models: []string{"175", "221"}, // SRF, CWF - Lkms: []string{"msr"}, - Depends: []string{"rdmsr"}, - Superuser: true, + Name: PrefetchersAtomName, + ScriptTemplate: "rdmsr 0x1320", // Atom Pref_tuning1 + Vendors: []string{cpus.IntelVendor}, + MicroArchitectures: []string{"SRF", "CWF"}, // SRF, CWF + Lkms: []string{"msr"}, + Depends: []string{"rdmsr"}, + Superuser: true, }, L3CacheWayEnabledName: { Name: L3CacheWayEnabledName, ScriptTemplate: "rdmsr 0xc90", // TODO: get name, used to read l3 size - Architectures: []string{x86_64}, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, Lkms: []string{"msr"}, Depends: []string{"rdmsr"}, Superuser: true, @@ -408,8 +390,7 @@ echo "$cores" "$sse" "$avx2" "$avx512" "$avx512h" "$amx"`, PackagePowerLimitName: { Name: PackagePowerLimitName, ScriptTemplate: "rdmsr -f 14:0 0x610", // MSR_PKG_POWER_LIMIT: Package limit in bits 14:0 - Architectures: []string{x86_64}, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, Lkms: []string{"msr"}, Depends: []string{"rdmsr"}, Superuser: true, @@ -417,8 +398,7 @@ echo "$cores" "$sse" "$avx2" "$avx512" "$avx512h" "$amx"`, EpbSourceScriptName: { Name: EpbSourceScriptName, ScriptTemplate: "rdmsr -f 34:34 0x1FC", // MSR_POWER_CTL, PWR_PERF_TUNING_ALT_EPB: Energy Performance Bias Hint Source (1 is from BIOS, 0 is from OS) - Architectures: []string{x86_64}, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, Lkms: []string{"msr"}, Depends: []string{"rdmsr"}, Superuser: true, @@ -446,17 +426,15 @@ else fi fi echo "$epb"`, - Architectures: []string{x86_64}, - Vendors: []string{"GenuineIntel"}, - Lkms: []string{"msr"}, - Depends: []string{"rdmsr"}, - Superuser: true, + Vendors: []string{cpus.IntelVendor}, + Lkms: []string{"msr"}, + Depends: []string{"rdmsr"}, + Superuser: true, }, EppValidScriptName: { Name: EppValidScriptName, ScriptTemplate: "rdmsr -a -f 60:60 0x774", // IA32_HWP_REQUEST: Energy Performance Preference, bit 60 indicates if per-cpu EPP is valid - Architectures: []string{x86_64}, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, Lkms: []string{"msr"}, Depends: []string{"rdmsr"}, Superuser: true, @@ -464,8 +442,7 @@ echo "$epb"`, EppPackageControlScriptName: { Name: EppPackageControlScriptName, ScriptTemplate: "rdmsr -a -f 42:42 0x774", // IA32_HWP_REQUEST: Energy Performance Preference, bit 42 indicates if package control is enabled - Architectures: []string{x86_64}, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, Lkms: []string{"msr"}, Depends: []string{"rdmsr"}, Superuser: true, @@ -473,8 +450,7 @@ echo "$epb"`, EppScriptName: { Name: EppScriptName, ScriptTemplate: "rdmsr -a -f 31:24 0x774", // IA32_HWP_REQUEST: Energy Performance Preference, bits 24-31 (0 is highest perf, 255 is highest energy saving) - Architectures: []string{x86_64}, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, Lkms: []string{"msr"}, Depends: []string{"rdmsr"}, Superuser: true, @@ -482,8 +458,7 @@ echo "$epb"`, EppPackageScriptName: { Name: EppPackageScriptName, ScriptTemplate: "rdmsr -f 31:24 0x772", // IA32_HWP_REQUEST_PKG: Energy Performance Preference, bits 24-31 (0 is highest perf, 255 is highest energy saving) - Architectures: []string{x86_64}, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, Lkms: []string{"msr"}, Depends: []string{"rdmsr"}, Superuser: true, @@ -491,8 +466,7 @@ echo "$epb"`, UncoreMaxFromMSRScriptName: { Name: UncoreMaxFromMSRScriptName, ScriptTemplate: "rdmsr -f 6:0 0x620", // MSR_UNCORE_RATIO_LIMIT: MAX_RATIO in bits 6:0 - Architectures: []string{x86_64}, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, Lkms: []string{"msr"}, Depends: []string{"rdmsr"}, Superuser: true, @@ -500,38 +474,31 @@ echo "$epb"`, UncoreMinFromMSRScriptName: { Name: UncoreMinFromMSRScriptName, ScriptTemplate: "rdmsr -f 14:8 0x620", // MSR_UNCORE_RATIO_LIMIT: MAX_RATIO in bits 14:8 - Architectures: []string{x86_64}, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, Lkms: []string{"msr"}, Depends: []string{"rdmsr"}, Superuser: true, }, UncoreMaxFromTPMIScriptName: { - Name: UncoreMaxFromTPMIScriptName, - ScriptTemplate: "pcm-tpmi 2 0x18 -d -b 8:14", - Architectures: []string{x86_64}, - Families: []string{"6"}, // Intel - Models: []string{"173", "174", "175", "221"}, // GNR, GNR-D, SRF, CWF - Depends: []string{"pcm-tpmi"}, - Superuser: true, + Name: UncoreMaxFromTPMIScriptName, + ScriptTemplate: "pcm-tpmi 2 0x18 -d -b 8:14", + MicroArchitectures: []string{"GNR", "GNR-D", "SRF", "CWF", "DMR"}, + Depends: []string{"pcm-tpmi"}, + Superuser: true, }, UncoreMinFromTPMIScriptName: { - Name: UncoreMinFromTPMIScriptName, - ScriptTemplate: "pcm-tpmi 2 0x18 -d -b 15:21", - Architectures: []string{x86_64}, - Families: []string{"6"}, // Intel - Models: []string{"173", "174", "175", "221"}, // GNR, GNR-D, SRF, CWF - Depends: []string{"pcm-tpmi"}, - Superuser: true, + Name: UncoreMinFromTPMIScriptName, + ScriptTemplate: "pcm-tpmi 2 0x18 -d -b 15:21", + MicroArchitectures: []string{"GNR", "GNR-D", "SRF", "CWF", "DMR"}, + Depends: []string{"pcm-tpmi"}, + Superuser: true, }, UncoreDieTypesFromTPMIScriptName: { - Name: UncoreDieTypesFromTPMIScriptName, - ScriptTemplate: "pcm-tpmi 2 0x10 -d -b 26:26", - Architectures: []string{x86_64}, - Families: []string{"6"}, // Intel - Models: []string{"173", "174", "175", "221"}, // GNR, GNR-D, SRF, CWF - Depends: []string{"pcm-tpmi"}, - Superuser: true, + Name: UncoreDieTypesFromTPMIScriptName, + ScriptTemplate: "pcm-tpmi 2 0x10 -d -b 26:26", + MicroArchitectures: []string{"GNR", "GNR-D", "SRF", "CWF", "DMR"}, + Depends: []string{"pcm-tpmi"}, + Superuser: true, }, ElcScriptName: { Name: ElcScriptName, @@ -600,11 +567,9 @@ for die in "${!die_types[@]}"; do done <<< "$output" done `, - Architectures: []string{x86_64}, - Families: []string{"6"}, // Intel - Models: []string{"173", "174", "175", "221"}, // GNR, GNR-D, SRF, CWF - Depends: []string{"pcm-tpmi"}, - Superuser: true, + MicroArchitectures: []string{"GNR", "GNR-D", "SRF", "CWF", "DMR"}, + Depends: []string{"pcm-tpmi"}, + Superuser: true, }, SSTTFHPScriptName: { Name: SSTTFHPScriptName, @@ -677,11 +642,9 @@ do echo "" # finish the line done `, - Architectures: []string{x86_64}, - Families: []string{"6"}, // Intel - Models: []string{"173", "174"}, // GNR, GNR-D - Depends: []string{"pcm-tpmi"}, - Superuser: true, + MicroArchitectures: []string{"GNR", "GNR-D", "DMR"}, + Depends: []string{"pcm-tpmi"}, + Superuser: true, }, SSTTFLPScriptName: { Name: SSTTFLPScriptName, @@ -734,11 +697,9 @@ do done echo "" # finish the line `, - Architectures: []string{x86_64}, - Families: []string{"6"}, // Intel - Models: []string{"173", "174"}, // GNR, GNR-D - Depends: []string{"pcm-tpmi"}, - Superuser: true, + MicroArchitectures: []string{"GNR", "GNR-D", "DMR"}, + Depends: []string{"pcm-tpmi"}, + Superuser: true, }, ChaCountScriptName: { Name: ChaCountScriptName, @@ -746,11 +707,10 @@ echo "" # finish the line rdmsr 0x702 rdmsr 0x2FFE `, // uncore client cha count, uncore cha count, uncore cha count spr - Architectures: []string{x86_64}, - Vendors: []string{"GenuineIntel"}, - Lkms: []string{"msr"}, - Depends: []string{"rdmsr"}, - Superuser: true, + Vendors: []string{cpus.IntelVendor}, + Lkms: []string{"msr"}, + Depends: []string{"rdmsr"}, + Superuser: true, }, IaaDevicesScriptName: { Name: IaaDevicesScriptName, @@ -941,8 +901,7 @@ fi`, Name: PMUDriverVersionScriptName, ScriptTemplate: `dmesg | grep -A 1 "Intel PMU driver" | tail -1 | awk '{print $NF}'`, Superuser: true, - Architectures: []string{x86_64}, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, }, PMUBusyScriptName: { Name: PMUBusyScriptName, @@ -982,26 +941,25 @@ for i in "${pmu_counters[@]}"; do echo "Values: ${pmu_values[$i]}" done `, - Superuser: true, - Architectures: []string{x86_64}, - Vendors: []string{"GenuineIntel"}, - Lkms: []string{"msr"}, - Depends: []string{"rdmsr"}, + Superuser: true, + Vendors: []string{cpus.IntelVendor}, + Lkms: []string{"msr"}, + Depends: []string{"rdmsr"}, }, GaudiInfoScriptName: { Name: GaudiInfoScriptName, ScriptTemplate: `hl-smi -Q module_id,serial,bus_id,driver_version -f csv`, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, }, GaudiFirmwareScriptName: { Name: GaudiFirmwareScriptName, ScriptTemplate: `hl-smi --fw-version`, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, }, GaudiNumaScriptName: { Name: GaudiNumaScriptName, ScriptTemplate: `hl-smi topo -N`, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, }, GaudiArchitectureScriptName: { Name: GaudiArchitectureScriptName, @@ -1017,7 +975,7 @@ elif echo $__pcidev | grep -qE '106[0-9]'; then fi echo $__DEFAULT_HL_DEVICE `, - Vendors: []string{"GenuineIntel"}, + Vendors: []string{cpus.IntelVendor}, }, MemoryBenchmarkScriptName: { Name: MemoryBenchmarkScriptName, @@ -1034,11 +992,10 @@ fi mlc --loaded_latency -b500m -X echo $orig_num_huge_pages > /proc/sys/vm/nr_hugepages `, - Architectures: []string{x86_64}, - Superuser: true, - Lkms: []string{"msr"}, - Depends: []string{"mlc"}, - Sequential: true, + Superuser: true, + Lkms: []string{"msr"}, + Depends: []string{"mlc"}, + Sequential: true, }, NumaBenchmarkScriptName: { Name: NumaBenchmarkScriptName, @@ -1055,11 +1012,10 @@ fi mlc --bandwidth_matrix -b500m -X echo $orig_num_huge_pages > /proc/sys/vm/nr_hugepages `, - Architectures: []string{x86_64}, - Superuser: true, - Lkms: []string{"msr"}, - Depends: []string{"mlc"}, - Sequential: true, + Superuser: true, + Lkms: []string{"msr"}, + Depends: []string{"mlc"}, + Sequential: true, }, SpeedBenchmarkScriptName: { Name: SpeedBenchmarkScriptName, @@ -1075,7 +1031,7 @@ done }, FrequencyBenchmarkScriptName: { Name: FrequencyBenchmarkScriptName, - Architectures: []string{x86_64}, + Architectures: []string{cpus.X86Architecture}, ScriptTemplate: `# Function to expand a range of numbers, e.g. "0-24", into an array of numbers expand_range() { local range=$1 @@ -1166,7 +1122,7 @@ avx-turbo --min-threads=1 --max-threads=$num_cores_per_socket --test scalar_iadd }, PowerBenchmarkScriptName: { Name: PowerBenchmarkScriptName, - Architectures: []string{x86_64}, + Architectures: []string{cpus.X86Architecture}, ScriptTemplate: `((turbostat -i 2 2>/dev/null &) ; stress-ng --cpu 0 --bsearch 0 -t 60s >/dev/null 2>&1 ; pkill -9 -f turbostat)`, Superuser: true, Lkms: []string{"msr"}, @@ -1175,7 +1131,7 @@ avx-turbo --min-threads=1 --max-threads=$num_cores_per_socket --test scalar_iadd }, IdlePowerBenchmarkScriptName: { Name: IdlePowerBenchmarkScriptName, - Architectures: []string{x86_64}, + Architectures: []string{cpus.X86Architecture}, ScriptTemplate: `turbostat -i 2 -n 2 2>/dev/null`, Superuser: true, Lkms: []string{"msr"}, @@ -1293,7 +1249,7 @@ wait }, TurbostatTelemetryScriptName: { Name: TurbostatTelemetryScriptName, - Architectures: []string{x86_64}, + Architectures: []string{cpus.X86Architecture}, ScriptTemplate: `interval={{.Interval}} duration={{.Duration}} if [ $duration -ne 0 ] && [ $interval -ne 0 ]; then