Win 10果然是Bug 10:GPU占用率原來是這么算的
從總體上來說,Windows 10是一個好系統(tǒng),雖然我們天天戲稱它為“Bug 10”,但不可否認的是,從立項以來,開發(fā)團隊就一直在努力為它加入新的功能,其中有不少是相當(dāng)實用的。
比如說,他們在1709這個大版本中,為任務(wù)管理器加入了GPU性能監(jiān)控單元,用戶可以通過任務(wù)管理器直觀地看到目前的GPU占用率,比以往要開GPU-Z等程序方便了不少。
但很多用戶在實際使用的時候也發(fā)現(xiàn)了,這個針對GPU的性能監(jiān)控好像不太準,我顯卡在全力計算的時候,任務(wù)管理器里面的GPU占用率怎么這么低?
比如我開個挖礦程序,顯卡的占用其實是滿的,但左邊GPU窗格中顯示的占用率只有3%
為了找出答案,我們找到了當(dāng)時引入這項新功能時,開發(fā)者的講解Blog,由于是與圖形相關(guān)的內(nèi)容,這篇Blog被歸入DirectX Developer Blog中。
首先開發(fā)者給我們講述了任務(wù)管理器是怎么得知GPU的占用情況的。在Windows 10上面,GPU通過Windows Display Driver Model(WDDM,Windows顯示驅(qū)動模型)抽象,它的核心—;—;圖形內(nèi)核—;—;負責(zé)抽象、管理和在所有進程分配GPU資源。
它含有一個GPU事務(wù)器(VidSch)和一個視頻內(nèi)存管理器(VidMem),前者負責(zé)將GPU的各種引擎分配給想要使用它們的進程,并對訪問進行仲裁和優(yōu)先級排序,后者則是負責(zé)管理GPU可調(diào)用的內(nèi)存—;—;包括專用的顯存和共享的系統(tǒng)內(nèi)存。
任務(wù)管理器就是通過VidSch和VidMem回報的數(shù)據(jù)來計算GPU的使用情況的,這樣一來,不管程序使用了什么API(DX、OpenGL、OpenCL,甚至CUDA、Mantle這種專有API都可以監(jiān)控),它都能準確地收集GPU的占用情況,另外由于兩者是實際負責(zé)分配GPU資源的,位于驅(qū)動層面,它們回報數(shù)據(jù)的精準度也要比很多第三方工具要高,使得任務(wù)管理器有很高的精度。
既然有很高的精度,那它為什么還是報不準我的GPU占用率呢?這就牽扯到另一個問題,GPU引擎。
現(xiàn)代GPU上除了有主要用于圖形、通用計算的統(tǒng)一計算單元外,還會集成一些其他的電路,比如說,用于視頻編解碼的專用模塊。它們之間的關(guān)系一般是并行的,GPU可以同時運行圖形計算和視頻編碼任務(wù),在驅(qū)動層面,這些不同的模塊就被抽象為不同的Engine,也就是引擎,比如說一個典型的GPU可以有以下這些引擎:
在具體執(zhí)行任務(wù)的時候,不同的任務(wù)會在不同的引擎上面執(zhí)行,比如說我打游戲,就用到3D引擎;我用顯卡加速Premiere Pro,就用到CUDA引擎;我用NVENC編碼視頻,就用到視頻編碼引擎。
一張RTX 2060顯卡被系統(tǒng)抽象出的引擎
由于部分引擎之間有復(fù)用的關(guān)系,比如說3D引擎和CUDA引擎復(fù)用CUDA Cores進行計算,那么如果通過簡單加法來計算占用率,那這個占用率就有可能會超過100%。
開發(fā)團隊也考慮過使用平均利用率來表示,但也不靠譜。那3D引擎不是被用的最多嗎,就用它怎么樣?也不太行,比如在視頻引擎滿載而3D引擎空載的情況下,它將會顯示0%的占用率,也是不準確的。最終,開發(fā)團隊選擇將當(dāng)前最為繁忙的引擎占用率作為GPU整體占用率的代表。
恩……博文說的很好,那么到今天為止這個功能上線也有一段時間了,其具體表現(xiàn)是怎樣的呢?讓我們看回頂上的那張圖,在GPU的CUDA引擎滿載的情況下,其左邊的整體占用率仍然很低,顯然是沒有達到開發(fā)團隊所說的。
我們又測試了一下別的情況,這里使用NVENC對視頻進行編碼,此時可以看到左邊窗格中的GPU占用率又跑到了滿載。
而在跑典型的3D應(yīng)用程序的時候,它也很正常。
最后,我們嘗試了OpenCL負載,這次任務(wù)管理器又能反映出CUDA引擎的占用率了。
如此看來,任務(wù)管理器GPU占用率的薛定諤情況可能是Windows 10的一個Bug所導(dǎo)致的,在大部分情況下,它都會反映負載最大引擎的占用率,但在某些情況下,它并不能夠正確地顯示當(dāng)前最繁忙引擎的占用情況。