Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions cmd/config/config_tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,11 @@ func configurationTableValues(outputs map[string]script.ScriptOutput) []table.Fi
fields = append(fields, []table.Field{
{Name: "Energy Performance Bias", Description: "--epb <0-15>", Values: []string{extract.EPBFromOutput(outputs)}},
{Name: "Energy Performance Preference", Description: "--epp <0-255>", Values: []string{extract.EPPFromOutput(outputs)}},
{Name: "Scaling Governor", Description: "--gov <performance|powersave>", Values: []string{strings.TrimSpace(outputs[script.ScalingGovernorScriptName].Stdout)}},
{Name: "Scaling Governor", Description: "--gov <" + strings.Join(governorOptions, "|") + ">", Values: []string{strings.TrimSpace(outputs[script.ScalingGovernorScriptName].Stdout)}},
}...)
// add ELC (for SRF, CWF and GNR only)
if strings.Contains(uarch, cpus.UarchSRF) || strings.Contains(uarch, cpus.UarchGNR) || strings.Contains(uarch, cpus.UarchCWF) {
fields = append(fields, table.Field{Name: "Efficiency Latency Control", Description: "--elc <default|latency-optimized>", Values: []string{extract.ELCSummaryFromOutput(outputs)}})
fields = append(fields, table.Field{Name: "Efficiency Latency Control", Description: "--elc <" + strings.Join(elcOptions, "|") + ">", Values: []string{extract.ELCSummaryFromOutput(outputs)}})
}
// add prefetchers
for _, pf := range extract.PrefetcherDefinitions {
Expand Down Expand Up @@ -123,20 +123,20 @@ func configurationTableValues(outputs map[string]script.ScriptOutput) []table.Fi
fields = append(fields,
table.Field{
Name: pf.ShortName + " prefetcher",
Description: "--" + "pref-" + strings.ReplaceAll(strings.ToLower(pf.ShortName), " ", "") + " <enable|disable>",
Description: "--" + "pref-" + strings.ReplaceAll(strings.ToLower(pf.ShortName), " ", "") + " <" + strings.Join(prefetcherOptions, "|") + ">",
Values: []string{enabledDisabled}},
)
}
}
// add C6
c6 := extract.C6FromOutput(outputs)
if c6 != "" {
fields = append(fields, table.Field{Name: "C6", Description: "--c6 <enable|disable>", Values: []string{c6}})
fields = append(fields, table.Field{Name: "C6", Description: "--c6 <" + strings.Join(c6Options, "|") + ">", Values: []string{c6}})
}
// add C1 Demotion
c1Demotion := strings.TrimSpace(outputs[script.C1DemotionScriptName].Stdout)
if c1Demotion != "" {
fields = append(fields, table.Field{Name: "C1 Demotion", Description: "--c1-demotion <enable|disable>", Values: []string{c1Demotion}})
fields = append(fields, table.Field{Name: "C1 Demotion", Description: "--c1-demotion <" + strings.Join(c1DemotionOptions, "|") + ">", Values: []string{c1Demotion}})
}
return fields
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/config/flag_groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ const (
var governorOptions = []string{"performance", "powersave"}

// elcOptions - list of valid elc options
var elcOptions = []string{"latency-optimized", "default"}
var elcOptions = []string{"latency", "power"}

// prefetcherOptions - list of valid prefetcher options
var prefetcherOptions = []string{"enable", "disable"}
Expand Down
9 changes: 2 additions & 7 deletions cmd/config/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -353,13 +353,8 @@ func convertValue(flagName string, rawValue string) (string, error) {
// "performance" or "powersave"
return parseEnableDisableOrOption(rawValue, governorOptions)
case flagELCName:
// "Default" -> "default"
// "Latency-Optimized" -> "latency-optimized"
rawValueLower := strings.ToLower(rawValue)
if slices.Contains(elcOptions, rawValueLower) {
return rawValueLower, nil
}
return "", fmt.Errorf("invalid elc value: %s", rawValue)
// "power" or "latency"
return parseEnableDisableOrOption(rawValue, elcOptions)
case flagC6Name:
return parseEnableDisableOrOption(rawValue, c6Options)
case flagC1DemotionName:
Expand Down
4 changes: 2 additions & 2 deletions cmd/config/restore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ func TestConvertValue(t *testing.T) {
{"Prefetcher enabled", "pref-l2hw", "Enabled", "enable", false},
{"Prefetcher disabled", "pref-l2hw", "Disabled", "disable", false},
{"C6 enabled", "c6", "Enabled", "enable", false},
{"ELC lowercase", "elc", "default", "default", false},
{"ELC capitalized", "elc", "Default", "default", false},
{"ELC lowercase", "elc", "power", "power", false},
{"ELC capitalized", "elc", "Power", "power", false},
{"Core SSE freq buckets", "core-max-buckets", "1-44/3.6, 45-52/3.5, 53-60/3.4", "1-44/3.6, 45-52/3.5, 53-60/3.4", false},
{"Core SSE freq buckets full", "core-max-buckets", "1-44/3.6, 45-52/3.5, 53-60/3.4, 61-72/3.2, 73-76/3.1, 77-86/3.0", "1-44/3.6, 45-52/3.5, 53-60/3.4, 61-72/3.2, 73-76/3.1, 77-86/3.0", false},
{"Core SSE freq buckets invalid", "core-max-buckets", "invalid-format", "", true},
Expand Down
89 changes: 76 additions & 13 deletions cmd/config/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -775,31 +775,94 @@ func setGovernor(governor string, myTarget target.Target, localTempDir string) e
return err
}

func setELC(elc string, myTarget target.Target, localTempDir string) error {
var mode string
switch elc {
case elcOptions[0]:
mode = "latency-optimized-mode"
case elcOptions[1]:
mode = "default"
default:
return fmt.Errorf("invalid ELC mode: %s", elc)
// setELCOPM sets ELC to Optimized Power Mode (OPM)
func setELCOPM(myTarget target.Target, localTempDir string) error {
// The script is derived from bhs-power-mode script in the Intel PCM repository.
setScript := script.ScriptDefinition{
Name: "set elc opm",
ScriptTemplate: `
# determine I/O and compute dies
output=$(pcm-tpmi 2 0x10 -d -b 26:26)

# Parse the output to build lists of I/O and compute dies
io_dies=()
compute_dies=()
declare -A die_types
while read -r line; do
if [[ $line == *"instance 0"* ]]; then
die=$(echo "$line" | grep -oP 'entry \K[0-9]+')
if [[ $line == *"value 1"* ]]; then
die_types[$die]="IO"
io_dies+=("$die")
elif [[ $line == *"value 0"* ]]; then
die_types[$die]="Compute"
compute_dies+=("$die")
fi
fi
done <<< "$output"

# Set ELC parameters for I/O and Compute dies
# set values common to both die types
pcm-tpmi 2 0x18 -d -b 39:39 -w 1 # EFFICIENCY_LATENCY_CTRL_HIGH_THRESHOLD_ENABLE
pcm-tpmi 2 0x18 -d -b 46:40 -w 120 # EFFICIENCY_LATENCY_CTRL_HIGH_THRESHOLD (120 / 127 ~= 94%)
pcm-tpmi 2 0x18 -d -b 38:32 -w 13 # EFFICIENCY_LATENCY_CTRL_LOW_THRESHOLD (13 / 127 ~= 10%)

# set values for I/O Dies
for die in "${io_dies[@]}"; do
pcm-tpmi 2 0x18 -d -e $die -b 28:22 -w 8 # EFFICIENCY_LATENCY_CTRL_RATIO 0.8 GHz for I/O Dies
done

# set values for Compute Dies
for die in "${compute_dies[@]}"; do
pcm-tpmi 2 0x18 -d -e $die -b 28:22 -w 12 # EFFICIENCY_LATENCY_CTRL_RATIO 1.2 GHz for Compute Dies
done
`,
Superuser: true,
Vendors: []string{cpus.IntelVendor},
MicroArchitectures: []string{cpus.UarchGNR, cpus.UarchGNR_D, cpus.UarchSRF, cpus.UarchCWF},
Depends: []string{"pcm-tpmi"},
}
_, err := runScript(myTarget, setScript, localTempDir)
if err != nil {
err = fmt.Errorf("failed to set ELC OPM mode: %w", err)
}
return err
}

// setELCLOM sets ELC to Latency Optimized Mode (LOM)
func setELCLOM(myTarget target.Target, localTempDir string) error {
// The script is derived from bhs-power-mode script in the Intel PCM repository.
setScript := script.ScriptDefinition{
Name: "set elc",
ScriptTemplate: fmt.Sprintf("bhs-power-mode.sh --%s", mode),
Name: "set elc lom",
ScriptTemplate: `
pcm-tpmi 2 0x18 -d -b 39:39 -w 1 # EFFICIENCY_LATENCY_CTRL_HIGH_THRESHOLD_ENABLE
pcm-tpmi 2 0x18 -d -b 28:22 -w 0 # EFFICIENCY_LATENCY_CTRL_RATIO
pcm-tpmi 2 0x18 -d -b 46:40 -w 0 # EFFICIENCY_LATENCY_CTRL_HIGH_THRESHOLD
pcm-tpmi 2 0x18 -d -b 38:32 -w 0 # EFFICIENCY_LATENCY_CTRL_LOW_THRESHOLD
`,
Superuser: true,
Vendors: []string{cpus.IntelVendor},
MicroArchitectures: []string{cpus.UarchGNR, cpus.UarchGNR_D, cpus.UarchSRF, cpus.UarchCWF},
Depends: []string{"bhs-power-mode.sh", "pcm-tpmi"},
Depends: []string{"pcm-tpmi"},
}
_, err := runScript(myTarget, setScript, localTempDir)
if err != nil {
err = fmt.Errorf("failed to set ELC mode: %w", err)
err = fmt.Errorf("failed to set ELC LOM mode: %w", err)
}
return err
}

func setELC(elc string, myTarget target.Target, localTempDir string) error {
switch elc {
case elcOptions[0]:
return setELCLOM(myTarget, localTempDir)
case elcOptions[1]:
return setELCOPM(myTarget, localTempDir)
default:
return fmt.Errorf("invalid ELC mode: %s", elc)
}
}

func getUarch(myTarget target.Target, localTempDir string) (string, error) {
scripts := []script.ScriptDefinition{}
scripts = append(scripts, script.GetScriptByName(script.LscpuScriptName))
Expand Down
26 changes: 19 additions & 7 deletions cmd/report/report_tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,10 @@ var tableDefinitions = map[string]table.TableDefinition{
script.EtcReleaseScriptName,
script.PackagePowerLimitName,
script.EpbScriptName,
script.EppScriptName,
script.EppValidScriptName,
script.EppPackageControlScriptName,
script.EppPackageScriptName,
script.ScalingDriverScriptName,
script.ScalingGovernorScriptName,
script.CstatesScriptName,
Expand Down Expand Up @@ -853,31 +857,39 @@ func elcTableInsights(outputs map[string]script.ScriptOutput, tableValues table.
}
// suggest setting ELC mode to 'Latency Optimized' or 'Default' based on the current setting
for _, mode := range tableValues.Fields[modeFieldIndex].Values {
if mode != "" && mode != "Latency Optimized" {
if mode != "" && mode != extract.ELCModeLatencyOptimized {
insights = append(insights, table.Insight{
Recommendation: "Consider setting Efficiency Latency Control mode to 'Latency Optimized' when workload is highly sensitive to memory latency.",
Recommendation: "Consider setting Efficiency Latency Control mode to 'Latency Optimized Mode (LOM)' when workload is highly sensitive to memory latency.",
Justification: fmt.Sprintf("ELC mode is set to '%s' on at least one die.", mode),
})
break
}
}
for _, mode := range tableValues.Fields[modeFieldIndex].Values {
if mode != "" && mode != "Default" {
if mode != "" && mode != extract.ELCModeOptimizedPower {
insights = append(insights, table.Insight{
Recommendation: "Consider setting Efficiency Latency Control mode to 'Default' to balance uncore performance and power utilization.",
Recommendation: "Consider setting Efficiency Latency Control mode to 'Optimized Power Mode (OPM)' to balance uncore performance and power utilization.",
Justification: fmt.Sprintf("ELC mode is set to '%s' on at least one die.", mode),
})
break
}
}
// if epb is not set to 'Performance (0)' and ELC mode is set to 'Latency Optimized', suggest setting epb to 'Performance (0)'
// if epb is not set to 'Performance (0)' and ELC mode is set to 'Latency Optimized Mode (LOM)', suggest setting epb to 'Performance (0)'
epb := extract.EPBFromOutput(outputs)
if epb != "" && epb != "Performance (0)" && firstMode == "Latency Optimized" {
if epb != "" && epb != "Performance (0)" && firstMode == extract.ELCModeLatencyOptimized {
insights = append(insights, table.Insight{
Recommendation: "Consider setting Energy Performance Bias to 'Performance (0)' to allow Latency Optimized mode to operate as designed.",
Recommendation: "Consider setting Energy Performance Bias to 'Performance (0)' to allow Latency Optimized Mode (LOM) to operate as designed.",
Justification: fmt.Sprintf("Energy Performance Bias is set to '%s' and ELC Mode is set to '%s'.", epb, firstMode),
})
}
// if epp is not set to 'Performance (0)' and ELC mode is set to 'Latency Optimized Mode (LOM)', suggest setting epp to 'Performance (0)'
epp := extract.EPPFromOutput(outputs)
if epp != "" && epp != "Performance (0)" && firstMode == extract.ELCModeLatencyOptimized {
insights = append(insights, table.Insight{
Recommendation: "Consider setting Energy Performance Preference to 'Performance (0)' to allow Latency Optimized Mode (LOM) to operate as designed.",
Justification: fmt.Sprintf("Energy Performance Preference is set to '%s' and ELC Mode is set to '%s'.", epp, firstMode),
})
}
}
return insights
}
Expand Down
59 changes: 39 additions & 20 deletions internal/extract/power.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,25 @@ func CstatesFromOutput(outputs map[string]script.ScriptOutput) []CstateInfo {
return cstatesInfo
}

// enum for the column indices in the ELC CSV output
const (
elcFieldSocketID = iota
elcFieldDie
elcFieldDieType
elcFieldMinRatio
elcFieldMaxRatio
elcFieldELCRatio
elcFieldELCLowThreshold
elcFieldELCHighThreshold
elcFieldELCHighThresholdEnable
)

const (
ELCModeLatencyOptimized = "Latency Optimized Mode (LOM)"
ELCModeOptimizedPower = "Optimized Power Mode (OPM)"
ELCModeCustom = "Custom Mode"
)

// ELCFieldValuesFromOutput extracts Efficiency Latency Control field values.
func ELCFieldValuesFromOutput(outputs map[string]script.ScriptOutput) (fieldValues []table.Field) {
if outputs[script.ElcScriptName].Stdout == "" {
Expand All @@ -189,6 +208,13 @@ func ELCFieldValuesFromOutput(outputs map[string]script.ScriptOutput) (fieldValu
if len(rows) < 2 {
return
}
// confirm rows have expected number of columns
for _, row := range rows {
if len(row) < elcFieldELCHighThresholdEnable+1 {
slog.Warn("ELC script output has unexpected number of columns", slog.Int("expected", elcFieldELCHighThresholdEnable+1), slog.Int("actual", len(row)))
return
}
}
for fieldNamesIndex, fieldName := range rows[0] {
values := []string{}
for _, row := range rows[1:] {
Expand All @@ -197,30 +223,23 @@ func ELCFieldValuesFromOutput(outputs map[string]script.ScriptOutput) (fieldValu
fieldValues = append(fieldValues, table.Field{Name: fieldName, Values: values})
}

values := []string{}
modeValues := []string{}
for _, row := range rows[1:] {
var mode string
if len(row) > 7 && row[2] == "IO" {
if row[5] == "0" && row[6] == "0" && row[7] == "0" {
mode = "Latency Optimized"
} else if row[5] == "800" && row[6] == "10" && row[7] == "94" {
mode = "Default"
} else {
mode = "Custom"
}
} else if len(row) > 5 {
switch row[5] {
case "0":
mode = "Latency Optimized"
case "1200":
mode = "Default"
default:
mode = "Custom"
}
if row[elcFieldELCRatio] == "0" && row[elcFieldELCLowThreshold] == "0" && row[elcFieldELCHighThreshold] == "0" && row[elcFieldELCHighThresholdEnable] == "1" {
mode = ELCModeLatencyOptimized
} else if row[elcFieldELCLowThreshold] == "10" &&
row[elcFieldELCHighThreshold] == "94" &&
row[elcFieldELCHighThresholdEnable] == "1" &&
((row[elcFieldDieType] == "IO" && row[elcFieldELCRatio] == "800") ||
(row[elcFieldDieType] == "Compute" && row[elcFieldELCRatio] == "1200")) {
mode = ELCModeOptimizedPower
} else {
mode = ELCModeCustom
}
values = append(values, mode)
modeValues = append(modeValues, mode)
}
fieldValues = append(fieldValues, table.Field{Name: "Mode", Values: values})
fieldValues = append(fieldValues, table.Field{Name: "Mode", Values: modeValues})
return
}

Expand Down
1 change: 0 additions & 1 deletion tools/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ tools-x86_64: async-profiler avx-turbo cpuid dmidecode ethtool fio ipmitool lshw
cp msr-tools/rdmsr bin/x86_64/
cp msr-tools/wrmsr bin/x86_64/
cp pcm/build/bin/pcm-tpmi bin/x86_64/
cp pcm/scripts/bhs-power-mode.sh bin/x86_64/
cp perf-archive/perf-archive.sh bin/x86_64/perf-archive && chmod +rx bin/x86_64/perf-archive
cp spectre-meltdown-checker/spectre-meltdown-checker.sh bin/x86_64/
cp sshpass/sshpass bin/x86_64/
Expand Down
Loading