Add modeled absolute temperature estimates

This commit is contained in:
saymrwulf 2026-04-21 21:35:53 +02:00
parent 01a281d73c
commit f382e45834
4 changed files with 59 additions and 17 deletions

View file

@ -125,8 +125,11 @@ while :; do
my $sample_s = (($ENV{SAMPLE_MS} || 5000) / 1000);
my $hold_s = $ENV{HOLD_SEC} || 6;
my $display_bias_w = defined $ENV{DISPLAY_BIAS_W} ? $ENV{DISPLAY_BIAS_W} : 2.5;
my $spread_theta = defined $ENV{THERMAL_SPREAD_C_PER_W} ? $ENV{THERMAL_SPREAD_C_PER_W} : 0.85;
my $clamshell_factor = defined $ENV{CLAMSHELL_FACTOR} ? $ENV{CLAMSHELL_FACTOR} : 1.08;
my $ambient_c = defined $ENV{AMBIENT_C} ? $ENV{AMBIENT_C} : 23;
my $idle_offset_c = defined $ENV{IDLE_OFFSET_C} ? $ENV{IDLE_OFFSET_C} : 9;
my $cpu_theta = defined $ENV{CPU_THETA_C_PER_W} ? $ENV{CPU_THETA_C_PER_W} : 1.55;
my $gpu_theta = defined $ENV{GPU_THETA_C_PER_W} ? $ENV{GPU_THETA_C_PER_W} : 1.35;
print "\e[1;97mCPU WALL\e[0m sample ${sample_s}s hold ${hold_s}s\n";
print "\e[38;5;240m$rule\e[0m\n\n";
@ -192,11 +195,18 @@ while :; do
? ($gpu_power_w + $display_component_w)
: (defined $gpu_used ? ((0.04 * $gpu_used) + $display_component_w) : undef);
my $gradient_c = (defined $cpu_hot_w && defined $gpu_zone_w)
? abs($cpu_hot_w - $gpu_zone_w) * $spread_theta * pressure_factor($thermal_state) * $clamshell_factor
my $thermal_mult = pressure_factor($thermal_state) * $clamshell_factor;
my $cpu_abs_c = defined $cpu_hot_w
? ($ambient_c + $idle_offset_c + ($cpu_hot_w * $cpu_theta * $thermal_mult))
: undef;
my $gpu_abs_c = defined $gpu_zone_w
? ($ambient_c + $idle_offset_c + ($gpu_zone_w * $gpu_theta * $thermal_mult))
: undef;
my $gradient_c = (defined $cpu_abs_c && defined $gpu_abs_c)
? abs($cpu_abs_c - $gpu_abs_c)
: undef;
my $gradient_side = !defined $gradient_c ? "insufficient data"
: $cpu_hot_w >= $gpu_zone_w ? "CPU side hotter"
: $cpu_abs_c >= $gpu_abs_c ? "CPU side hotter"
: "GPU/display side hotter";
my $basis = (defined $cpu_power_w && defined $gpu_power_w) ? "power-based estimate" : "util fallback";
my $state = defined $thermal_state ? $thermal_state : "n/a";
@ -205,6 +215,7 @@ while :; do
print "\e[1;97mTHERMAL ESTIMATE\e[0m\n";
print "\e[38;5;240m$rule\e[0m\n\n";
printf " pressure \e[38;5;%sm%s\e[0m\n", $state_color, $state;
printf " ambient est %6.2f C\n", $ambient_c;
printf " cpu hotspot %6.2f W %s\n", $cpu_hot_w, $cpu_hot_name if defined $cpu_hot_w;
if (defined $gpu_zone_w) {
if (defined $gpu_power_w) {
@ -213,9 +224,13 @@ while :; do
printf " gpu zone %6.2f W util fallback + display %.2f\n", $gpu_zone_w, $display_component_w;
}
}
printf " cpu abs est %6.2f C\n", $cpu_abs_c if defined $cpu_abs_c;
printf " gpu abs est %6.2f C\n", $gpu_abs_c if defined $gpu_abs_c;
printf " est gradient %6.2f C %s\n", $gradient_c, $gradient_side if defined $gradient_c;
printf " basis %s\n", $basis;
print " note estimate only, not a sensor temperature\n";
printf " model idle %.1fC + zone_w * theta * pressure * clamshell\n", $idle_offset_c;
printf " theta cpu %.2fC/W gpu %.2fC/W\n", $cpu_theta, $gpu_theta;
print " note estimated absolute temps, not sensor readings\n";
'
)"

View file

@ -119,8 +119,11 @@ while :; do
my $sample_s = (($ENV{SAMPLE_MS} || 5000) / 1000);
my $hold_s = $ENV{HOLD_SEC} || 6;
my $display_bias_w = defined $ENV{DISPLAY_BIAS_W} ? $ENV{DISPLAY_BIAS_W} : 2.5;
my $spread_theta = defined $ENV{THERMAL_SPREAD_C_PER_W} ? $ENV{THERMAL_SPREAD_C_PER_W} : 0.85;
my $clamshell_factor = defined $ENV{CLAMSHELL_FACTOR} ? $ENV{CLAMSHELL_FACTOR} : 1.08;
my $ambient_c = defined $ENV{AMBIENT_C} ? $ENV{AMBIENT_C} : 23;
my $idle_offset_c = defined $ENV{IDLE_OFFSET_C} ? $ENV{IDLE_OFFSET_C} : 9;
my $cpu_theta = defined $ENV{CPU_THETA_C_PER_W} ? $ENV{CPU_THETA_C_PER_W} : 1.55;
my $gpu_theta = defined $ENV{GPU_THETA_C_PER_W} ? $ENV{GPU_THETA_C_PER_W} : 1.35;
print "\e[1;97mGPU WALL\e[0m sample ${sample_s}s hold ${hold_s}s\n";
print "\e[38;5;240m$rule\e[0m\n\n";
@ -172,11 +175,18 @@ while :; do
? ($gpu_power_w + $display_component_w)
: (defined $used ? ((0.04 * $used) + $display_component_w) : undef);
my $gradient_c = (defined $cpu_hot_w && defined $gpu_zone_w)
? abs($cpu_hot_w - $gpu_zone_w) * $spread_theta * pressure_factor($thermal_state) * $clamshell_factor
my $thermal_mult = pressure_factor($thermal_state) * $clamshell_factor;
my $cpu_abs_c = defined $cpu_hot_w
? ($ambient_c + $idle_offset_c + ($cpu_hot_w * $cpu_theta * $thermal_mult))
: undef;
my $gpu_abs_c = defined $gpu_zone_w
? ($ambient_c + $idle_offset_c + ($gpu_zone_w * $gpu_theta * $thermal_mult))
: undef;
my $gradient_c = (defined $cpu_abs_c && defined $gpu_abs_c)
? abs($cpu_abs_c - $gpu_abs_c)
: undef;
my $gradient_side = !defined $gradient_c ? "insufficient data"
: $cpu_hot_w >= $gpu_zone_w ? "CPU side hotter"
: $cpu_abs_c >= $gpu_abs_c ? "CPU side hotter"
: "GPU/display side hotter";
my $basis = (defined $cpu_power_w && defined $gpu_power_w) ? "power-based estimate" : "util fallback";
my $state = defined $thermal_state ? $thermal_state : "n/a";
@ -185,6 +195,7 @@ while :; do
print "\n\e[1;97mTHERMAL ESTIMATE\e[0m\n";
print "\e[38;5;240m$rule\e[0m\n\n";
printf " pressure \e[38;5;%sm%s\e[0m\n", $state_color, $state;
printf " ambient est %6.2f C\n", $ambient_c;
printf " cpu hotspot %6.2f W %s\n", $cpu_hot_w, $cpu_hot_name if defined $cpu_hot_w;
if (defined $gpu_zone_w) {
if (defined $gpu_power_w) {
@ -193,9 +204,13 @@ while :; do
printf " gpu zone %6.2f W util fallback + display %.2f\n", $gpu_zone_w, $display_component_w;
}
}
printf " cpu abs est %6.2f C\n", $cpu_abs_c if defined $cpu_abs_c;
printf " gpu abs est %6.2f C\n", $gpu_abs_c if defined $gpu_abs_c;
printf " est gradient %6.2f C %s\n", $gradient_c, $gradient_side if defined $gradient_c;
printf " basis %s\n", $basis;
print " note estimate only, not a sensor temperature\n";
printf " model idle %.1fC + zone_w * theta * pressure * clamshell\n", $idle_offset_c;
printf " theta cpu %.2fC/W gpu %.2fC/W\n", $cpu_theta, $gpu_theta;
print " note estimated absolute temps, not sensor readings\n";
'
)"

View file

@ -29,10 +29,10 @@ SAMPLE_MS=2000 HOLD_SEC=2 ./tmux-wall.sh
Thermal estimate tuning:
```bash
DISPLAY_BIAS_W=2.5 THERMAL_SPREAD_C_PER_W=0.85 CLAMSHELL_FACTOR=1.08 ./tmux-wall.sh
AMBIENT_C=23 IDLE_OFFSET_C=9 DISPLAY_BIAS_W=2.5 CPU_THETA_C_PER_W=1.55 GPU_THETA_C_PER_W=1.35 CLAMSHELL_FACTOR=1.08 ./tmux-wall.sh
```
The thermal section is an estimate derived from `powermetrics` CPU/GPU power and activity plus thermal pressure. It is not a direct temperature sensor reading.
The thermal section now shows estimated absolute CPU-side and GPU-side temperatures plus the estimated gradient. These values are derived from `powermetrics` CPU/GPU power and activity plus thermal pressure. They are modeled estimates, not direct sensor readings.
If you want to attach to an existing session later:

View file

@ -9,11 +9,14 @@ script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
sample_ms="${SAMPLE_MS:-5000}"
hold_sec="${HOLD_SEC:-6}"
display_bias_w="${DISPLAY_BIAS_W:-}"
thermal_spread="${THERMAL_SPREAD_C_PER_W:-}"
clamshell_factor="${CLAMSHELL_FACTOR:-}"
ambient_c="${AMBIENT_C:-}"
idle_offset_c="${IDLE_OFFSET_C:-}"
cpu_theta="${CPU_THETA_C_PER_W:-}"
gpu_theta="${GPU_THETA_C_PER_W:-}"
if [[ "${EUID}" -ne 0 ]]; then
exec sudo --preserve-env=TMUX_SESSION_NAME,TMUX_WINDOW_NAME,TMUX_RECREATE,SAMPLE_MS,HOLD_SEC,DISPLAY_BIAS_W,THERMAL_SPREAD_C_PER_W,CLAMSHELL_FACTOR bash "$0" "$@"
exec sudo --preserve-env=TMUX_SESSION_NAME,TMUX_WINDOW_NAME,TMUX_RECREATE,SAMPLE_MS,HOLD_SEC,DISPLAY_BIAS_W,CLAMSHELL_FACTOR,AMBIENT_C,IDLE_OFFSET_C,CPU_THETA_C_PER_W,GPU_THETA_C_PER_W bash "$0" "$@"
fi
if ! command -v tmux >/dev/null 2>&1; then
@ -35,12 +38,21 @@ env_prefix="SAMPLE_MS=${sample_ms} HOLD_SEC=${hold_sec}"
if [[ -n "${display_bias_w}" ]]; then
env_prefix="${env_prefix} DISPLAY_BIAS_W=${display_bias_w}"
fi
if [[ -n "${thermal_spread}" ]]; then
env_prefix="${env_prefix} THERMAL_SPREAD_C_PER_W=${thermal_spread}"
fi
if [[ -n "${clamshell_factor}" ]]; then
env_prefix="${env_prefix} CLAMSHELL_FACTOR=${clamshell_factor}"
fi
if [[ -n "${ambient_c}" ]]; then
env_prefix="${env_prefix} AMBIENT_C=${ambient_c}"
fi
if [[ -n "${idle_offset_c}" ]]; then
env_prefix="${env_prefix} IDLE_OFFSET_C=${idle_offset_c}"
fi
if [[ -n "${cpu_theta}" ]]; then
env_prefix="${env_prefix} CPU_THETA_C_PER_W=${cpu_theta}"
fi
if [[ -n "${gpu_theta}" ]]; then
env_prefix="${env_prefix} GPU_THETA_C_PER_W=${gpu_theta}"
fi
if tmux has-session -t "${session_name}" 2>/dev/null; then
if [[ "${recreate_session}" == "1" ]]; then