Windows下用NVAPI获取NVIDIA GPU显存占用最可靠,需驱动≥R450、正确链接NvAPI.lib/dll,调用NvAPI_EnumPhysicalGPUs()获取句柄后通过NvAPI_GPU_GetMemoryInfo()读取dedicatedVideoMemory与availableDedicatedVideoMemory之差,WDDM模式下为近似值,误差可达100–500MB。

Windows下用NVAPI获取NVIDIA GPU显存占用
直接调用NVIDIA官方驱动接口是目前最可靠的方式,但前提是目标机器装了NVIDIA驱动且版本支持NVAPI。NVAPI不依赖CUDA或图形API(如OpenGL/DirectX),属于底层驱动暴露的轻量级接口。
常见错误现象:NvAPI_Initialize() 返回 NVAPI_NVIDIA_DEVICE_NOT_FOUND 或 NVAPI_INVALID_ARGUMENT,多数是因为没链接NvAPI.lib、没把NvAPI.dll放在可加载路径,或者驱动太旧(建议≥R450)。
- 下载最新
NvAPI.h和NvAPI.lib(从NVIDIA官网开发者页面获取,别用SDK包里过时的) - 初始化后必须用
NvAPI_EnumPhysicalGPUs()拿到NvPhysicalGpuHandle,不能硬编码索引 - 显存占用需两次调用:
NvAPI_GPU_GetMemoryInfo()返回的是当前帧的显存使用快照,不是实时流;若要轮询,间隔建议≥100ms,否则可能触发驱动限频 -
NV_MEMORY_INFO_V2结构里的dedicatedVideoMemory和availableDedicatedVideoMemory之差才是已用显存,不是usedDedicatedVideoMemory字段(该字段在旧版驱动中不可靠)
Linux下通过sysfs读取NVIDIA GPU显存状态
Linux没有统一的驱动级API,NVIDIA驱动在/proc/driver/nvidia/gpus/下暴露了若干节点,其中information和memory_usage最常用。这方法不依赖用户态库,只要驱动加载成功就能读。
典型问题:普通用户读/proc/driver/nvidia/gpus/xxx/memory_usage会失败,报Permission denied——这不是权限位问题,而是NVIDIA驱动默认关闭该接口,需手动启用。
立即学习“C++免费学习笔记(深入)”;
- 先确认GPU存在:
ls /proc/driver/nvidia/gpus/,输出类似0000:01:00.0 - 启用内存统计:
echo 1 | sudo tee /sys/module/nvidia/parameters/enable_stream_mem_info(部分驱动版本用nv_enable_stream_mem_info,需查对应内核模块参数) - 读取结果格式为
gpu_id: used_memory / total_memory (unit),例如0: 2147483648 / 8589934592 bytes,注意单位是字节,不是MB - 该路径在驱动重启后失效,建议写入
/etc/modprobe.d/nvidia.conf:添加options nvidia enable_stream_mem_info=1
跨平台方案只能靠进程级估算(非驱动级)
如果你的目标是“所有GPU型号通用”,那根本不存在真正的底层驱动接口——AMD有ADL,Intel有GPU Tools,但接口差异大、文档残缺、新版驱动常废弃旧函数。硬写跨平台抽象层反而容易出错。
更实际的做法是降级需求:只监控本进程的GPU内存分配。CUDA和HIP提供了可靠的运行时接口,虽然不是系统级,但对大多数训练/推理场景已足够。
- CUDA场景用
cudaMemGetInfo():返回free和total,相减即当前进程已用显存;注意它不包含其他进程占用,也不含驱动保留内存 - HIP等价函数是
hipMemGetInfo(),行为一致,但需确保hip_runtime.h版本匹配驱动 - OpenCL可用
clGetDeviceInfo()查CL_DEVICE_GLOBAL_MEM_SIZE和CL_DEVICE_GLOBAL_MEM_CACHE_SIZE,但无法获取实时占用——这是OpenCL规范限制,不是实现问题 - 不要尝试解析
nvidia-smi -q -d MEMORY输出做自动化,它的CLI格式不稳定(不同驱动版本字段顺序/命名可能变),且启动开销大(约50–100ms)
为什么WDDM下无法精确获取独立显存占用
Windows对NVIDIA GPU默认走WDDM模式,而WDDM把显存当作统一内存池管理,GPU显存和系统内存共享调度。此时NvAPI_GPU_GetMemoryInfo()返回的“dedicated video memory”其实是驱动虚拟出来的视图,实际物理显存可能被桌面窗口管理器(DWM)、DirectComposition等组件占用,且这部分不向NVAPI上报。
这意味着即使你拿到usedDedicatedVideoMemory,它也可能比nvidia-smi显示的小——因为nvidia-smi走的是内核模块直通路径,而NVAPI走的是WDDM用户态代理。
- 唯一绕过方式是强制GPU工作在TCC模式(仅Tesla/Quadro/A100等专业卡支持),此时
NvAPI数据与nvidia-smi基本一致 - 消费级卡(GeForce)无法切换TCC,所以WDDM下所有“显存占用”数值都只是近似值,误差可能达100–500MB
- 如果你的应用必须精确到MB级,要么接受误差,要么改用Linux + TCC等效环境
NvAPI_GPU_GetMemoryInfo()返回值是否合理。



















