9

How can I get in c# the CPU frequency (example : 2Ghz) ? It's simple but I don't find it in the environnement variables. Thanks :)

Orpheo
  • 386
  • 1
  • 6
  • 15

5 Answers5

14
 var searcher = new ManagementObjectSearcher(
            "select MaxClockSpeed from Win32_Processor");
 foreach (var item in searcher.Get())
 {
      var clockSpeed = (uint)item["MaxClockSpeed"];
 }

if you wish to get other fields look at class Win32_processor

wiero
  • 2,176
  • 1
  • 19
  • 28
5

Try this code

using System.Management;

uint currentsp , Maxsp;
public void CPUSpeed()
{
   using(ManagementObject Mo = new ManagementObject("Win32_Processor.DeviceID='CPU0'"))
   {
       currentsp = (uint)(Mo["CurrentClockSpeed"]);
       Maxsp = (uint)(Mo["MaxClockSpeed"]);
   }
}
Amir Ismail
  • 3,865
  • 3
  • 20
  • 33
  • 1
    `CurrentClockSpeed` sounds like the current one, not the maximum :) – Matten Aug 03 '11 at 08:47
  • 1
    you should use a dispose statement. using(ManagementObject Mo = new ManagementObject("Win32_Processor.DeviceID='CPU0'")) { ... } – nakhli Aug 03 '11 at 08:51
  • 3
    @Matten just replace CurrentClockSpeed by MaxClockSpeed and you are done – nakhli Aug 03 '11 at 08:53
  • 2
    @Chaker Nakhli -- ok, then this is the preferable solution – Matten Aug 03 '11 at 08:55
  • 1
    I do not recommend to use ManagementObject as it is way slow. It takes up to 1 second, while ManagementObjectSearcher does the same in under 100ms. Microsoft recommends to use ManagementClass instead of ManagementObject as it addresses peroformance issues, though some quries stop working. E.g. "Win32_Processor.DeviceID='CPU0'" – sampai Nov 27 '13 at 09:25
  • @sampai I couldn't find any sources for your statement. Can you please provide a source for that? And preferably also example code in a separate answer. – ygoe Sep 15 '18 at 15:15
4

If you want to get the turbo speed, you can make use of the "% Processor Performance" performance counter and multiply it with the WMI "MaxClockSpeed" as follows:

private string GetCPUInfo()
{
  PerformanceCounter cpuCounter = new PerformanceCounter("Processor Information", "% Processor Performance", "_Total");
  double cpuValue = cpuCounter.NextValue();

  Thread loop = new Thread(() => InfiniteLoop());
  loop.Start();

  Thread.Sleep(1000);
  cpuValue = cpuCounter.NextValue();
  loop.Abort();

  foreach (ManagementObject obj in new ManagementObjectSearcher("SELECT *, Name FROM Win32_Processor").Get())
  {
    double maxSpeed = Convert.ToDouble(obj["MaxClockSpeed"]) / 1000;
    double turboSpeed = maxSpeed * cpuValue / 100;
    return string.Format("{0} Running at {1:0.00}Ghz, Turbo Speed: {2:0.00}Ghz",  obj["Name"], maxSpeed, turboSpeed);
  }

  return string.Empty;
}

The InfiniteLoop method is simply an integer that gets 1 added and subtracted:

private void InfiniteLoop()
{
  int i = 0;

  while (true)
    i = i + 1 - 1;
}

The InfiniteLoop method is just added to give the CPU something to do and turbo in the process. The loop is allowed to run for a second before the next value is taken and the loop aborted.

RooiWillie
  • 2,198
  • 1
  • 30
  • 36
  • Thank you - unlike CurrentClockSpeed query this actually gives you the real current processor frequency. I removed infiniteloop because I'm interested in current state, not the max possible frequency – DAG Jun 27 '20 at 12:47
3

One could take the information out of the registry, but dunno if it works on Windows XP or older (mine is Windows 7).

HKEY_LOCAL_MACHINE/HARDWARE/DESCRIPTION/CentralProcessor/0/ProcessorName 

reads like

Intel(R) Core(TM)2 Quad CPU    Q6600  @ 2.40GHz

for me.

Something like this code could retrieve the information (not tested):

RegistryKey processor_name = Registry.LocalMachine.OpenSubKey(@"Hardware\Description\System\CentralProcessor\0", RegistryKeyPermissionCheck.ReadSubTree);  


if (processor_name != null)
{
  if (processor_name.GetValue("ProcessorNameString") != null)
  {
    string value = processor_name.GetValue("ProcessorNameString");
    string freq = value.Split('@')[1];
    ...
  }
}

(source: here)

Matten
  • 17,365
  • 2
  • 42
  • 64
2

You can get it via WMI, but it's quite slow so if you're going to be getting it on more than one occasion I'd suggest you cache it - something like:

namespace Helpers
{
    using System.Management;

    public static class HardwareHelpers
    {
        private static uint? maxCpuSpeed = null;
        public static uint MaxCpuSpeed
        {
            get
            {
                return maxCpuSpeed.HasValue ? maxCpuSpeed.Value : (maxCpuSpeed = GetMaxCpuSpeed()).Value;
            }
        }

        private static uint GetMaxCpuSpeed()
        {
            using (var managementObject = new ManagementObject("Win32_Processor.DeviceID='CPU0'"))
            {
                var sp = (uint)(managementObject["MaxClockSpeed"]);

                return sp;
            }
        }
    }
}
Steven Robbins
  • 26,441
  • 7
  • 76
  • 90