Getting CPU usage percentage of current process from inside of the program
Note: This is Windows specific
It took me lots of searching and I couldn't find a single straightforward way of displaying the percentage usage
of a process the same way you see it in Task Manager. So after the time I spent to finally figure it out, I
decided to share my result in case someone is having the same issue when working on their own engine. so here it
goes:
The problem with CPU usage measuring is that the CPU processors are either on or off, you can't really measure
how much of a processor is working. you can measure how ever how many are working from overall at one instance
of time, but that still doesn't show you the average over time, which is what Task Manager does. Now I found
this code from this URL, so credits to them for it. It measures CPU resources by current process, but there's a
catch (more below) I will paste the initial code here as it is part of this solution:
include "windows.h"
static ULARGE_INTEGER lastCPU, lastSysCPU, lastUserCPU;
static int numProcessors;
static HANDLE self;
void init(){
SYSTEM_INFO sysInfo;
FILETIME ftime, fsys, fuser;
GetSystemInfo(&sysInfo);
numProcessors = sysInfo.dwNumberOfProcessors;
GetSystemTimeAsFileTime(&ftime);
memcpy(&lastCPU, &ftime, sizeof(FILETIME));
self = GetCurrentProcess();
GetProcessTimes(self, &ftime, &ftime, &fsys, &fuser);
memcpy(&lastSysCPU, &fsys, sizeof(FILETIME));
memcpy(&lastUserCPU, &fuser, sizeof(FILETIME));
}
double getCurrentValue(){
FILETIME ftime, fsys, fuser;
ULARGE_INTEGER now, sys, user;
double percent;
GetSystemTimeAsFileTime(&ftime);
memcpy(&now, &ftime, sizeof(FILETIME));
GetProcessTimes(self, &ftime, &ftime, &fsys, &fuser);
memcpy(&sys, &fsys, sizeof(FILETIME));
memcpy(&user, &fuser, sizeof(FILETIME));
percent = (sys.QuadPart - lastSysCPU.QuadPart) +
(user.QuadPart - lastUserCPU.QuadPart);
percent /= (now.QuadPart - lastCPU.QuadPart);
percent /= numProcessors;
lastCPU = now;
lastUserCPU = user;
lastSysCPU = sys;
return percent * 100;
}
The problem with this code is that while it works at getting the CPU percentage of the current process, the
results are way too accurate to be useful. if you printf()
the result of
getCurrentValue()
you will get a bunch
of zeros and occasionally a nonzero value that is high like 50% or more, which isn't really that useful as it
doesn't show you an overall view of what's happening.
This is -I assume and am not sure of- the dedicated core or nodes of your CPU that are working on your process.
Since the CPU multitasks, it won't be doing your process constantly but rather occasionally, especially if your
process is FPS-capped.
So what's the solution of this? simple, lets just measure the average of these recordings.
double CPU_Recordings[100];
double count = 0;
float ActualUsage = 0;
while (1)
{
CPU_Recordings[count] = getCurrentValue();
count++;
if (count == 100)
{
count = 0;
float CPU_sum = 0;
for (int i = 0; i < 100; i++)
CPU_sum += G->Debug.CPU[i];
ActualUsage = CPU_sum / 100;
}
printf("%.1f %% \n",ActualUsage);
}
(of course you can adjust array sizes and increment frequency to change how often this updates)
And voila, we have a result that is really close to what the Task Manager shows, something that could be of use
to
display how much CPU resources you are using.I hope this helps, and if there is any mistake or comment on this
or
how to improve it, I would gladly hear them.
-Wassim