Summary
On macOS (Apple Silicon), the Freq: field in the GPU List row of the view TUI intermittently appears and disappears between refreshes. The value is correct when shown, but the whole Freq: label+value vanishes for a refresh cycle and comes back later, which also shifts the layout of the fields after it (Pwr: etc.) on that row.
NVIDIA and other accelerators have not been confirmed yet, but the analysis below shows the rendering-layer half of the bug is cross-platform; the data-layer half is Apple-Silicon-specific.
Reproduction
sudo ./target/release/all-smi view (or cargo run --bin all-smi -- view) on an Apple Silicon Mac.
- Watch the GPU List row over 20-30s while the machine is mostly idle.
- The
Freq: field disappears and reappears across refresh cycles. It is most stable under sustained GPU load and most flickery when the GPU is near-idle.
Root cause
There are two distinct bugs that compound.
Bug A — data layer: idle Apple GPU computes frequency == 0
Render value chain:
AppleSiliconNativeGpuReader::get_gpu_info() → frequency: metrics.frequency.unwrap_or(0) — src/device/readers/apple_silicon_native.rs:236
metrics.frequency = Some(data.gpu_frequency) — src/device/readers/apple_silicon_native.rs:153
data.gpu_frequency = ioreport.gpu_freq — src/device/macos_native/metrics.rs:105
ioreport.gpu_freq defaults to 0, overwritten only via calculate_cluster_average(&gpu_freqs) — src/device/macos_native/ioreport.rs:765-768
gpu_freq ends up 0 through either of these paths:
-
Idle GPU, active_residency == 0. process_gpu_channel → calc_gpu_freq_with_table (src/device/macos_native/ioreport.rs:851-887) skips every state whose name contains IDLE/OFF/DOWN (ioreport.rs:861-863). When the Apple GPU power-gates (the normal idle state on a machine just running a TUI), all GPUPH residency for the 100ms window sits in those idle states, so active_residency stays 0 and the function returns (0, …). That (0, 0.0) is pushed into gpu_freqs, so calculate_cluster_average returns Some((0, …)) — note: Some, not None — and gpu_freq is set to 0.
-
gpu_freqs empty. If the GPUPH channel item is absent from a given IOReport sample, or item.get_residencies() returns empty, process_gpu_channel early-returns (src/device/macos_native/ioreport.rs:830-832) and nothing is pushed. calculate_cluster_average([]) returns None, so gpu_freq keeps its 0 default.
The 4-sample integer averaging in NativeMetricsManager::average_samples (src/device/macos_native/manager.rs:242,257) then averages those per-sample values; an all-idle collection window averages to 0.
The core semantic problem: GpuInfo.frequency: u32 (src/device/types.rs:50) cannot distinguish "GPU idle, no active P-state this window" from "no frequency data available". An idle Apple GPU is not running at 0 Hz — it is parked at its lowest P-state — but the code reports 0 for it.
Bug B — render layer: frequency > 0 used as "is data available"
src/ui/renderers/gpu_renderer.rs:315:
if info.frequency > 0 {
print_colored_text(stdout, " Freq:", Color::Magenta, None, None);
...
}
The entire Freq: label+value is gated on frequency > 0. This conflates "zero / no data" with "don't render at all", so any refresh where Bug A produces 0 makes the field vanish — and because it is rendered inline, every field after it on the row shifts left. This block has been unchanged since the renderer split in #44.
This half is cross-platform: NVIDIA's reader also does device.clock(...).unwrap_or(0) (src/device/readers/nvidia.rs:341) and the nvidia-smi fallback does parts[7].parse().unwrap_or(0) (src/device/readers/nvidia.rs:818); Jetson reads cur_freq from sysfs (src/device/readers/nvidia_jetson.rs:120). Any of those producing 0 (query error, sysfs read failure) would flicker identically. NVIDIA just rarely hits it because NVML reports a stable idle graphics clock.
Why it is intermittent
gpu_freq is tied to GPU activity during the ~400ms collection window. Busy GPU → active P-state residency → non-zero freq → Freq: shown. Idle GPU → only idle-state residency → 0 → Freq: hidden. A normal desktop Apple GPU floats between these states constantly (even drawing the TUI causes short bursts), so the field flickers every few seconds.
Proposed fix
Two parts; both should land together.
Fix B (renderer, cross-platform) — stop gating display on the value
Don't use frequency > 0 as a data-availability proxy. Either:
- always render
Freq: and show N/A when no data is available — consistent with how VRAM:/Temp: already handle metrics_available == "false" and temperature == 0 in the same function (src/ui/renderers/gpu_renderer.rs:273,293-298), or
- gate on an explicit "frequency known" signal rather than the integer value.
This alone stops the flicker and keeps the row layout stable.
Fix A (Apple Silicon data layer) — idle GPU should report a real frequency
Make calc_gpu_freq_with_table (and calc_freq_from_residencies) return the GPU's idle/base clock instead of 0 when the GPU is present but idle (total_residency > 0 && active_residency == 0): return freq_table[0] (the lowest P-state in the IOKit pmgr table) rather than 0. An idle Apple GPU genuinely sits at its lowest P-state.
Optionally also make availability explicit end-to-end — e.g. GpuInfo.frequency: Option<u32> (or a companion frequency_available: bool), with None reserved for the genuine "no data" case (channel missing / residencies empty) and the renderer showing N/A for None. This cleanly separates the two states Bug A conflates today.
Worth checking while in here
- Whether
GPUPH is the correct/only GPU P-state channel across M1-M5 (Pro/Max/Ultra), or whether some chips expose it under a different channel name — a permanently-missing channel would make Freq never show, not flicker.
- Whether
get_residencies() ever transiently returns empty for GPUPH (would indicate a sampling-robustness issue, not just an idle-state issue).
Affected files
src/ui/renderers/gpu_renderer.rs:314-334 — Fix B
src/device/macos_native/ioreport.rs:828-887 — process_gpu_channel, calc_gpu_freq_with_table, calc_freq_from_residencies — Fix A
src/device/macos_native/ioreport.rs:765-768 — calculate_cluster_average call site for GPU
src/device/readers/apple_silicon_native.rs:153,236 — frequency plumbing
src/device/types.rs:50 — GpuInfo.frequency field (if making availability explicit)
src/device/macos_native/manager.rs:242,257 — sample averaging (verify behavior once idle returns base clock)
Acceptance criteria
Summary
On macOS (Apple Silicon), the
Freq:field in the GPU List row of theviewTUI intermittently appears and disappears between refreshes. The value is correct when shown, but the wholeFreq:label+value vanishes for a refresh cycle and comes back later, which also shifts the layout of the fields after it (Pwr:etc.) on that row.NVIDIA and other accelerators have not been confirmed yet, but the analysis below shows the rendering-layer half of the bug is cross-platform; the data-layer half is Apple-Silicon-specific.
Reproduction
sudo ./target/release/all-smi view(orcargo run --bin all-smi -- view) on an Apple Silicon Mac.Freq:field disappears and reappears across refresh cycles. It is most stable under sustained GPU load and most flickery when the GPU is near-idle.Root cause
There are two distinct bugs that compound.
Bug A — data layer: idle Apple GPU computes
frequency == 0Render value chain:
AppleSiliconNativeGpuReader::get_gpu_info()→frequency: metrics.frequency.unwrap_or(0)—src/device/readers/apple_silicon_native.rs:236metrics.frequency=Some(data.gpu_frequency)—src/device/readers/apple_silicon_native.rs:153data.gpu_frequency=ioreport.gpu_freq—src/device/macos_native/metrics.rs:105ioreport.gpu_freqdefaults to0, overwritten only viacalculate_cluster_average(&gpu_freqs)—src/device/macos_native/ioreport.rs:765-768gpu_freqends up0through either of these paths:Idle GPU,
active_residency == 0.process_gpu_channel→calc_gpu_freq_with_table(src/device/macos_native/ioreport.rs:851-887) skips every state whose name containsIDLE/OFF/DOWN(ioreport.rs:861-863). When the Apple GPU power-gates (the normal idle state on a machine just running a TUI), allGPUPHresidency for the 100ms window sits in those idle states, soactive_residencystays0and the function returns(0, …). That(0, 0.0)is pushed intogpu_freqs, socalculate_cluster_averagereturnsSome((0, …))— note:Some, notNone— andgpu_freqis set to0.gpu_freqsempty. If theGPUPHchannel item is absent from a given IOReport sample, oritem.get_residencies()returns empty,process_gpu_channelearly-returns (src/device/macos_native/ioreport.rs:830-832) and nothing is pushed.calculate_cluster_average([])returnsNone, sogpu_freqkeeps its0default.The 4-sample integer averaging in
NativeMetricsManager::average_samples(src/device/macos_native/manager.rs:242,257) then averages those per-sample values; an all-idle collection window averages to0.The core semantic problem:
GpuInfo.frequency: u32(src/device/types.rs:50) cannot distinguish "GPU idle, no active P-state this window" from "no frequency data available". An idle Apple GPU is not running at 0 Hz — it is parked at its lowest P-state — but the code reports0for it.Bug B — render layer:
frequency > 0used as "is data available"src/ui/renderers/gpu_renderer.rs:315:The entire
Freq:label+value is gated onfrequency > 0. This conflates "zero / no data" with "don't render at all", so any refresh where Bug A produces0makes the field vanish — and because it is rendered inline, every field after it on the row shifts left. This block has been unchanged since the renderer split in #44.This half is cross-platform: NVIDIA's reader also does
device.clock(...).unwrap_or(0)(src/device/readers/nvidia.rs:341) and the nvidia-smi fallback doesparts[7].parse().unwrap_or(0)(src/device/readers/nvidia.rs:818); Jetson readscur_freqfrom sysfs (src/device/readers/nvidia_jetson.rs:120). Any of those producing0(query error, sysfs read failure) would flicker identically. NVIDIA just rarely hits it because NVML reports a stable idle graphics clock.Why it is intermittent
gpu_freqis tied to GPU activity during the ~400ms collection window. Busy GPU → active P-state residency → non-zero freq →Freq:shown. Idle GPU → only idle-state residency →0→Freq:hidden. A normal desktop Apple GPU floats between these states constantly (even drawing the TUI causes short bursts), so the field flickers every few seconds.Proposed fix
Two parts; both should land together.
Fix B (renderer, cross-platform) — stop gating display on the value
Don't use
frequency > 0as a data-availability proxy. Either:Freq:and showN/Awhen no data is available — consistent with howVRAM:/Temp:already handlemetrics_available == "false"andtemperature == 0in the same function (src/ui/renderers/gpu_renderer.rs:273,293-298), orThis alone stops the flicker and keeps the row layout stable.
Fix A (Apple Silicon data layer) — idle GPU should report a real frequency
Make
calc_gpu_freq_with_table(andcalc_freq_from_residencies) return the GPU's idle/base clock instead of0when the GPU is present but idle (total_residency > 0 && active_residency == 0): returnfreq_table[0](the lowest P-state in the IOKit pmgr table) rather than0. An idle Apple GPU genuinely sits at its lowest P-state.Optionally also make availability explicit end-to-end — e.g.
GpuInfo.frequency: Option<u32>(or a companionfrequency_available: bool), withNonereserved for the genuine "no data" case (channel missing / residencies empty) and the renderer showingN/AforNone. This cleanly separates the two states Bug A conflates today.Worth checking while in here
GPUPHis the correct/only GPU P-state channel across M1-M5 (Pro/Max/Ultra), or whether some chips expose it under a different channel name — a permanently-missing channel would makeFreqnever show, not flicker.get_residencies()ever transiently returns empty forGPUPH(would indicate a sampling-robustness issue, not just an idle-state issue).Affected files
src/ui/renderers/gpu_renderer.rs:314-334— Fix Bsrc/device/macos_native/ioreport.rs:828-887—process_gpu_channel,calc_gpu_freq_with_table,calc_freq_from_residencies— Fix Asrc/device/macos_native/ioreport.rs:765-768—calculate_cluster_averagecall site for GPUsrc/device/readers/apple_silicon_native.rs:153,236—frequencyplumbingsrc/device/types.rs:50—GpuInfo.frequencyfield (if making availability explicit)src/device/macos_native/manager.rs:242,257— sample averaging (verify behavior once idle returns base clock)Acceptance criteria
Freq:field in the GPU List stays visible across consecutive refresh cycles (no appear/disappear flicker) and the row layout does not shift.0; a loaded GPU still reports the correct weighted active frequency.N/Ainstead of vanishing.N/A, no flicker).viewTUI code path (not just helper functions) and confirmed in a runningall-smi viewsession.cargo fmt --check,cargo clippy, andcargo testpass; existingioreport.rsfreq tests updated for the new idle-state behavior.