I forgot to mention, the "GetSystemTimes" routine requires, at minimum, Windows XP SP1.
toralf wrote:
You used a "?" inside your var names
I use "?" as a record operator to denote a field, as opposed to "." since that is unavailable.
toralf wrote:
And I still do not understand some of the math you did (bitshift and *).
First, all times are stored in ms. Second, most of the math is irrelevant -- my mistake. I forgot AHk (and ReadInteger) supports 64-bit signed integers.
Below is the revised version with some comments to explain why?:
Code:
SetBatchLines, -1
SetFormat, float, 0.0 ; set same display format as that in Process Explorer
CoordMode, ToolTip, screen
period = 1000 ; sample period
loop
{
; first sample
idleTime = idleTime1
GetIdleTime( idleTime )
start := a_TickCount
Sleep, %period%
; second sample
elapsed := a_TickCount-start
idleTime = idleTime2
GetIdleTime( idleTime )
total_idle_ticks := ( idleTime2?ticks-idleTime1?ticks )*0.0001 ; calculate difference and convert to ms
ppu_idle := total_idle_ticks/elapsed*100 ; ppu = Percentage Processor Usage
total := elapsed-total_idle_ticks
ppu := 100-ppu_idle
ToolTip, period = %period% (ideal)`nelapsed = %elapsed% (actual)`n`nppu = %total% ms (%ppu%`%)`nidle = %total_idle_ticks% ms (%ppu_idle%`%), 10, 10
}
ReadInteger( p_address, p_offset, p_size, p_hex=true )
{
old_FormatInteger := a_FormatInteger
if ( p_hex )
SetFormat, integer, hex
else
SetFormat, integer, dec
value = 0
loop, %p_size%
value := value+( *( ( p_address+p_offset )+( a_Index-1 ) ) << ( 8* ( a_Index-1 ) ) )
SetFormat, integer, %old_FormatInteger%
return, value
}
GetIdleTime( p_IdleTime )
{
global
local success
/*
struct FILETIME {
DWORD dwLowDateTime; uint4 0
DWORD dwHighDateTime; uint4 4
}
*/
VarSetCapacity( %p_IdleTime%?ticks, 4+4 )
; GetSystemTimes returns pointers to 64-bit signed integers (aka, ticks). ticks are are the
; number of 100-nanosecond intervals since January 1, 1601 -- a Microsoft thing.
success := DllCall( "kernel32.dll\GetSystemTimes", "uint", &%p_IdleTime%?ticks, "uint", 0, "uint", 0 )
if ( ! success )
{
MsgBox, GetSystemTimes failed!
ExitApp
}
; convert binary 64-bit signed integer to AHk format
%p_IdleTime%?ticks := ReadInteger( &%p_IdleTime%?ticks, 0, 8 )
}
When evaluating discrepancies between the processor usage (PU) as given by this method and others, consider the following:
1. The sample period is set at 1 s.
2. The clock resolution for timing may only be 10 ms.
3. The system PU is tracking the PU of the System Idle Process. This may or may not be the statistic used by the Windows performance library to determine the system PU.
4. There may occur an offset, due to indirect tracking of the System Idle Process. Code within the Idle Process, will produce the most accurate results (i.e., discrepancy between retrieving system idle time and elapsed time).