GPU有问有答:任务管理器里面的GPU占用率到底是怎么算的?


从总体上来说 , Windows 10是一个好系统 , 虽然我们天天戏称它为“Bug 10” , 但不可否认的是 , 从立项以来 , 开发团队就一直在努力为它加入新的功能 , 其中有不少是相当实用的 , 比如说 , 他们在1709这个大版本中 , 为任务管理器加入了GPU性能监控单元 , 用户可以通过任务管理器直观地看到目前的GPU占用率 , 比以往要开GPU-Z等程序方便了不少 。 但很多用户在实际使用的时候也发现了 , 这个针对GPU的性能监控好像不太准 , 我显卡在全力计算的时候 , 任务管理器里面的GPU占用率怎么这么低?
GPU有问有答:任务管理器里面的GPU占用率到底是怎么算的?
本文插图
比如我开个挖矿程序 , 显卡的占用其实是满的 , 但左边GPU窗格中显示的占用率只有3%
为了找出答案 , 我们找到了当时引入这项新功能时 , 开发者的讲解Blog , 由于是与图形相关的内容 , 这篇Blog被归入DirectX Developer Blog中 。
首先开发者给我们讲述了任务管理器是怎么得知GPU的占用情况的 。 在Windows 10上面 , GPU通过Windows Display Driver Model(WDDM , Windows显示驱动模型)抽象 , 它的核心——图形内核——负责抽象、管理和在所有进程分配GPU资源 。 它含有一个GPU事务器(VidSch)和一个视频内存管理器(VidMem) , 前者负责将GPU的各种引擎分配给想要使用它们的进程 , 并对访问进行仲裁和优先级排序 , 后者则是负责管理GPU可调用的内存——包括专用的显存和共享的系统内存 。
任务管理器就是通过VidSch和VidMem回报的数据来计算GPU的使用情况的 , 这样一来 , 不管程序使用了什么API(DX、OpenGL、OpenCL , 甚至CUDA、Mantle这种专有API都可以监控) , 它都能准确地收集GPU的占用情况 , 另外由于两者是实际负责分配GPU资源的 , 位于驱动层面 , 它们回报数据的精准度也要比很多第三方工具要高 , 使得任务管理器有很高的精度 。
【GPU有问有答:任务管理器里面的GPU占用率到底是怎么算的?】既然有很高的精度 , 那它为什么还是报不准我的GPU占用率呢?这就牵扯到另一个问题 , GPU引擎 。
现代GPU上除了有主要用于图形、通用计算的统一计算单元外 , 还会集成一些其他的电路 , 比如说 , 用于视频编解码的专用模块 。 它们之间的关系一般是并行的 , GPU可以同时运行图形计算和视频编码任务 , 在驱动层面 , 这些不同的模块就被抽象为不同的Engine , 也就是引擎 , 比如说一个典型的GPU可以有以下这些引擎:
GPU有问有答:任务管理器里面的GPU占用率到底是怎么算的?
本文插图
在具体执行任务的时候 , 不同的任务会在不同的引擎上面执行 , 比如说我打游戏 , 就用到3D引擎;我用显卡加速Premiere Pro , 就用到CUDA引擎;我用NVENC编码视频 , 就用到视频编码引擎 。
GPU有问有答:任务管理器里面的GPU占用率到底是怎么算的?
本文插图
一张RTX 2060显卡被系统抽象出的引擎
由于部分引擎之间有复用的关系 , 比如说3D引擎和CUDA引擎复用CUDA Cores进行计算 , 那么如果通过简单加法来计算占用率 , 那这个占用率就有可能会超过100% 。 开发团队也考虑过使用平均利用率来表示 , 但也不靠谱 。 那3D引擎不是被用的最多吗 , 就用它怎么样?也不太行 , 比如在视频引擎满载而3D引擎空载的情况下 , 它将会显示0%的占用率 , 也是不准确的 。 最终 , 开发团队选择将当前最为繁忙的引擎占用率作为GPU整体占用率的代表 。
恩……博文说的很好 , 那么到今天为止这个功能上线也有一段时间了 , 其具体表现是怎样的呢?让我们看回顶上的那张图 , 在GPU的CUDA引擎满载的情况下 , 其左边的整体占用率仍然很低 , 显然是没有达到开发团队所说的 。