shell: add gpumean, a settled GPU busy sampler

This commit is contained in:
rope 2026-08-19 14:10:11 +01:00
parent 9a54ddacaa
commit 42adab61df

View file

@ -153,5 +153,40 @@ in
end end
function fish_right_prompt; end function fish_right_prompt; end
# GPU load, averaged. A single read of gpu_busy_percent is worthless —
# it catches whatever transient the card was in at that instant. Settle
# first, then sample, and report the spread as well as the mean: a
# steady 30% and a 0-to-70% sawtooth are different problems.
function gpumean --description "Mean GPU busy % 5s settle, then N seconds at 5Hz (default 10)"
set -l secs 10
test (count $argv) -gt 0; and set secs $argv[1]
# find, not a glob: an unmatched wildcard is an error in fish and would
# abort the function before the emptiness check below.
set -l cards (find /sys/class/drm -maxdepth 3 -name gpu_busy_percent 2>/dev/null | sort)
if test (count $cards) -eq 0
echo "no gpu_busy_percent found (amdgpu/i915 only nvidia doesn't expose it)"
return 1
end
sleep 5
set -l sum; set -l lo; set -l hi
for c in $cards
set -a sum 0; set -a lo 100; set -a hi 0
end
set -l n (math "$secs * 5")
for i in (seq $n)
for j in (seq (count $cards))
set -l v (cat $cards[$j])
set sum[$j] (math "$sum[$j] + $v")
test $v -lt $lo[$j]; and set lo[$j] $v
test $v -gt $hi[$j]; and set hi[$j] $v
end
sleep 0.2
end
for j in (seq (count $cards))
set -l name (string replace -r '.*/(card[0-9]+)/.*' '$1' $cards[$j])
echo "$name mean="(math -s0 "$sum[$j] / $n")"% min=$lo[$j]% max=$hi[$j]% ($secs""s)"
end
end
''; '';
} }