Windows 10任務管理器裡面的GPU佔用率到底是怎麼算的?
從總體上來說,Windows 10是一個好系統,雖然我們天天戲稱它為“Bug 10”,但不可否認的是,從立項以來,開發團隊就一直在努力為它加入新的功能,其中有不少是相當實用的,比如說,他們在1709這個大版本中,為任務管理器加入了GPU性能監控單元,用戶可以通過任務管理器直觀地看到目前的GPU佔用率,比以往要開GPU-Z等程序方便了不少。
但很多用戶在實際使用的時候也發現了,這個針對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可以同時運行圖形計算和視頻編碼任務,在驅動層面,這些不同的模塊就被抽象為不同的Engine,也就是引擎,比如說一個典型的GPU可以有以下這些引擎:
在具體執行任務的時候,不同的任務會在不同的引擎上面執行,比如說我打遊戲,就用到3D引擎;我用顯卡加速Premiere Pro,就用到CUDA引擎;我用NVENC編碼視頻,就用到視頻編碼引擎。
一張RTX 2060顯卡被系統抽像出的引擎
由於部分引擎之間有復用的關係,比如說3D引擎和CUDA引擎復用CUDA Cores進行計算,那麼如果通過簡單加法來計算佔用率,那這個佔用率就有可能會超過100%。開發團隊也考慮過使用平均利用率來表示,但也不靠譜。那3D引擎不是被用的最多嗎,就用它怎麼樣?也不太行,比如在視頻引擎滿載而3D引擎空載的情況下,它將會顯示0%的佔用率,也是不准確的。最終,開發團隊選擇將當前最為繁忙的引擎佔用率作為GPU整體佔用率的代表。
恩……博文說的很好,那麼到今天為止這個功能上線也有一段時間了,其具體表現是怎樣的呢?讓我們看回頂上的那張圖,在GPU的CUDA引擎滿載的情況下,其左邊的整體佔用率仍然很低,顯然是沒有達到開發團隊所說的。
我們又測試了一下別的情況,這裡使用NVENC對視頻進行編碼,此時可以看到左邊窗格中的GPU佔用率又跑到了滿載。
而在跑典型的3D應用程序的時候,它也很正常。
最後,我們嘗試了OpenCL負載,這次任務管理器又能反映出CUDA引擎的佔用率了。
如此看來,任務管理器GPU佔用率的薛定諤情況可能是Windows 10的一個Bug所導致的,在大部分情況下,它都會反映負載最大引擎的佔用率,但在某些情況下,它並不能夠正確地顯示當前最繁忙引擎的佔用情況。