mirror of
https://github.com/XuehaiPan/nvitop.git
synced 2026-10-29 22:03:15 -06:00
[GH-ISSUE #236] [BUG] Process %CPU oscillates between 0% and the real value when the process-metrics screen or treeview is open #235
Labels
No labels
api
bug
bug
cli / tui
dependencies
documentation
documentation
documentation
duplicate
enhancement
exporter
invalid
pull-request
pynvml
question
question
upstream
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
github-starred/nvitop#235
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @arinawang11 on GitHub (Oct 31, 2026).
Original GitHub issue: https://github.com/XuehaiPan/nvitop/issues/236
Originally assigned to: @XuehaiPan on GitHub.
What version of nvitop are you using?
1.7.1. The same code structure is present in 1.7.2 and on
main(verified by reading the sources).Operating system and version
Windows Server 2025 Datacenter 10.0.26100 (96 logical CPUs).
NVIDIA driver version
581.80
NVIDIA-SMI
Python environment
Installed with
pip.Problem description
Expected: the
%CPUvalue of a process is stable. A process pinning one CPU core should report ~100% on every refresh.Actual: while the process-metrics screen is open (
Enteron a process) or the treeview is open (t), the CPU percentage of the process alternates between0.0%and its real value on every sample. The CPU history graph on the metrics screen looks like a square wave. Going back to the main screen (Enter/Esc) makes the value stable again.Root cause:
nvitopcachesHostProcessper PID andGpuProcessper(pid, device), while multiple snapshot daemons call psutil's non-blockingProcess.cpu_percent()on the same object concurrently. That API is stateful: it returns a delta since the previous call on that object. The loser of the race measures a sub-millisecond window; on WindowsGetProcessTimesis only updated every ~15.6 ms, so it reads a zero delta and returns exactly0.0%. The winner measures the full window and returns the real value. The same pattern is reproducible on any platform where the CPU-time counter has a coarser granularity than the concurrent sampling window.Relevant code:
nvitop/api/process.py:196-230—HostProcess.INSTANCEScache by PID; the same instance is shared by all screens.nvitop/api/process.py:834-847—GpuProcess.cpu_percent()delegates toself.host.cpu_percent().nvitop/tui/screens/metrics.py:294-316— the process-metrics daemon samples the same cachedGpuProcessevery 0.5 s.nvitop/tui/screens/main/panels/process.py:362-388— the main process panel daemon; its thread is only stopped indestroy()(lines 662-664).nvitop/tui/library/displayable.py:143-149andnvitop/tui/tui.py:316-322— hiding a screen only setsvisible = False; the panel daemon keeps running, so both daemons sample the same object while the metrics/treeview screen is shown.nvitop/tui/screens/treeview.py:103— treeview re-samples sharedHostProcess/GpuProcessinstances instead of reusingSnapshot.cpu_percent.Steps to Reproduce
Minimal reproduction, no GPU required:
Output on Windows Server 2025 with psutil 7.2.2:
With a single sampler, the same process reports
100.0%on every sample.TUI steps:
nvitopon a machine with a GPU process that is CPU-active.Enterto open the process-metrics screen. The CPU history graph alternates between the real value and 0.Enter/Escto return to the main screen. The value becomes stable again.tto open treeview. The%CPUcolumn of the GPU processes alternates as well.Traceback
None.
Additional context
GpuProcess.as_snapshot()/HostProcess.cpu_percent()from two threads.main.Snapshot.cpu_percentfor processes that already have a snapshot. A more general fix would serialize per-PID sampling with a short cache inHostProcess.cpu_percent.