Skip to content

xptea/VGPU-Mon

Repository files navigation

VGPU-Mon

CI CodeQL MIT License

VGPU-Mon is a native Windows GPU task manager written in C. It combines direct Windows per-process video-memory queries, WDDM engine counters, DXGI, and NVIDIA NVML to show board telemetry and the processes consuming each GPU.

It is a real full-screen terminal application, not a wrapper around nvidia-smi. NVML is loaded dynamically, so the same executable still runs on AMD and Intel systems with the vendor-neutral data that Windows exposes.

Features

  • Live GPU and physical VRAM utilization with driver-reserved memory separated
  • Full-screen timestamped charts with time-span zoom, history panning, and exact hover values
  • Direct per-process dedicated/shared GPU-memory usage, with a validated WDDM fallback for protected processes
  • Per-process 3D, compute, copy, encode, and decode engine activity
  • Temperature, board power, power limit, fan, P-state, and clocks through NVML
  • Encoder, decoder, and PCIe link/throughput telemetry when the driver exposes it
  • Multiple-GPU switching
  • Mouse-clickable sort headers and process rows, plus context-aware wheel navigation
  • Responsive layouts with bounded full-frame repainting after every terminal resize
  • Interactive sorting, process-name filtering, and process details
  • Confirmed process termination with protection for system and self PIDs
  • Pause/resume and adjustable 250-5000 ms refresh interval
  • CSV logging
  • One-shot human-readable and JSON output for scripts
  • Automatic, checksum-verified background updates for installed interactive launches
  • Statically linked MSVC runtime; no NVML SDK or third-party runtime required

Runtime requirements and compatibility

  • 64-bit Windows 10 version 1809 or newer, or Windows 11
  • A WDDM 2.x display driver for direct per-process memory queries and per-engine Windows counters
  • Windows Terminal is recommended for the interactive interface
  • A current NVIDIA display driver for temperature, power, clocks, fan, encoder/decoder, and NVML memory accounting

No CUDA Toolkit, NVML SDK, Visual C++ Redistributable, Python, or administrator access is required at runtime. The release executable statically links the C runtime and dynamically discovers NVML in both supported Windows driver locations: System32 for DCH drivers and Program Files\NVIDIA Corporation\NVSMI for standard drivers.

Modern GeForce/RTX, Quadro/RTX professional, and data-center NVIDIA GPUs generally receive the full feature set when the installed driver exposes those calls. NVIDIA documents only limited NVML support for non-data-center GPUs, so not every NVIDIA GPU/driver combination exposes every sensor. Unsupported values appear as N/A or Unavailable, not as fabricated readings.

Under NVIDIA TCC mode, old pre-WDDM 2.x drivers, some VMs, or remote sessions, NVML board telemetry may work while Windows per-process and engine counters do not. AMD and Intel adapters receive DXGI/WDDM data but not NVIDIA-only sensors.

Visual Studio 2022 C++ Build Tools are needed only to build from source.

Some protected processes cannot be inspected or terminated without elevation. VGPU-Mon reports their GPU accounting normally when Windows exposes it, but does not bypass Windows security.

Install

Open PowerShell or Windows Terminal and paste this one command:

curl.exe -fsSL https://raw.githubusercontent.com/xptea/VGPU-Mon/main/install.ps1 | Out-String | Invoke-Expression

The bootstrap script finds the latest stable GitHub Release, downloads its per-user installer and SHA256SUMS.txt, verifies the installer SHA-256, and only then runs it silently. It does not require administrator access. Open a new terminal tab after installation, then run:

vgpu
vgpu --chart vram
vgpu --chart 3d
vgpu --json

Existing terminal processes keep their old environment. Uninstalling VGPU-Mon from Windows Settings removes the PATH entry only when the installer originally added it.

Starting with VGPU-Mon 1.2.0, an installed interactive launch checks the latest stable release's small version.txt manifest. If a newer version exists, VGPU-Mon downloads that exact versioned installer, verifies its SHA-256 with Windows cryptography, and installs it without elevation. The command then returns cleanly; run vgpu again after a few seconds to start the updated monitor. The updater deliberately does not relaunch inside the old terminal because the shell would already own that terminal's input. Network or GitHub failures do not prevent the monitor from opening. Redirected output and script commands (--json, --once, --version, and --demo) never perform an automatic update check.

Use vgpu --update to check immediately. Use --no-update for one launch or set VGPU_MON_NO_UPDATE=1 to disable automatic checks. Portable ZIP copies do not update silently; vgpu --update converts a portable copy into the normal per-user installation.

Prefer to inspect scripts before running them? Read install.ps1, or download the versioned installer/portable ZIP manually from Releases. Release assets include SHA256SUMS.txt. Windows SmartScreen may warn about community-built releases until the project has a trusted code-signing certificate; always verify the download came from this repository.

Build and run

Install Visual Studio 2022 with Desktop development with C++. Include the optional C++ AddressSanitizer component if you want to run the sanitizer gate. From PowerShell:

.\build.ps1 -Configuration Release -Test
.\run.ps1

The build script discovers Visual Studio through vswhere, initializes the correct x64 native toolchain, and writes build\vgpu-mon.exe.

A CMake target is also provided for IDEs and static-analysis tooling:

cmake -S . -B build\cmake -A x64
cmake --build build\cmake --config Release --parallel
ctest --test-dir build\cmake -C Release --output-on-failure

The full local quality gates are:

.\build.ps1 -Configuration Debug -Test
.\build.ps1 -Configuration Release -Test
.\build.ps1 -Configuration Sanitize -Test -OutputName vgpu-mon-asan
.\analyze.ps1
.\tools\verify-pe.ps1

Debug tests enable the MSVC CRT leak detector. The sanitizer build runs the same native, ConPTY, and CLI tests under MSVC AddressSanitizer. /analyze warnings fail the build. The PE check verifies ASLR, DEP, CFG, CET compatibility, and the absence of a dynamic MSVC runtime dependency. GitHub Actions repeats these checks and runs CodeQL on every change to main.

To create the portable release ZIP:

.\package.ps1

To build the Windows installer, install Inno Setup 6 and run:

winget install --id JRSoftware.InnoSetup --exact --scope user
.\installer.ps1

Interactive controls

Key Action
Up / Down Select a process
PgUp / PgDn Move by ten rows
u Sort by busiest GPU engine
m Sort by dedicated VRAM
s Sort by shared memory
p, n, e Sort by PID, name, or engine
o Reverse the current sort
Mouse click Sort a header or select a process row
Mouse wheel Move through process rows; zoom the time span over a chart
Shift + mouse wheel Pan backward or forward through chart history
Left / Right Pan a chart by one-quarter of its visible span
PgUp / PgDn Pan a chart by one full visible span
Home / End Jump to the oldest complete chart window or return live
Mouse hover Show the exact chart value and how long ago it was sampled
f Edit the process-name filter
d Toggle details for the selected process
i Toggle the full GPU information panel
c Toggle full-screen chart/table view
1-0 Select GPU, VRAM, engine, temperature, or power chart
k Ask to terminate the selected process
l Toggle CSV logging to vgpu-mon.csv
[ / ] Switch GPU
+ / - Refresh faster or slower
Space Pause or resume sampling
h Toggle help
q Quit

Script-friendly output

.\build\vgpu-mon.exe --once
.\build\vgpu-mon.exe --json
.\build\vgpu-mon.exe --gpu 0 --interval 500 --json |
    ConvertFrom-Json

Demo mode

--demo feeds deterministic sample telemetry through the real renderer, input loop, charts, and JSON code without querying GPU hardware. It is useful for evaluating the UI, reproducing terminal bugs, and automated testing:

.\build\vgpu-mon.exe --demo
.\build\vgpu-mon.exe --demo --chart vram
.\build\vgpu-mon.exe --demo --json

Demo values are clearly labeled and must not be treated as machine telemetry.

Full-screen charts

.\build\vgpu-mon.exe --chart
.\build\vgpu-mon.exe --chart vram
.\build\vgpu-mon.exe --chart 3d
.\build\vgpu-mon.exe --chart copy
.\build\vgpu-mon.exe --chart decode
.\build\vgpu-mon.exe --chart encode
.\build\vgpu-mon.exe --chart compute
.\build\vgpu-mon.exe --chart memory-controller
.\build\vgpu-mon.exe --chart temperature
.\build\vgpu-mon.exe --chart power

The flag form requested by the UI is also supported, such as --chart --vram, --chart --3d, or simply --vram. In chart view, number keys switch metrics without restarting and c returns to the process table.

Charts open on a one-minute live window. Scroll the mouse wheel over the plot to zoom from a tighter view to the full retained range. Use Shift+wheel, Left/Right, or PgUp/PgDn to inspect older samples; End snaps back to live data. Hovering anywhere on the plot draws a crosshair and an in-chart tooltip with the nearest real sample's value and age.

VGPU-Mon retains 14,400 timestamped samples per metric in a fixed-size ring, so memory use stays bounded. That represents about four hours at the default one-second interval, one hour at 250 ms, or twenty hours at five seconds. Stored timestamps keep zoom, panning, and hover ages correct when the sampling interval changes during a run. History is in memory only and resets when the app closes or the selected GPU changes; use CSV logging for long-term storage.

Options:

--once             Print one snapshot and exit
--json             Print one snapshot as JSON
--chart [METRIC]   Open a full-screen chart
--vram, --percent  Open a VRAM or overall-utilization chart
--3d, --copy, --decode, --encode, --compute
                   Open a WDDM engine chart
--gpu INDEX        Select a physical GPU
--interval MS      Sampling interval from 250 to 5000
--log PATH         Start CSV logging when interactive mode opens
--demo             Use deterministic sample data for previews and tests
--update           Check for and install an update now
--no-update        Skip the automatic update check for this run
--help             Show help
--version          Show the version

Data sources and accounting

  • D3DKMT video-memory queries provide current local and non-local usage for each accessible process on the selected adapter. VGPU-Mon resolves the documented Windows entry points dynamically and opens adapters using their DXGI LUIDs.
  • Windows GPU performance counters discover active GPU processes, provide per-process engine utilization, and supply a guarded memory fallback when Windows does not allow the process handle needed by the direct API. The displayed process percentage is that process's busiest engine, which follows Windows Task Manager's accounting model.
  • DXGI 1.4 enumerates hardware adapters, supplies the LUID used by the direct memory provider, and reports local video-memory usage and the current OS memory budget.
  • NVML supplies NVIDIA board telemetry. VGPU-Mon uses the versioned memory API to separate driver/firmware-reserved VRAM from application allocation. nvml.dll is discovered and loaded at runtime; the project does not ship NVIDIA libraries.

VRAM figures from D3DKMT, NVML, DXGI, and WDDM can differ because they describe different accounting layers. Shared allocations may be attributed to more than one process, so adding every row is not a physical-board total. VGPU-Mon marks process columns with * and keeps the physical total and OS budget separate.

Windows' GPU Process Memory performance counter can accumulate stale allocations and produce implausibly large values. Those counters are no longer the primary memory source. If a protected process requires the fallback, VGPU-Mon validates only that row, marks a rejected value as N/A !, writes a blank CSV field or JSON null, and raises wddm_process_memory_warning without hiding valid rows. Physical board usage at the top remains sourced from NVML/DXGI.

JSON reports dedicated_memory_source and shared_memory_source as d3dkmt, pdh, demo, or unavailable. The generic dedicated_memory_bytes and shared_memory_bytes fields are authoritative. The older JSON aliases and CSV column names ending in _commit_bytes remain for compatibility; their source columns identify whether the value came from the direct API or the guarded fallback.

Terminating a process is not the same as resetting a GPU. VGPU-Mon deliberately does not expose driver resets or unsafe attempts to cancel individual command queues.

JSON, CSV, screenshots, and bug reports can expose process names, executable activity, paths, or GPU identifiers. Review and redact telemetry before sharing it.

Contributing and security

VGPU-Mon is released under the MIT License.

Technical references

About

Native Windows GPU process monitor in C with WDDM, DXGI, and NVIDIA NVML telemetry

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors