取得GPU Video Memory Usage - Windows 10 1709 only

  最近的Windows 10 Fall Creators Update更新中,提供了一樣以往被視為是難以取得的的資訊,那就是GPU的使用率及記憶體用量,這以往都要靠特定的工具才能查看,例如GPU-Z或是Riva Tuner,如果是NVIDIA那就還好,NVIDIA會在資源監視器中添加幾個計數器,所以取得其實不困難,但如果是ATI/AMD甚至是Intel HD,沒有特定的通道與知識是很難達到取得這些資訊的,尤其是記憶體(Video Memory)用量,在這次的更新後,這一切都變得非常簡單了。

 

GPU監測資訊在哪裡?

   Windows 10 Fall Creators Update把它放在Task Manager,也就是工作管理員裡,如下圖所示。

你也可以在詳細資料中找到每個Process的GPU還有記憶體用量。

 

在程式中取得這些資訊?

  既然已經提供,那麼自然就會聯想到是否有新的API或是管道讓程式也可以取得這些資訊,我找了一下,似乎還沒有公布特定的API來取得,不過還有一個程式設計師常用的管道,那就是資源監視器。

果然好好地躺在那,一旦在這找到,那麼就可以使用PerformanceCounter來取得這些資訊了,而且不限GPU廠牌哦。我們先由記憶體開始,你會看到這裡有兩個例項,這是因為在一台主機中,GPU不一定只有一個,所以有多個例項是可以理解的,但事實上我這台機器只有一個GPU,所以我猜後面的phys_0大概就是用來分辨是哪顆GPU的關鍵,兩個的值加起來才是那個GPU實際的記憶體使用量,但注意,這是猜,除非有更多的文件或是實測,否則很難知道整體的邏輯。那要怎麼寫呢?很簡單,.NET Framework所提供的PerformanceCounter就可以辦到。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            var memoryCategory = new PerformanceCounterCategory("GPU Adapter Memory");
            var memoryInstances = memoryCategory.GetInstanceNames();
            List<PerformanceCounter> memoryUsage = new List<PerformanceCounter>();
            foreach (var item in memoryInstances)
            {
                memoryUsage.AddRange(memoryCategory.GetCounters(item));
            }

            Task.Run(() =>
            {
                var dedicateUsage = memoryUsage.Where(a => a.CounterName == "Dedicated Usage").FirstOrDefault();
                while (true)
                {
                    var total = dedicateUsage.NextValue();
                    BeginInvoke(new Action(() =>
                    {
                        label1.Text = $"GPU Memory : {Math.Round(total / 1024 / 1024, 0)} MB";
                    }));
                    Thread.Sleep(1000);
                }
            });
        }
    }
}

這是個Windows Form程式,執行的結果如下。

基本上數字是吻合的,雖然可以取得記憶體用量資訊,但說真的還是有些因資訊不足產生的困擾,例如GPU使用量,看看下圖,你就會知道這東西還真的要有點GPU知識才知道這啥鬼。

如果我沒猜錯的話,這個Utilization Percentage細到依據用途不同來分,這增加了要取得GPU Usage的難度,所以如果目的是要取得整體GPU的使用量,那麼由Running Time來算會比較容易,不過這應該是趟不短的旅程,畢竟GPU知識要對應到這個東西上也有困難,以上,報告完畢。