nvml无法获取当前进程显存占用,仅提供整卡全局视图;精确定位本进程需依赖cudamemgetinfo()(须先激活cuda上下文)或解析nvidia-smi进程查询结果。

直接说结论:不能用 NVML 拿“当前进程”的显存占用,它只提供全局 GPU 显存视图;真要定位到本进程,得靠 cudaMemGetInfo() 配合 CUDA 上下文,但有严格前提。
nvmlDeviceGetMemoryInfo() 返回的是整卡显存,不是进程级
NVML 的设计目标是设备级监控,nvmlDeviceGetMemoryInfo() 拿到的 info.used 是当前 GPU 所有进程 + 内核驱动 + 纹理缓存等加起来的总用量。它不区分谁占了哪块——哪怕你程序只 malloc 了 10MB,info.used 也可能显示 2GB,因为旁边有个 PyTorch 训练任务占着显存。
常见错误现象:nvmlDeviceGetMemoryInfo() 数值远高于你预期,且随其他程序启停剧烈波动,这就是典型“被别的进程带飞”了。
- 它适合做整卡水位告警(比如 >95% 就发 warning)
- 不适合做资源配额判断或进程自身显存泄漏分析
- 不依赖 CUDA 上下文,普通用户只要权限够就能调
cudaMemGetInfo() 能反映当前进程,但必须先激活 CUDA 上下文
cudaMemGetInfo() 返回的是“当前 CUDA 上下文绑定的 GPU”上、属于该上下文的可用显存和已用显存。但它不是进程维度的统计,而是上下文维度的——如果你没显式创建过上下文,它大概率返回 cudaErrorInvalidValue。
关键前提:
在OpenClaw上部署你的首席AI助理贾维斯(JARVIS)。针对Dell Pro Max GB10(NVIDIA DGX Spark)边缘设备优化。用于设置和配置贾维斯。
- 必须调过
cudaSetDevice(0)或至少触发一次 kernel 启动(比如cudaMalloc()),否则上下文未初始化 - 如果程序里混用多个 GPU,
cudaMemGetInfo()只反映最后一次cudaSetDevice()绑定的那个设备 - 它不包含非 CUDA 分配的显存(比如 OpenGL 或 Vulkan 的纹理内存)
示例片段:
size_t free_bytes, total_bytes;
cudaError_t err = cudaMemGetInfo(&free_bytes, &total_bytes);
if (err != cudaSuccess) {
// 常见报错:cudaErrorInvalidValue —— 上下文未建立
fprintf(stderr, "cudaMemGetInfo failed: %s\n", cudaGetErrorString(err));
return;
}
printf("Process-visible GPU memory: %.1f / %.1f MB\n",
(total_bytes - free_bytes) / 1024.0 / 1024.0,
total_bytes / 1024.0 / 1024.0);
想精确知道本进程占了多少?Linux 下可查 /proc/self/pid/status
在 Linux 上,NVIDIA 驱动会把每个进程的 GPU 显存映射记录在 /proc/[pid]/status 的 gpu_mem 字段(需内核 >= 5.10 + 驱动 >= 470),但这不是标准字段,依赖驱动版本和内核配置。
更通用的做法是结合 nvidia-smi --query-compute-apps=pid,used_memory --format=csv,noheader,nounits 解析输出,再过滤出本进程 PID。虽然慢、有启动开销、格式可能变,但它是目前唯一能跨驱动版本稳定拿到“进程-显存”映射的方式。
- 别用
nvidia-smi -q -xXML 输出去解析,太重,且<process_info></process_info>在某些旧驱动里默认关闭 - 注意权限:普通用户执行
nvidia-smi查询进程信息时,可能看不到其他用户的进程,这是正常行为 - Windows 下无等效机制,只能靠 NVAPI 的
NvAPI_GPU_GetMemoryInfo()(需注册开发者账号获取 SDK)
真正难的不是调哪个函数,而是搞清你要回答的问题到底是什么:是“这张卡还剩多少空闲显存”,还是“我的代码现在实际用了多少”。前者用 NVML,后者得拉起 CUDA 上下文或绕道系统命令——选错接口,后面所有逻辑都会偏。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










