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 :)
5 Answers
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

- 2,176
- 1
- 19
- 28
-
-
1seems to return in MHz MaxClockSpeed Data type: uint32 Access type: Read-only Qualifiers: Units (MegaHertz) – kenny Jun 02 '15 at 20:12
-
I did this to convert it, `var clockSpeed = 0.001f * (uint)item["MaxClockSpeed"];` – Brad Moore Dec 16 '15 at 01:16
-
MaxClockSpeed does not correctly report a CPU's real maximum clock speed. Likewise, CurrentClockSpeed does not correctly report a CPU's real current clock speed. – CXL May 13 '22 at 20:54
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"]);
}
}

- 3,865
- 3
- 20
- 33
-
1
-
1you 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
-
1I 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
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.

- 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
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)

- 17,365
- 2
- 42
- 64
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;
}
}
}
}

- 26,441
- 7
- 76
- 90