mirror of
https://github.com/XuehaiPan/nvitop.git
synced 2026-10-29 22:03:15 -06:00
[PR #237] [MERGED] fix(tui/process): cache CPU utilization samples across screens #236
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#236
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?
📋 Pull Request Information
Original PR: https://github.com/XuehaiPan/nvitop/pull/237
Author: @arinawang11
Created: 10/31/2026
Status: ✅ Merged
Merged: 10/31/2026
Merged by: @XuehaiPan
Base:
main← Head:fix/cpu-percent-sampling-race📝 Commits (4)
41cf5c6fix(tui/process): cache non-blockingcpu_percentsamples0bea27edocs(tui/process): clarify CPU sampling cache rationale5076387docs(changelog): note TUI CPU sampling fixe7d44e2fix(process): preserve subclasses and enlarge CPU sample cache📊 Changes
4 files changed (+36 additions, -14 deletions)
View changed files
📝
CHANGELOG.md(+1 -1)📝
nvitop/api/device.py(+2 -2)📝
nvitop/api/process.py(+17 -9)📝
nvitop/tui/library/process.py(+16 -2)📄 Description
Problem
HostProcesscaches one instance per PID (HostProcess.INSTANCES), and every screen shares that instance. The TUI runs several snapshot daemons concurrently: the main process panel keeps sampling while the process-metrics screen (Enter) and the treeview (t) are open, and those screens sample the same cachedGpuProcess/HostProcess.psutil.Process.cpu_percent(interval=None)is stateful: it reports the utilization since the previous call on the same instance and resets its baseline on every call. When two daemons sample concurrently, the first one measures the elapsed window (the real value), while the others measure a near-zero window. On WindowsGetProcessTimesonly advances every ~15.6 ms, so that window reads a zero delta and returns exactly0.0%. The visible symptom is a strict 0% / real-value alternation in the process-metrics CPU graph and in the treeview%CPUcolumn.Fixes #236.
Change
nvitop/api/process.py: addGpuProcess.HOST_PROCESS_CLASS(defaults toHostProcess) and use it when creating the host process, following theDevice.GPU_PROCESS_CLASSpattern.nvitop/tui/library/process.py: subclassHostProcessand cachecpu_percentwithttl_cache(ttl=0.1)(the minimum sampling interval recommended by psutil). The TUIGpuProcesssetsHOST_PROCESS_CLASSto this subclass.The API classes keep their previous behaviour; only the TUI layer caches the sample.
Verification
Minimal repro (two threads sampling one cached
HostProcess):thread-1=100.0% thread-2=0.0%100.0%on every sampleAlso checked on Windows Server 2025 / Python 3.12 / psutil 7.2.2:
GpuProcess(pid, device).hostis the TUIHostProcesssubclasspython -m nvitop --oncestill rendersruff check,ruff format --check,pylintpass on the changed modulesThe first non-blocking call on a freshly created instance still returns
0.0, which is psutil's documented behaviour and is unchanged.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.