4

I would like to create an application that monitors and displays the frequencies of each core in a system's processor to a user, in MHz. I have seen other applications do this, such as Piriform's Speccy, so I know that it must be possible.

I have tried searching for a solution on Stack Overflow but I could not find it. Even this question, which was the closest match I could find speaks to an anti-cheating implementation in C++ and does not offer an actual solution but has one important takeaway that this article describes: "With power management technologies becoming more commonplace in today's computers, a commonly-used method to obtain high-resolution CPU timings, the RDTSC instruction, may no longer work as expected." There goes that idea.

The closest thing I've seen is that the management object has a MaxClockSpeed, but that answers to the speed of the processor, not of the processor's individual cores.

There is also the CPUID System Information Monitoring Kit, but that's a development kit which costs money that I don't have.

So...back to the question at hand now, how can I programmatically get a current snapshot of a core's clock speed? There must be a way.

P.S. With turbo boost and other technologies, core speeds are variable. That is why I want to get this information as a current time snapshot. For monitoring purposes, such an application would be helpful to an end-user in order to facilitate them with detecting whether or not their system is configured properly, working correctly, and would allow them to monitor their system and see what performance is like under load, etc. Also, there is no harm in knowing how to get this data.

Community
  • 1
  • 1
Alexandru
  • 12,264
  • 17
  • 113
  • 208
  • 1
    you can use this command: wmic cpu get CurrentClockSpeed –  Apr 22 '14 at 13:54
  • 1
    Here is the WMI object: http://msdn.microsoft.com/en-us/library/aa394373.aspx – Dark Falcon Apr 22 '14 at 13:56
  • @SouthPole That does not work. Point 1: It gives the processor clock speed. My question asks for the speed of each core. Point 2: The value this returns never changes. I know it does change, though, since I have turbo boost on. Speccy shows me when turbo boost is engaged and shows me that increase in frequency for each core but "wmic cpu get CurrentClockSpeed" does not. – Alexandru Apr 22 '14 at 14:41
  • @DarkFalcon That doesn't help. I've already read through this article, and my question links WMI objects. It doesn't have any directives for core frequency as far as I can tell. Only processor clock speed. This is the clock speed of the processor, but I want to know the speed of each individual core in that processor. – Alexandru Apr 22 '14 at 14:45
  • @Alexandru: My apologies, on older OSes, that class models cores, not processors. It appears that has been corrected in Windows Vista and later. – Dark Falcon Apr 22 '14 at 14:58
  • @DarkFalcon I feel like I might need to find a way to calculate it because nothing seems to return back a variable rate :( – Alexandru Apr 22 '14 at 20:56
  • @DarkFalcon I figured it out: http://www.dima.to/blog/?p=101 – Alexandru Jun 10 '14 at 14:55

1 Answers1

0

Try CallNtPowerInformation. Here is an example by someone else:

#include <NTstatus.h>
#define WIN32_NO_STATUS
#include <windows.h>
#include <Powrprof.h>
#include <iostream>

typedef struct _PROCESSOR_POWER_INFORMATION {
   ULONG  Number;
   ULONG  MaxMhz;
   ULONG  CurrentMhz;
   ULONG  MhzLimit;
   ULONG  MaxIdleState;
   ULONG  CurrentIdleState;
} PROCESSOR_POWER_INFORMATION, *PPROCESSOR_POWER_INFORMATION;

#pragma comment(lib, "Powrprof.lib")

int main()
{
   // get the number or processors 
   SYSTEM_INFO si = {0};
   ::GetSystemInfo(&si);
   // allocate buffer to get info for each processor
   const int size = si.dwNumberOfProcessors * sizeof(PROCESSOR_POWER_INFORMATION);
   LPBYTE pBuffer = new BYTE[size]; 

   NTSTATUS status = ::CallNtPowerInformation(ProcessorInformation, NULL, 0, pBuffer, size);
   if(STATUS_SUCCESS == status)
   {
      // list each processor frequency 
      PPROCESSOR_POWER_INFORMATION ppi = (PPROCESSOR_POWER_INFORMATION)pBuffer;
      for(DWORD nIndex = 0; nIndex < si.dwNumberOfProcessors; nIndex++)
      {
         std::cout << "Processor #" << ppi->Number << " frequency: " 
            << ppi->CurrentMhz << " MHz" << std::endl;
         ppi++;
      }
   }
   else
   {
      std::cout << "CallNtPowerInformation failed. Status: " << status << std::endl;
   }
   delete []pBuffer;
   system("pause");
   return status;
}
Dark Falcon
  • 43,592
  • 5
  • 83
  • 98
  • Hey, this is a good find, but this also doesn't work. I modified it a little bit, linked in the PowrProf.lib and threaded it out, but for all my cores it always gives a frequency of 1729 MHz which is not always the case. :( For example, Speccy shows my core speeds idling at ~900 MHz and it can sometimes jump to 2600 MHz, which seems more accurate and at least is tangible under load. – Alexandru Apr 22 '14 at 15:27
  • Here are my changes if anyone's curious: http://pastebin.com/vHDiEfGX Just be sure to link PowrProf.lib into your project's linker settings (simple C++ console application). – Alexandru Apr 22 '14 at 15:32
  • This used to work, but no longer does. I suspect this may have to do with security? Apparently, knowing how busy the CPU cores are, is a potential security breach. – Bram Apr 16 '23 at 22:42