I've been struggling to come up with a correct code to determine CPU usage
on the Windows-based system. So far I came up with the following. The code
is called internally from WM_TIMER message that is called once every 100
milliseconds, but if compared with the Task Manager's CPU usage, it does not
always match. What could be the reason for that?
int g_nCPU_usage_percent; //Global variable
....
SetTimer(m_hMainWndHandle, TIMER_ID, 100, NULL);
....
void OnTimer(UINT nIDEvent)
{
g_nCPU_usage_percent = GetCPU_Usage();
}
....
int GetCPU_Usage()
{
//RETURN:
// = Percentage value [0-100], or
// = -1 if not known, or error
int nRes = -1;
FILETIME ftIdle, ftKrnl, ftUsr;
if(GetSystemTimes(&ftIdle, &ftKrnl, &ftUsr))
{
static BOOL bUsedOnce = FALSE;
static ULONGLONG uOldIdle = 0;
static ULONGLONG uOldKrnl = 0;
static ULONGLONG uOldUsr = 0;
ULONGLONG uIdle = ((ULONGLONG)ftIdle.dwHighDateTime << 32) |
ftIdle.dwLowDateTime;
ULONGLONG uKrnl = ((ULONGLONG)ftKrnl.dwHighDateTime << 32) |
ftKrnl.dwLowDateTime;
ULONGLONG uUsr = ((ULONGLONG)ftUsr.dwHighDateTime << 32) |
ftUsr.dwLowDateTime;
//Only if we have previous values
if(bUsedOnce)
{
ULONGLONG uDiffIdle = uIdle - uOldIdle;
ULONGLONG uDiffKrnl = uKrnl - uOldKrnl;
ULONGLONG uDiffUsr = uUsr - uOldUsr;
if(uDiffKrnl + uDiffUsr)
{
//Calculate percentage
nRes = (int)((uDiffKrnl + uDiffUsr - uDiffIdle) * 100 / (uDiffKrnl +
uDiffUsr));
}
}
//Remember data
bUsedOnce = TRUE;
uOldIdle = uIdle;
uOldKrnl = uKrnl;
uOldUsr = uUsr;
}
return nRes;
}
I remember working on a process manager sime time ago in C#. It seems
like I used WMI and PercentProcessorTime from
Win32_PerfFormattedData_PerfOS_Processor to get processes' usage or
something like that. Maybe you can try to look at that?
--
Regards,
Jackie
Maybe you can look at Win32_PerfRawData_PerfOS_Processor as well. :)
--
Regards,
Jackie
Tried to cancel my first replies. No idea if it worked.
Either way, I meant processors' usage and not processes' usage.
PercentProcessorTime from Win32_PerfFormattedData_PerfOS_Processor or
Win32_PerfRawData_PerfOS_Processor (via WMI).
I hope it help.
--
Regards,
Jackie
This approach is used by "ejor" at
<http://www.codeproject.com/KB/threads/Get_CPU_Usage.aspx>
But he warns that it doesn't give the correct
results with a multiprocessor system. I didn't
download his complete code, but he says it has a
solution for that.
Best regards,
Bob Masta
DAQARTA v5.10
Data AcQuisition And Real-Time Analysis
www.daqarta.com
Scope, Spectrum, Spectrogram, Sound Level Meter
Frequency Counter, FREE Signal Generator
Pitch Track, Pitch-to-MIDI
DaqMusic - FREE MUSIC, Forever!
(Some assembly required)
Science (and fun!) with your sound card!
Thanks!
I'll see what this does. Just curious though, how much of an imprint will a
call to those WMI classes put on the system if, say, I do it once every
second or so? I don't want to add too many CPU cycles to just run it, you
know.
PS. I don't think one can edit or remove previous posts.
Bob, thanks, but I don't think I want to use something that doesn't work in
multiprocessor environment (that's pretty much every CPU these days :)
I think I found a solution to use NtQuerySystemInformation API myself, but
if you look at its description it looks like they may change it at any time,
so I try to steer clear from functions like that.
I understand and agree. I am no expert on WMI but I read that you can
improve performance by reusing the WMI connection somehow or reusing the
locator. It also sounds logical to me that it will be some overhead with
processing the query (parsing the same string and finding what you want,
over and over again). I also read something about the LSASS process
using "a lot" of the CPU under Windows Server 2008 with queries to
remote machines. You could try to benchmark the methods you find (WMI,
that internal function or other ways). I don't really know more than
this, but I am kind of interested in the answer myself.
> PS. I don't think one can edit or remove previous posts.
Seems like it. I guess Thunderbird must be laughing at me for trying the
"Cancel message" option. Had my doubts so at least I was not completely
fooled.
--
Regards,
Jackie
Thanks, Jackie. If I find more info I will post it here.
Thank you as well. :)
--
Regards,
Jackie
How different is it?
CPU usage is an instantaneous value so two apps querying it will show
roughly the same profile but may well give different values.
--
Dee Earley (dee.e...@icode.co.uk)
i-Catcher Development Team
iCode Systems
(Replies direct to my email address will be ignored.
Please reply to the group.)
It's not that much different most of the times, but sometimes the Vista
gadget will spike up when my app still shows a much lower value. But I agree
that it's very hard to debug.
--
Regards,
Jackie
There's a class calld PSLProcessor:
http://www.prosyslib.org/Help/ProSysLib~PSLProcessor.html
There's a "Usage" member there as well.
I think the class should work on Windows 7 as well (the latest update
says something about Windows 7 so I would assume everything else works
on Windows 7 as well).
I saw some comments on Code Project by the author of this library, and
it seems like the internal function may be used. It's open source so
least you can have a look on the inside.
The library looks pretty interesting to me, actually.
I am interested in exactly how the API GetSystemTimes is not giving the
right info as said in the article mentioned earlier on Code Project,
since it says on MSDN "On a multiprocessor system, the values returned
are the sum of the designated times across all processors".
--
Regards,
Jackie