Skip to content

Commit 4cce9c2

Browse files
committed
refactor: update ELC options and improve mode handling in configuration
Signed-off-by: Harper, Jason M <[email protected]>
1 parent 327d946 commit 4cce9c2

File tree

6 files changed

+133
-50
lines changed

6 files changed

+133
-50
lines changed

cmd/config/flag_groups.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ const (
7676
var governorOptions = []string{"performance", "powersave"}
7777

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

8181
// prefetcherOptions - list of valid prefetcher options
8282
var prefetcherOptions = []string{"enable", "disable"}

cmd/config/restore.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -353,13 +353,8 @@ func convertValue(flagName string, rawValue string) (string, error) {
353353
// "performance" or "powersave"
354354
return parseEnableDisableOrOption(rawValue, governorOptions)
355355
case flagELCName:
356-
// "Power-Optimized" -> "power-optimized"
357-
// "Latency-Optimized" -> "latency-optimized"
358-
rawValueLower := strings.ToLower(rawValue)
359-
if slices.Contains(elcOptions, rawValueLower) {
360-
return rawValueLower, nil
361-
}
362-
return "", fmt.Errorf("invalid elc value: %s", rawValue)
356+
// "power" or "latency"
357+
return parseEnableDisableOrOption(rawValue, elcOptions)
363358
case flagC6Name:
364359
return parseEnableDisableOrOption(rawValue, c6Options)
365360
case flagC1DemotionName:

cmd/config/set.go

Lines changed: 74 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -775,31 +775,92 @@ func setGovernor(governor string, myTarget target.Target, localTempDir string) e
775775
return err
776776
}
777777

778-
func setELC(elc string, myTarget target.Target, localTempDir string) error {
779-
var mode string
780-
switch elc {
781-
case elcOptions[0]:
782-
mode = "latency-optimized-mode"
783-
case elcOptions[1]:
784-
mode = "optimized-power-mode"
785-
default:
786-
return fmt.Errorf("invalid ELC mode: %s", elc)
778+
// setELCOPM sets ELC to Optimized Power Mode (OPM)
779+
func setELCOPM(myTarget target.Target, localTempDir string) error {
780+
setScript := script.ScriptDefinition{
781+
Name: "set elc opm",
782+
ScriptTemplate: `
783+
# determine I/O and compute dies
784+
output=$(pcm-tpmi 2 0x10 -d -b 26:26)
785+
786+
# Parse the output to build lists of I/O and compute dies
787+
io_dies=()
788+
compute_dies=()
789+
declare -A die_types
790+
while read -r line; do
791+
if [[ $line == *"instance 0"* ]]; then
792+
die=$(echo "$line" | grep -oP 'entry \K[0-9]+')
793+
if [[ $line == *"value 1"* ]]; then
794+
die_types[$die]="IO"
795+
io_dies+=("$die")
796+
elif [[ $line == *"value 0"* ]]; then
797+
die_types[$die]="Compute"
798+
compute_dies+=("$die")
799+
fi
800+
fi
801+
done <<< "$output"
802+
803+
# Set ELC parameters for I/O and Compute dies
804+
# set values common to both die types
805+
pcm-tpmi 2 0x18 -d -b 39:39 -w 1 # EFFICIENCY_LATENCY_CTRL_HIGH_THRESHOLD_ENABLE
806+
pcm-tpmi 2 0x18 -d -b 46:40 -w 95 # EFFICIENCY_LATENCY_CTRL_HIGH_THRESHOLD
807+
pcm-tpmi 2 0x18 -d -b 38:32 -w 10 # EFFICIENCY_LATENCY_CTRL_LOW_THRESHOLD
808+
809+
# set values for I/O Dies
810+
for die in "${io_dies[@]}"; do
811+
pcm-tpmi 2 0x18 -d -e $die -b 28:22 -w 8 # EFFICIENCY_LATENCY_CTRL_RATIO 0.8 GHz for I/O Dies
812+
done
813+
814+
# set values for Compute Dies
815+
for die in "${compute_dies[@]}"; do
816+
pcm-tpmi 2 0x18 -d -e $die -b 28:22 -w 12 # EFFICIENCY_LATENCY_CTRL_RATIO 1.2 GHz for Compute Dies
817+
done
818+
`,
819+
Superuser: true,
820+
Vendors: []string{cpus.IntelVendor},
821+
MicroArchitectures: []string{cpus.UarchGNR, cpus.UarchGNR_D, cpus.UarchSRF, cpus.UarchCWF},
822+
Depends: []string{"pcm-tpmi"},
787823
}
824+
_, err := runScript(myTarget, setScript, localTempDir)
825+
if err != nil {
826+
err = fmt.Errorf("failed to set ELC OPM mode: %w", err)
827+
}
828+
return err
829+
}
830+
831+
// setELCLOM sets ELC to Latency Optimized Mode (LOM)
832+
func setELCLOM(myTarget target.Target, localTempDir string) error {
788833
setScript := script.ScriptDefinition{
789-
Name: "set elc",
790-
ScriptTemplate: fmt.Sprintf("bhs-power-mode.sh --%s", mode),
834+
Name: "set elc lom",
835+
ScriptTemplate: `
836+
pcm-tpmi 2 0x18 -d -b 39:39 -w 1 # EFFICIENCY_LATENCY_CTRL_HIGH_THRESHOLD_ENABLE
837+
pcm-tpmi 2 0x18 -d -b 28:22 -w 0 # EFFICIENCY_LATENCY_CTRL_RATIO
838+
pcm-tpmi 2 0x18 -d -b 46:40 -w 0 # EFFICIENCY_LATENCY_CTRL_HIGH_THRESHOLD
839+
pcm-tpmi 2 0x18 -d -b 38:32 -w 0 # EFFICIENCY_LATENCY_CTRL_LOW_THRESHOLD
840+
`,
791841
Superuser: true,
792842
Vendors: []string{cpus.IntelVendor},
793843
MicroArchitectures: []string{cpus.UarchGNR, cpus.UarchGNR_D, cpus.UarchSRF, cpus.UarchCWF},
794-
Depends: []string{"bhs-power-mode.sh", "pcm-tpmi"},
844+
Depends: []string{"pcm-tpmi"},
795845
}
796846
_, err := runScript(myTarget, setScript, localTempDir)
797847
if err != nil {
798-
err = fmt.Errorf("failed to set ELC mode: %w", err)
848+
err = fmt.Errorf("failed to set ELC LOM mode: %w", err)
799849
}
800850
return err
801851
}
802852

853+
func setELC(elc string, myTarget target.Target, localTempDir string) error {
854+
switch elc {
855+
case elcOptions[0]:
856+
return setELCLOM(myTarget, localTempDir)
857+
case elcOptions[1]:
858+
return setELCOPM(myTarget, localTempDir)
859+
default:
860+
return fmt.Errorf("invalid ELC mode: %s", elc)
861+
}
862+
}
863+
803864
func getUarch(myTarget target.Target, localTempDir string) (string, error) {
804865
scripts := []script.ScriptDefinition{}
805866
scripts = append(scripts, script.GetScriptByName(script.LscpuScriptName))

cmd/report/report_tables.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -853,31 +853,39 @@ func elcTableInsights(outputs map[string]script.ScriptOutput, tableValues table.
853853
}
854854
// suggest setting ELC mode to 'Latency Optimized' or 'Default' based on the current setting
855855
for _, mode := range tableValues.Fields[modeFieldIndex].Values {
856-
if mode != "" && mode != "Latency Optimized" {
856+
if mode != "" && mode != extract.ELCModeLatencyOptimized {
857857
insights = append(insights, table.Insight{
858-
Recommendation: "Consider setting Efficiency Latency Control mode to 'Latency Optimized' when workload is highly sensitive to memory latency.",
858+
Recommendation: "Consider setting Efficiency Latency Control mode to 'Latency Optimized Mode (LOM)' when workload is highly sensitive to memory latency.",
859859
Justification: fmt.Sprintf("ELC mode is set to '%s' on at least one die.", mode),
860860
})
861861
break
862862
}
863863
}
864864
for _, mode := range tableValues.Fields[modeFieldIndex].Values {
865-
if mode != "" && mode != "Power Optimized" {
865+
if mode != "" && mode != extract.ELCModeOptimizedPower {
866866
insights = append(insights, table.Insight{
867-
Recommendation: "Consider setting Efficiency Latency Control mode to 'Power Optimized' to balance uncore performance and power utilization.",
867+
Recommendation: "Consider setting Efficiency Latency Control mode to 'Optimized Power Mode (OPM)' to balance uncore performance and power utilization.",
868868
Justification: fmt.Sprintf("ELC mode is set to '%s' on at least one die.", mode),
869869
})
870870
break
871871
}
872872
}
873-
// if epb is not set to 'Performance (0)' and ELC mode is set to 'Latency Optimized', suggest setting epb to 'Performance (0)'
873+
// if epb is not set to 'Performance (0)' and ELC mode is set to 'Latency Optimized Mode (LOM)', suggest setting epb to 'Performance (0)'
874874
epb := extract.EPBFromOutput(outputs)
875-
if epb != "" && epb != "Performance (0)" && firstMode == "Latency Optimized" {
875+
if epb != "" && epb != "Performance (0)" && firstMode == extract.ELCModeLatencyOptimized {
876876
insights = append(insights, table.Insight{
877-
Recommendation: "Consider setting Energy Performance Bias to 'Performance (0)' to allow Latency Optimized mode to operate as designed.",
877+
Recommendation: "Consider setting Energy Performance Bias to 'Performance (0)' to allow Latency Optimized Mode (LOM) to operate as designed.",
878878
Justification: fmt.Sprintf("Energy Performance Bias is set to '%s' and ELC Mode is set to '%s'.", epb, firstMode),
879879
})
880880
}
881+
// if epp is not set to 'Performance (0)' and ELC mode is set to 'Latency Optimized Mode (LOM)', suggest setting epp to 'Performance (0)'
882+
epp := extract.EPPFromOutput(outputs)
883+
if epp != "" && epp != "Performance (0)" && firstMode == extract.ELCModeLatencyOptimized {
884+
insights = append(insights, table.Insight{
885+
Recommendation: "Consider setting Energy Performance Preference to 'Performance (0)' to allow Latency Optimized Mode (LOM) to operate as designed.",
886+
Justification: fmt.Sprintf("Energy Performance Preference is set to '%s' and ELC Mode is set to '%s'.", epp, firstMode),
887+
})
888+
}
881889
}
882890
return insights
883891
}

internal/extract/power.go

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,25 @@ func CstatesFromOutput(outputs map[string]script.ScriptOutput) []CstateInfo {
176176
return cstatesInfo
177177
}
178178

179+
// enum for the column indices in the ELC CSV output
180+
const (
181+
elcFieldSocketID = iota
182+
elcFieldDie
183+
elcFieldDieType
184+
elcFieldMinRatio
185+
elcFieldMaxRatio
186+
elcFieldELCRatio
187+
elcFieldELCLowThreshold
188+
elcFieldELCHighThreshold
189+
elcFieldELCHighThresholdEnable
190+
)
191+
192+
const (
193+
ELCModeLatencyOptimized = "Latency Optimized Mode (LOM)"
194+
ELCModeOptimizedPower = "Optimized Power Mode (OPM)"
195+
ELCModeCustom = "Custom Mode"
196+
)
197+
179198
// ELCFieldValuesFromOutput extracts Efficiency Latency Control field values.
180199
func ELCFieldValuesFromOutput(outputs map[string]script.ScriptOutput) (fieldValues []table.Field) {
181200
if outputs[script.ElcScriptName].Stdout == "" {
@@ -189,6 +208,13 @@ func ELCFieldValuesFromOutput(outputs map[string]script.ScriptOutput) (fieldValu
189208
if len(rows) < 2 {
190209
return
191210
}
211+
// confirm rows have expected number of columns
212+
for _, row := range rows {
213+
if len(row) < elcFieldELCHighThresholdEnable+1 {
214+
slog.Warn("ELC script output has unexpected number of columns", slog.Int("expected", elcFieldELCHighThresholdEnable+1), slog.Int("actual", len(row)))
215+
return
216+
}
217+
}
192218
for fieldNamesIndex, fieldName := range rows[0] {
193219
values := []string{}
194220
for _, row := range rows[1:] {
@@ -197,30 +223,23 @@ func ELCFieldValuesFromOutput(outputs map[string]script.ScriptOutput) (fieldValu
197223
fieldValues = append(fieldValues, table.Field{Name: fieldName, Values: values})
198224
}
199225

200-
values := []string{}
226+
modeValues := []string{}
201227
for _, row := range rows[1:] {
202228
var mode string
203-
if len(row) > 7 && row[2] == "IO" {
204-
if row[5] == "0" && row[6] == "0" && row[7] == "0" {
205-
mode = "Latency Optimized"
206-
} else if row[5] == "800" && row[6] == "10" && row[7] == "94" {
207-
mode = "Power Optimized"
208-
} else {
209-
mode = "Custom"
210-
}
211-
} else if len(row) > 5 {
212-
switch row[5] {
213-
case "0":
214-
mode = "Latency Optimized"
215-
case "1200":
216-
mode = "Power Optimized"
217-
default:
218-
mode = "Custom"
219-
}
229+
if row[elcFieldELCRatio] == "0" && row[elcFieldELCLowThreshold] == "0" && row[elcFieldELCHighThreshold] == "0" && row[elcFieldELCHighThresholdEnable] == "1" {
230+
mode = ELCModeLatencyOptimized
231+
} else if row[elcFieldELCLowThreshold] == "10" &&
232+
row[elcFieldELCHighThreshold] == "95" &&
233+
row[elcFieldELCHighThresholdEnable] == "1" &&
234+
((row[elcFieldDieType] == "IO" && row[elcFieldELCRatio] == "800") ||
235+
(row[elcFieldDieType] == "Compute" && row[elcFieldELCRatio] == "1200")) {
236+
mode = ELCModeOptimizedPower
237+
} else {
238+
mode = ELCModeCustom
220239
}
221-
values = append(values, mode)
240+
modeValues = append(modeValues, mode)
222241
}
223-
fieldValues = append(fieldValues, table.Field{Name: "Mode", Values: values})
242+
fieldValues = append(fieldValues, table.Field{Name: "Mode", Values: modeValues})
224243
return
225244
}
226245

internal/script/scripts.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -541,8 +541,8 @@ extract_and_print_metrics() {
541541
min_ratio=$(( min_ratio * 100 ))
542542
max_ratio=$(( max_ratio * 100 ))
543543
eff_latency_ctrl_ratio=$(( eff_latency_ctrl_ratio * 100 ))
544-
eff_latency_ctrl_low_threshold=$(( (eff_latency_ctrl_low_threshold * 100) / 127 ))
545-
eff_latency_ctrl_high_threshold=$(( (eff_latency_ctrl_high_threshold * 100) / 127 ))
544+
eff_latency_ctrl_low_threshold=$(( (eff_latency_ctrl_low_threshold * 100) / 100 ))
545+
eff_latency_ctrl_high_threshold=$(( (eff_latency_ctrl_high_threshold * 100) / 100 ))
546546
547547
# Print metrics
548548
echo -n "$socket_id,$die,$die_type,$min_ratio,$max_ratio,$eff_latency_ctrl_ratio,"

0 commit comments

Comments
 (0)