.NET Thread

SpriteMidr

Active Member
Is there any way to get the current CPU clock speed (variable, not maximum) for the system I am using in C♯?

I am currently using the following

Code:
using System;
using System.Threading; // Sleep
// Add reference to following
using System.Management;

static class App {
  static void Main(string[] args) {
    // WMI query
    const string WQL_QUERY = "SELECT DeviceID, Name, CurrentClockSpeed FROM Win32_Processor;";
   
    var wmiSearcher = new ManagementObjectSearcher(WQL_QUERY);
   
    // Perform in a loop.
    while(true) {
      // Set cursor position to 0,0 (quicker to overwrite than to clear)
      Console.SetCursorPosition(0,0);

      // Perform search, store results (each CPU available) in a ManagementObjectCollection
      ManagementObjectCollection resultCollection = wmiSearcher.Get();

      // For each result
      foreach(ManagementObject result in resultCollection) {
        var device = result["DeviceID"].ToString();
        var name = result["Name"].ToString();
        var speedSz = result["CurrentClockSpeed"].ToString();
        var speed = uint.Parse(speedSz);
       
        // Output result
        App.FormatOutput(device, name, speed);
      }
      // Wait two seconds
      Thread.Sleep(2000);
      continue; // (not needed, but useful notation for this example, hence why it is included).
    }
  }

  private static void FormatOutput(string device, string name, uint speed) {
    Console.Out.WriteLine("{0} ({1}) is running at {0,5} MHz.", device, name, speed);
  }
}
Link to working code on Github

The code above is dumbed down to just printing to the console. My actual app is graphing the result (hence the link), so the code is a bit more complex, but uses the same principle.

I just feel that performing a SQL (well, WQL) query every two seconds is a bit stupid. It is a complex operation, so it keeps making the clock speed spike whenever it executes.

Any ideas are welcome :)

Thanks
 

SpriteMidr

Active Member

Cromewell

Administrator
Staff member
Sorry, didn't read all your code the first time, I just saw the question and assumed you were using MaxClockSpeed.

HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\# has the MHz speed, but I'm pretty sure that's the max speed.

I wasn't able to find anything C# besides the WMI documentation. As you mentioned the PerformanceCounters don't show quite what you are looking for.

I found someone who's implemented it in a very short assembly program but I don't know of a way to run assembly from c# (c/++ is another story ;))
 

SpriteMidr

Active Member
Sorry, didn't read all your code the first time, I just saw the question and assumed you were using MaxClockSpeed.

HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\# has the MHz speed, but I'm pretty sure that's the max speed.

I wasn't able to find anything C# besides the WMI documentation. As you mentioned the PerformanceCounters don't show quite what you are looking for.

I found someone who's implemented it in a very short assembly program but I don't know of a way to run assembly from c# (c/++ is another story ;))

In C#, can you use a compiled DLL? iirc there is an extern command, as you can use the Win32 API, and that is not dotnet.

In C/C++ I believe there is an Assembly module, so could I use the assembly module to interface with it in C and then compile down to a DLL that I can implement in C#?

Or am I talking garbage?
 

Cromewell

Administrator
Staff member
Yeah in C you can use asm (assembly instructions).

You can call to dlls in c# but I don't have experience doing that. I can look it up and help if you have trouble with it, but at that point we're doing the same thing :)
 

SpriteMidr

Active Member
Yeah in C you can use asm (assembly instructions).

You can call to dlls in c# but I don't have experience doing that. I can look it up and help if you have trouble with it, but at that point we're doing the same thing :)

Ah okydokes :)

I might look into it more after my exams are over.

Thanks again for the help! Appreciate it.
 

SpriteMidr

Active Member
Yeah in C you can use asm (assembly instructions).

You can call to dlls in c# but I don't have experience doing that. I can look it up and help if you have trouble with it, but at that point we're doing the same thing :)

Been having a fiddle with the cpuid instruction in assembly (had to use C, not C#, but I thought I might as well post the general idea just in case anyone else wants to know)... seems you can get most of the info from WMI in C using inline Assembly.

The following prints either GenuineIntel or AuthenticAmd depending on your cpu...

Code:
#include <Windows.h>
#include <stdio.h>

/*
 * Get the CPU vendor ID.
 * out - a 13 byte long char buffer to fill.
 */
void getVendorId(char* output) {
  DWORD b, c, d; // 4 byte integer

  __asm {
    mov eax, 0x0 // Move the eaxVal param to eax
    cpuid           // call cpuid op
    mov b, ebx
    mov c, ecx
    mov d, edx
  };

  // Use char buffers for each integer value to abstract the int
  char bBuff[4], cBuff[4], dBuff[4];

  // Copy data to buffers
  memcpy(bBuff, &b, 4);
  memcpy(cBuff, &c, 4);
  memcpy(dBuff, &d, 4);

  // Concatenate the char buffers for each register to one string
  static char buff[13];

  int i;
  // Copy the buffer contents over. Remembering that
  // each buffer is NOT null terminated, so we don't 
  // want to buffer overflow.
  for (i = 0; i < sizeof(buff); ++i) {
    if (i >= 0 && i <= 3)
      buff[i] = bBuff[i % 4];
    else if (i > 3 && i <= 7)
      buff[i] = dBuff[i % 4];
    else if (i > 7 && i <= 11)
      buff[i] = cBuff[i % 4];
    else
      buff[i] = NULL;
  }

  // Copy the buffer to output
  strcpy_s(output, 13, buff);
}

int main() {
  char vendorId[13];
  getVendorId(vendorId);
  printf("Vendor ID: %s\n", vendorId);
  gets(stdin);
}

(Compiled using Visual C)

<edit: improved code readability>
 
Last edited:
Top