0

I am adding a couple of new features to my program that currently sends the CPU usage and RAM usage to Arduino via serial connection (see this). I am trying to add GPU and Disk usage as well. Disk usage is not a problem but fetching GPU usage from Windows have become a real trouble.

I've tried using PerformanceCounter but that doesn't seem to work at all! See the code below.

PerformanceCounter gpuCounter = new PerformanceCounter("GPU Engine", "Utilization Percentage");
string gpuUsage = gpuCounter.NextValue()

I want the GPU usage in percentage like this:

GPU usage: #.#%

Is there any possible way i can achieve this?

Sunny
  • 19
  • 1
  • 5
  • The code you posted, what does it return? – Miguel Mateo Jul 01 '19 at 05:36
  • Check for GPU names in your computer, I run something similar with the following code and works fine: PerformanceCounter gpuCounter = new PerformanceCounter("NVIDIA GPU", "% GPU Usage","#0 Quadro K1100M(id=1, NVAPI ID=256)"); ... but in your case, it could be different. – Miguel Mateo Jul 01 '19 at 05:38
  • which gpu brand do you have? maybe this is interesting if you have an NVIDIA: https://stackoverflow.com/questions/36389944/c-sharp-performance-counter-help-nvidia-gpu – Jonas Jul 01 '19 at 05:38
  • This is what it returns: Counter is not single instance, an instance name needs to be specified. And yes, it doesn't matters what brand GPU i have (AMD), i have to make it work with all brands. – Sunny Jul 01 '19 at 05:42

2 Answers2

4

You need to create a PerformanceCounterCategory for "GPU Engine", then call GetInstanceNames () on the category. You can then iterate on the name string array calling GetCounters (name) method.

    public List<PerformanceCounter> Sample ()
    {
        var list = new List<PerformanceCounter> ();
        var category = new PerformanceCounterCategory ("GPU Engine");
        var names = category.GetInstanceNames ();
        foreach (var name in names)
            list.AddRange (category.GetCounters (name));
        return list;
    }

There will be both "Running Time" and "Utilization Percentage" counters in your list. You could filter based on the CounterName property for the counters returned by GetCounters.

  • Note: the utilization percentage is a difference value; you'll need to do NextSample () rather than NextValue (), and compute the percentage as current raw value - last raw value / timespan ticks. – Patrick Weber Aug 29 '19 at 19:04
  • can you share the code with this calculation logic? – maulik kansara Jul 07 '20 at 10:07
  • Sorry, no. What I wrote belongs to a client. – Patrick Weber Jul 09 '20 at 19:59
  • @PatrickWeber not sure from the C# API, but from C++ with PDH, I get the computed percentage after calling PdhCollectQueryData. However, it would be true for "Running Time", collecting the samples and dividing over the time delta. – 000Camus000 Aug 31 '22 at 01:05
3

I use the following:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using System.Threading;

public class GetCPUUsage
{
    static void Main(string[] args)
    {   
        while (true)
        {
            try
            {
                var gpuCounters = GetGPUCounters();         
                var gpuUsage = GetGPUUsage(gpuCounters);
                Console.WriteLine(gpuUsage);
                continue;
            } catch {}
            
            Thread.Sleep(1000);
        }
    }
    
    public static List<PerformanceCounter> GetGPUCounters()
    {
        var category = new PerformanceCounterCategory("GPU Engine");
        var counterNames = category.GetInstanceNames();

        var gpuCounters = counterNames
                            .Where(counterName => counterName.EndsWith("engtype_3D"))
                            .SelectMany(counterName => category.GetCounters(counterName))
                            .Where(counter => counter.CounterName.Equals("Utilization Percentage"))
                            .ToList();
            
        return gpuCounters;
    }
    
    public static float GetGPUUsage(List<PerformanceCounter> gpuCounters)
    {
        gpuCounters.ForEach(x => x.NextValue());

        Thread.Sleep(1000);

        var result = gpuCounters.Sum(x => x.NextValue());

        return result;
    }
}
Fidel
  • 7,027
  • 11
  • 57
  • 81