Unable to get current CPU frequency in Powershell or Python - windows
I am trying to somehow programamtically log the CPU frequency of my windows 10 machine. However I apparently fail to get the current frequency as shown in the task manager.
in Powershell, using
get-wmiobject Win32_Processor -Property CurrentClockSpeed
does only return a clock speed that is exactly the maximum one (even though i can see in task manager that it is not running that high)
I even tried this solution: https://www.remkoweijnen.nl/blog/2014/07/18/get-actual-cpu-clock-speed-powershell/ but it did not give me anything but a static value = max value.
Even python's psutil does only return a static value.
Does anybody know how to get around this and actually somehow log the CPU frequency each x seconds?
any help would be appreciated, thanks!
TLDR: To find the Current Processor Frequency, you have to use the % Processor Performance performance counter:
$MaxClockSpeed = (Get-CimInstance CIM_Processor).MaxClockSpeed
$ProcessorPerformance = (Get-Counter -Counter "\Processor Information(_Total)\% Processor Performance").CounterSamples.CookedValue
$CurrentClockSpeed = $MaxClockSpeed*($ProcessorPerformance/100)
Write-Host "Current Processor Speed: " -ForegroundColor Yellow -NoNewLine
Write-Host $CurrentClockSpeed
The more in depth explanation as to why does querying WMI Win32_Processor for CurrentClockSpeed seem to always return the maximum frequency rather than the actual "Current Clock Speed"? In fact, why do all of the dozens of WMI/CMI/Perfmon counters all seem to return the "wrong" frequency? If CPU-Z and Task Manager can get it, what do we have to do to get the "actual" frequency? To answer that, we need to understand what CurrentClockSpeed is actually returning.
From the WMI documentation for Win32_Processor CurrentClockSpeed:
Current speed of the processor, in MHz. This value comes from the
Current Speed member of the Processor Information structure in the
SMBIOS information.
Great! One would think that this simple query should get us the current frequency. This worked great a dozen years ago, but nowadays it doesn't; because it really only works for two very specific cases:
When you have a processor that only runs at its defined stock speed.
When a mobile processor is asked by Windows to run at a different speed (e.g. moving to battery mode).
At startup, Widows gets the processor information and gets the Current Clock Speed. Most people are running their processor at the recommended settings so Current Clock Speed == Max Clock Speed, which mean that the two numbers match all the time. When you change power states, Windows will change the frequency, and CurrentClockSpeed will be changed as well.
Now, what happened a dozen years ago to essentially make CurrentClockSpeed completely inaccurate/irrelevant? You can ultimately thank Intel. They essentially blew this whole ideal value out of the water thanks to a new technology called Turbo Boost.
What does Turbo Boost have to do with this?
Turbo Boost dynamically changes the processor frequency based on the current load on the processor within the confines of voltage, current, and thermal envelopes. Almost all modern processors also now have power saving modes and can dynamically change their frequencies based on their current marketing buzzword (e.g. Turbo Boost (up), Cool'N'Quiet (down)).
The key point is: all this frequency moving up/down/off/on is all automatically done without Windows knowing about it. Because Windows doesn't know about it, the CurrentClockSpeed value could be completely inaccurate most of the time. In fact, Microsoft knows this, and when you open your Performance Monitor, and you look at the description under Processor Performance/Processor Frequency:
Processor Frequency is the frequency of the current processor in
megahertz. Some processors are capable of regulating their frequency
outside of the control of Windows. Processor Frequency will not
accurately reflect actual processor frequency on these systems. Use
Processor Information\% Processor Performance instead.
Fortunately this description gives us a hint of what we have to use to get the actual value: Processor Information\% Processor Performance
We can use Get-Counter to access the current Processor performance like so:
PS C:\> Get-Counter -Counter "\Processor Information(_Total)\% Processor Performance"
Timestamp CounterSamples
--------- --------------
2020-01-01 1:23:45 AM \\HAL9256\processor information(_total)\% processor performance :
153.697654229441
Here, you can see that my processor is running at 153% performance a.k.a. 153% of the frequency of the processor (yay for Turbo Boost!). We then query the MaxClockSpeed from CIM_Processor class (you can use WMI_Processor as well):
PS C:\> (Get-CimInstance CIM_Processor).MaxClockSpeed
2592
In order to calculate out the actual clock speed:
$MaxClockSpeed = (Get-CimInstance CIM_Processor).MaxClockSpeed
$ProcessorPerformance = (Get-Counter -Counter "\Processor Information(_Total)\% Processor Performance").CounterSamples.CookedValue
$CurrentClockSpeed = $MaxClockSpeed*($ProcessorPerformance/100)
Write-Host "Current Processor Speed: " -ForegroundColor Yellow -NoNewLine
Write-Host $CurrentClockSpeed
Then wrapping it up in a loop if you need it to run every 2 seconds (Ctrl+C to stop):
$MaxClockSpeed = (Get-CimInstance CIM_Processor).MaxClockSpeed
While($true){
$ProcessorPerformance = (Get-Counter -Counter "\Processor Information(_Total)\% Processor Performance").CounterSamples.CookedValue
$CurrentClockSpeed = $MaxClockSpeed*($ProcessorPerformance/100)
Write-Host "Current Processor Speed: " -ForegroundColor Yellow -NoNewLine
Write-Host $CurrentClockSpeed
Sleep -Seconds 2
}
With help of the PS code above and the doc of win32pdh, I'm able to get it work in Python:
from win32pdh import PDH_FMT_DOUBLE
from win32pdh import OpenQuery, CloseQuery, AddCounter
from win32pdh import CollectQueryData, GetFormattedCounterValue
def get_freq():
ncores = 16
paths = []
counter_handles = []
query_handle = OpenQuery()
for i in range(ncores):
paths.append("\Processor Information(0,{:d})\% Processor Performance".format(i))
counter_handles.append(AddCounter(query_handle, paths[i]))
CollectQueryData(query_handle)
time.sleep(1)
CollectQueryData(query_handle)
freq = []
for i in range(ncores):
(counter_type, value) = GetFormattedCounterValue(counter_handles[i], PDH_FMT_DOUBLE)
freq.append(value*2.496/100)
# 2.496 is my base speed, I didn't spend time to automate this part
# print("{:.3f} Ghz".format(max(freq)))
CloseQuery(query_handle)
return "{:.3f} GHz".format(max(freq))
Related
System.Diagnostics.PerformanceCounter current CPU usage in GHz
I need the information of the current CPU usage in GHz as the Task Manager shows is under Performance in the Speed variable. Is it possible to get this information from the method? I need it in Matlab by the way. I was hoping to use this function for it: Show CPU cores utilization in MATLAB Thanks.
So, the answer is: obj = System.Diagnostics.PerformanceCounter('Processor Information', '% Processor Performance', '_Total'); current_frequency = obj.NextValue * base_frequency;
What does DPCRate stand for in Win32_PerfRawData_Counters_ProcessorInformation WMI Class?
While studying Deferred Procedure Calls I came to some properties/data I could not find any information about on the web. Using WMI I can read a lot of processor data, including DPC data. Many properties of the Win32_PerfRawData_Counters_ProcessorInformation WMI class are self-explanatory, for example InterruptsPerSec or PercentInterruptTime. One of the properties is called DPCRate. Powershell code to get the value: Get-CimInstance -Class Win32_PerfRawData_Counters_ProcessorInformation | Format-Table -Property DPCRate On my system the value of the DPCRate varies between 40 and 70. What is the meaning of this value? What does it measure? I could not find anything in Microsoft's WMI documentation.
DPCRate : DPC Rate is the rate at which deferred procedure calls (DPCs) were added to the processors DPC queues between the timer ticks of the processor clock. DPCs are interrupts that run at alower priority than standard interrupts. Each processor has its own DPC queue. This counter measures the rate that DPCs were added to the queue, not the number of DPCs in the queue. This counter displays the last observed value only; it is not an average. Refer to The WMI Explorer Tool for getting a PowerShell WMI Browser tool for querying WMI class and its properties description. Update:
Windows CPU temps
How can I check CPU temp from the command line in Windows 10? I have an older computer that I installed a pre-assembled CPU cooler with radiator from Corsair, and I think that it is failing because I get CPU overtemp messages at reboot. I realize that there are freeware apps that are capable of delivering this information, and I have installed the ASUS AI suite that goes with my motherboard and that is giving me the information that I want. But it is a little infuriating that I have to install this software to get the temperature data. I have found a script at this link that runs in powershell that calls the temp and sets it to a variable like so: function Get-Temperature { $t = Get-WmiObject MSAcpi_ThermalZoneTemperature -Namespace "root/wmi" And I guess that WMiObject is supposed to return a temperature in (degrees Kelvin)*e+2, because later in the script it does conversions which return Kelvin, Celsius and Farenheit. However, when I run it on my machine it returns 0 Kelvin and -273 Celsius and whatever that is in Fahrenheit. I assume that something in that line is wrong? Can you help?
How I know if CPU is Haswell or Not
You know, haswell is the codename for a processor microarchitecture developed by Intel as the "fourth-generation core" successor to the Ivy Bridge microarchitecture.1 Intel officially announced CPUs based on this microarchitecture... More But, I want to know how to show's up my CPU if haswell or not by using the PowerShell in windows? in this case i have a script to to that, but it maybe not legal for everyone: $cpuname = (Get-CimInstance CIM_Processor).Name $splcpuall = #($cpuname -csplit "") $splcpu = $splcpuall[20] $ishaswell = if ($splcpu -gt 3){ Write-Output "Haswell" }
Identifying a CPU needs some digging and regular maintenance for new CPU models is needed too. Your best bet is to use some existing tool that provides CPU information. For example, CPU-Z is nice a tool. The problem is that CPUs don't contain human readable name strings. What they contain is a CPUID, a hex code that must be looked up and interpreted as model name. Hashwell's ID is 0x0306C3, Broadwell's is 0x0306D4 and so on. Digging up the CPUID can be done via WMI. On a Broadwell box: (gwmi win32_processor).ProcessorId BFEBFBFF000306D4 The result is a string combination that contains stuff in addition to the CPU ID. This needs to be parsed to identify the CPU ID part and then the matched name must be looked up from somewhere.
Tracking CPU and Memory usage per process
I suspect that one of my applications eats more CPU cycles than I want it to. The problem is - it happens in bursts, and just looking at the task manager doesn't help me as it shows immediate usage only. Is there a way (on Windows) to track the history of CPU & Memory usage for some process. E.g. I will start tracking "firefox", and after an hour or so will see a graph of its CPU & memory usage during that hour. I'm looking for either a ready-made tool or a programmatic way to achieve this.
Press Win+R, type perfmon and press Enter. When the Performance window is open, click on the + sign to add new counters to the graph. The counters are different aspects of how your PC works and are grouped by similarity into groups called "Performance Object". For your questions, you can choose the "Process", "Memory" and "Processor" performance objects. You then can see these counters in real time You can also specify the utility to save the performance data for your inspection later. To do this, select "Performance Logs and Alerts" in the left-hand panel. (It's right under the System Monitor console which provides us with the above mentioned counters. If it is not there, click "File" > "Add/remove snap-in", click Add and select "Performance Logs and Alerts" in the list".) From the "Performance Logs and Alerts", create a new monitoring configuration under "Counter Logs". Then you can add the counters, specify the sampling rate, the log format (binary or plain text) and log location.
Process Explorer can show total CPU time taken by a process, as well as a history graph per process.
Using perfmon.exe, I have tried using the "Private Bytes" counter under "Process" counters for tracking memory usage and it works well.
maybe you can use this. It should work for you and will report processor time for the specified process. #echo off : Rich Kreider <rjk#techish.net> : report processor time for given process until process exits (could be expanded to use a PID to be more : precise) : Depends: typeperf : Usage: foo.cmd <processname> set process=%~1 echo Press CTRL-C To Stop... :begin for /f "tokens=2 delims=," %%c in ('typeperf "\Process(%process%)\%% Processor Time" -si 1 -sc 1 ^| find /V "\\"') do ( if %%~c==-1 ( goto :end ) else ( echo %%~c%% goto begin ) ) :end echo Process seems to have terminated.
I agree, perfmon.exe allows you to add counters (right click on the right panel) for any process you want to monitor. Performance Object: Process Check "Select instances from list" and select firefox.
WMI is Windows Management Instrumentation, and it's built into all recent versions of Windows. It allows you to programmatically track things like CPU usage, disk I/O, and memory usage. Perfmon.exe is a GUI front-end to this interface, and can monitor a process, write information to a log, and allow you to analyze the log after the fact. It's not the world's most elegant program, but it does get the job done.
Process Lasso is designed more for process automation and priority class optimization, not graphs. That said, it does offer per-process CPU utilization history (drawn as a white line on the graph) but it does NOT offer per-process memory utilization history. DISCLAIMER: I am the author of Process Lasso, but am not actually endorsing it here - as there are better solutions (perfmon being the best). The best thing ever is Windows Vista+ Resource and Performance Monitor. It can track usage of CPU, Memory, Network, and Disk accesses by processes over time. It is a great overall system information utility that should have been created long ago. Unless I am mistaken, it can track per-process CPU and memory utilization over time (amongst the other things listed).
You can also try using a C#/Perl/Java script get the utilization data using WMI Commands, and below is the steps for it. We need to execute 2 WMI Select Queries and apply CPU% utilization formula 1. To retrieve the total number of logical process select NumberOfLogicalProcessors from Win32_ComputerSystem 2. To retrieve the values of PercentProcessorTime, TimeStamp_Sys100NS ( CPU utilization formula has be applied get the actual utilization percentage)and WorkingSetPrivate ( RAM ) minimum of 2 times with a sleep interval of 1 second select * from Win32_PerfRawData_PerfProc_Process where IDProcess=1234 3. Apply CPU% utilization formula CPU%= ((p2-p1)/(t2-t1)*100)/NumberOfLogicalProcessors p2 indicated PercentProcessorTime retrieved for the second time, and p1 indicateds the PercentProcessorTime retrieved for the first time, t2 and t1 is for TimeStamp_Sys100NS. A sample Perl code for this can be found in the link http://www.craftedforeveryone.com/cpu-and-ram-utilization-of-an-application-using-perl-via-wmi/ This logic applies for all programming language which supports WMI queries
Although I have not tried this out, ProcDump seems like a better solution. Description from site: ProcDump is a command-line utility whose primary purpose is monitoring an application for CPU spikes and generating crash dumps during a spike that an administrator or developer can use to determine the cause of the spike. ProcDump also includes hung window monitoring (using the same definition of a window hang that Windows and Task Manager use), unhandled exception monitoring and can generate dumps based on the values of system performance counters. It also can serve as a general process dump utility that you can embed in other scripts.
There was a requirement to get status and cpu / memory usage of some specific windows servers. I used below script: This is an example of Windows Search Service. $cpu = Get-WmiObject win32_processor $search = get-service "WSearch" if ($search.Status -eq 'Running') { $searchmem = Get-WmiObject Win32_Service -Filter "Name = 'WSearch'" $searchid = $searchmem.ProcessID $searchcpu1 = Get-WmiObject Win32_PerfRawData_PerfProc_Process | Where {$_.IDProcess -eq $searchid} Start-Sleep -Seconds 1 $searchcpu2 = Get-WmiObject Win32_PerfRawData_PerfProc_Process | Where {$_.IDProcess -eq $searchid} $searchp2p1 = $searchcpu2.PercentProcessorTime - $searchcpu1.PercentProcessorTime $searcht2t1 = $searchcpu2.Timestamp_Sys100NS - $searchcpu1.Timestamp_Sys100NS $searchcpu = [Math]::Round(($searchp2p1 / $searcht2t1 * 100) /$cpu.NumberOfLogicalProcessors, 1) $searchmem = [Math]::Round($searchcpu1.WorkingSetPrivate / 1mb,1) Write-Host 'Service is' $search.Status', Memory consumed: '$searchmem' MB, CPU Usage: '$searchcpu' %' } else { Write-Host Service is $search.Status -BackgroundColor Red }
Hmm, I see that Process Explorer can do it, although its graphs are not too convenient. Still looking for alternative / better ways to do it.
Perfmon.exe is built into windows.
You might want to have a look at Process Lasso.
I use taskinfo for history graph of CPU/RAM/IO speed. http://www.iarsn.com/taskinfo.html But bursts of unresponsiveness, sounds more like interrupt time due to a falty HD/SS drive.
Under Windows 10, the Task Manager can show you cumulative CPU hours. Just head to the "App history" tab and "Delete usage history". Now leave things running for an hour or two: What this does NOT do is break down usage in browsers by tab. Quite often inactive tabs will do a tremendous amount of work, with each open tab using energy and slowing your PC.
Download process monitor Start Process Monitor Set a filter if required Enter menu Options > Profiling Events Click "Generate thread prof‌iling events", choose the frequency, and click OK. To see the collected historical data at any time, enter menu Tools > Process Activity Summary