Hardware.Info icon indicating copy to clipboard operation
Hardware.Info copied to clipboard

Question: Obtaining CPU Utilization Metrics

Open Kiryuumaru opened this issue 2 years ago • 5 comments

First off, big thanks for this awesome lib! I'm digging into CPU metrics on Windows and wondering how to get the PercentProcessorUtility instead of PercentProcessorTime. It seems more in line with Task Manager's display. Any tips on grabbing this specific metric?

Kiryuumaru avatar Mar 25 '24 06:03 Kiryuumaru

I am glad you like my lib :)

Take a look at GetCpuList https://github.com/Jinjinov/Hardware.Info/blob/master/Hardware.Info/Windows/HardwareInfoRetrieval.cs#L247 and replace PercentProcessorTime with PercentProcessorUtility like so:

    ulong percentProcessorUtility = 0ul;

    string queryString = "SELECT Name, PercentProcessorUtility FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name != '_Total'";
    ManagementObjectSearcher percentProcessorUtilityMOS = new ManagementObjectSearcher(_managementScope, queryString, _enumerationOptions);

    queryString = "SELECT PercentProcessorUtility FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name = '_Total'";
    ManagementObjectSearcher totalPercentProcessorUtilityMOS = new ManagementObjectSearcher(_managementScope, queryString, _enumerationOptions);

    try
    {
        foreach (ManagementBaseObject mo in percentProcessorUtilityMOS.Get())
        {
            // for each core:
            //Name = GetPropertyString(mo["Name"])
            //PercentProcessorUtility = GetPropertyValue<ulong>(mo["PercentProcessorUtility"])
        }

        foreach (ManagementBaseObject mo in totalPercentProcessorUtilityMOS.Get())
        {
            // total:
            percentProcessorUtility = GetPropertyValue<ulong>(mo["PercentProcessorUtility"]);
        }
    }
    catch (ManagementException)
    {
        // https://github.com/Jinjinov/Hardware.Info/issues/30
    }
    finally
    {
        percentProcessorUtilityMOS.Dispose();

        totalPercentProcessorUtilityMOS.Dispose();
    }

Jinjinov avatar Mar 25 '24 07:03 Jinjinov

Thank you for providing the solution! I've successfully implemented the usage of PercentProcessorUtility on Windows and it's working. I was wondering if there's a possibility to include support for this feature directly into the library in future updates? It would be really beneficial for users who rely on obtaining CPU utilization metrics

Kiryuumaru avatar Mar 26 '24 08:03 Kiryuumaru

I just noticed that I am using PercentProcessorTime under Win32_PerfFormattedData_PerfOS_Processor but PercentProcessorUtility is listed only under Win32_PerfRawData_Counters_ProcessorInformation

Googling "PercentProcessorUtility Win32_PerfFormattedData_PerfOS_Processor" actually returns no results.

As you can see here https://github.com/Jinjinov/Hardware.Info?tab=readme-ov-file#known-issues the main problem with these counters is their slow initialization.

If PercentProcessorUtility was under Win32_PerfFormattedData_PerfOS_Processor I would have no problem adding it into the lib. But querying another counter Win32_PerfRawData_Counters_ProcessorInformation might slow things down. I would have to test it extensively before adding it.

How large is the actual difference between PercentProcessorUtility and PercentProcessorTime values?

Jinjinov avatar Mar 26 '24 16:03 Jinjinov

Thanks for looking into it! From my real-time comparisons, I've noticed a pretty big gap between PercentProcessorUtility and PercentProcessorTime in real-time comparisons. During stress tests, PercentProcessorUtility seems to track Task Manager's numbers better, but it doesn't cap at 100% like Task Manager does—it goes beyond, hitting around 200%. As for Linux ubuntu, its PercentProcessorTime lines up pretty well with its system monitor, unlike Windows's PercentProcessorTime with Task Manager.

Kiryuumaru avatar Mar 27 '24 06:03 Kiryuumaru

Could you tell me a few startup times of your app under different conditions?

If you start the stopwatch in the first line of void Main() and immediately execute these, how long do they take

  • new HardwareInfo() and RefreshCPUList(false)
  • new HardwareInfo() and RefreshCPUList(true)
  • your code for PercentProcessorUtility
  • new HardwareInfo() and RefreshCPUList(false) and your code for PercentProcessorUtility
  • new HardwareInfo() and RefreshCPUList(true) and your code for PercentProcessorUtility

If you tell me these times for both DEBUG and RELEASE (or at least RELEASE) it would really help me a lot.

It would allow me to compare the startup times on your PC with those on my PC.

If I am going to query another counter Win32_PerfRawData_Counters_ProcessorInformation then I really want to test the impact on app startup time on as many PCs as possible.

Jinjinov avatar Mar 27 '24 07:03 Jinjinov