BOOL QueryPerformanceCounter(
__out LARGE_INTEGER *lpPerformanceCount
);
LARGE_IN
TEGER startTimer()
{
LARGE_INTEGER start;
DWORD_PTR oldmask = SetThreadAffinityMask(GetCurrentThread(), 0);
QueryPerformanceCounter(&start);
SetThreadAffinityMask(GetCurrentThread(), oldmask);
return
start;
}
LARGE_INTEGER endTimer()
{
LARGE_INTE
GER stop;
DWORD_PTR oldmask = SetThreadAffinityMask(GetCurrentThread(), 0);
QueryPerformanceCounter(&stop);
SetThreadAffinityMask(GetCurrentThread(), oldmask);
return
stop;
}
I'm using those functions but I'm not sure in what type it returns values.
endTimer - startTimer = ? How to convert this result to get seconds ?
You need to get frequency and divide your 2 counters difference by it.
LARGE_INTEGER fr,t1,t2;
QueryPerformanceCounter(&t1);
// some lengthy code ...
QueryPerformanceCounter(&t2);
QueryPerformanceFrequency(&fr);
double diff_sec = (t2.QuadPart-t1.QuadPart)/(double)fr.QuadPart;
Related
I am trying to code task manager and i stuck with %CPU for each process dy PID.
I wrote something like, that:
static float CalculateCPULoad(unsigned long long idleTicks, unsigned long long totalTicks)
{
static unsigned long long _previousTotalTicks = 0;
static unsigned long long _previousIdleTicks = 0;
unsigned long long totalTicksSinceLastTime = totalTicks - _previousTotalTicks;
unsigned long long idleTicksSinceLastTime = idleTicks - _previousIdleTicks;
float ret = 1.0f - ((totalTicksSinceLastTime > 0) ? ((float)idleTicksSinceLastTime) / totalTicksSinceLastTime : 0);
_previousTotalTicks = totalTicks;
_previousIdleTicks = idleTicks;
return ret;
}
static unsigned long long FileTimeToInt64(const FILETIME& ft) { return (((unsigned long long)(ft.dwHighDateTime)) << 32) | ((unsigned long long)ft.dwLowDateTime); }
And was using it like:
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
printError("Failed to create Process Snap");
return FALSE;
}
pe.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hProcessSnap, &pe))
{
printError("Failed to move along process snap");
CloseHandle(hProcessSnap);
return FALSE;
}
do
{
printf("\n\n=====================================================");
_tprintf(TEXT("\n PROCESS NAME: %s"), pe.szExeFile);
printf("\n-----------------------------------------------------");
dwPriorityClass = 0;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
if (hProcess == NULL)
{
printError("Failed to open process");
}
else
{
for (int i = 0; i < 2; i++)
{
GetProcessTimes(hProcess, &exist, &exit, &lastKernel, &lastUser);
GetSystemTimes(&lastIdle, 0, 0);
GetCPULoad(lastIdle, lastKernel, lastUser);
Sleep(2500);
}
std::cout << GetCPULoad(lastIdle, lastKernel, lastUser) << "\n";
CloseHandle(hProcess);
}
} while (Process32Next(hProcessSnap, &pe));
CloseHandle(hProcessSnap);
return (TRUE);
}
I know that using sleep() here isnt a good idea,but i havent think up anything better for now.
Pls help me with some code examples,if you can.
Also i want to know am i right that:
CPU% for process= (1- (IdleSystemTimeDelta/TotalProcessTimeDelta))*100%
This is how i get_CPU in percent.
I use hash_map in order to have PID-time connection static to update it.
First time usage get_cpu_usage(int pid) returns zero every time,but with each next usage it will be more and more accurate(I use it with 0.5 sec period).
static int get_processor_number()
{
SYSTEM_INFO info;
GetSystemInfo(&info);
return (int)info.dwNumberOfProcessors;
}
static __int64 file_time_2_utc(const FILETIME* ftime)
{
LARGE_INTEGER li;
li.LowPart = ftime->dwLowDateTime;
li.HighPart = ftime->dwHighDateTime;
return li.QuadPart;
}
static int get_cpu_usage(int pid)
{
static int processor_count_ = -1;
static std::unordered_map<int, __int64> last_time_;
static std::unordered_map<int, __int64> last_system_time_;
FILETIME now;
FILETIME creation_time;
FILETIME exit_time;
FILETIME kernel_time;
FILETIME user_time;
__int64 system_time;
__int64 time;
__int64 system_time_delta;
__int64 time_delta;
int cpu = -1;
if (processor_count_ == -1)
{
processor_count_ = get_processor_number();
}
GetSystemTimeAsFileTime(&now);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
if (!GetProcessTimes(hProcess, &creation_time, &exit_time, &kernel_time, &user_time))
{
std::cout << "Unable to getProcessTime\n";
return -1;
}
system_time = (file_time_2_utc(&kernel_time) + file_time_2_utc(&user_time)) / processor_count_;
time = file_time_2_utc(&now);
if ((last_system_time_[pid] == 0) || (last_time_[pid] == 0))
{
last_system_time_[pid] = system_time;
last_time_[pid] = time;
return 0;
}
system_time_delta = system_time - last_system_time_[pid];
time_delta = time - last_time_[pid];
if (time_delta == 0)
{
std::cout << "timedelta=0";
return -1;
}
cpu = int((system_time_delta * 100 + time_delta / 2) / time_delta);
last_system_time_[pid] = system_time;
last_time_[pid] = time;
return cpu;
}
I am trying to calculate CPU usage per core using C++ and WinAPI, but I am not able to do that properly. Thus, I have managed to calculate it by following:
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include <windows.h>
#define SystemProcessorPerformanceInformation 0x8
#define SystemBasicInformation 0x0
int _tmain(int argc, _TCHAR* argv[])
{
typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
{
LARGE_INTEGER IdleTime;
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER Reserved1[2];
ULONG Reserved2;
} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
typedef struct _SYSTEM_BASIC_INFORMATION {
ULONG Reserved;
ULONG TimerResolution;
ULONG PageSize;
ULONG NumberOfPhysicalPages;
ULONG LowestPhysicalPageNumber;
ULONG HighestPhysicalPageNumber;
ULONG AllocationGranularity;
ULONG_PTR MinimumUserModeAddress;
ULONG_PTR MaximumUserModeAddress;
KAFFINITY ActiveProcessorsAffinityMask;
CCHAR NumberOfProcessors;
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
// SYSTEM_INFO sysinf;
if (argc<2)
{
printf("Please specify waiting time in seconds\n");
return -1;
}
int nWaitSec = _wtoi(argv[1]);
if (nWaitSec <= 0)
{
printf("Waiting interval in seconds should be positive integer\n");
return -1;
}
typedef DWORD(WINAPI * PNTQUERYSYSYTEMINFORMATION)(DWORD info_class, void *out, DWORD size, DWORD *out_size);
PNTQUERYSYSYTEMINFORMATION pNtQuerySystemInformation = NULL;
pNtQuerySystemInformation = (PNTQUERYSYSYTEMINFORMATION)GetProcAddress(GetModuleHandle(L"NTDLL.DLL"), "NtQuerySystemInformation");
SYSTEM_BASIC_INFORMATION sbi;
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION * spi;
DWORD returnlength;
DWORD status = pNtQuerySystemInformation(SystemBasicInformation, &sbi,
sizeof(SYSTEM_BASIC_INFORMATION), &returnlength);
spi = new SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION[sbi.NumberOfProcessors];
memset(spi, 0, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)*sbi.NumberOfProcessors);
status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, spi,
(sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)*sbi.NumberOfProcessors), &returnlength);
int numberOfCores = returnlength / sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
printf("Number of cores: %d\n", numberOfCores);
static ULARGE_INTEGER ul_sys_idle_old[32];
static ULARGE_INTEGER ul_sys_kernel_old[32];
static ULARGE_INTEGER ul_sys_user_old[32];
float usage = 0;
float usageAccum = 0;
printf("\n\nWait for %d seconds\n", nWaitSec);
Sleep(nWaitSec*1000);
status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, spi,
(sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)*numberOfCores), &returnlength);
usageAccum = 0;
for (int ii = 0; ii<numberOfCores; ii++)
{
ULARGE_INTEGER ul_sys_idle;
ULARGE_INTEGER ul_sys_kernel;
ULARGE_INTEGER ul_sys_user;
ul_sys_idle.QuadPart = spi[ii].IdleTime.QuadPart;
ul_sys_kernel.QuadPart = spi[ii].KernelTime.QuadPart;
ul_sys_user.QuadPart = spi[ii].UserTime.QuadPart;
ULONGLONG kernelTime = (ul_sys_kernel.QuadPart - ul_sys_kernel_old[ii].QuadPart);
ULONGLONG usertime = (ul_sys_user.QuadPart - ul_sys_user_old[ii].QuadPart);
ULONGLONG idletime = (ul_sys_idle.QuadPart - ul_sys_idle_old[ii].QuadPart);
ULONGLONG proctime = kernelTime + usertime - idletime;
ULONGLONG totaltime = kernelTime + usertime;
usage = (float)(proctime * 100) / totaltime;
usageAccum += usage;
printf("Core : %u: Usage : %f%%\n", ii + 1, usage);
}
usageAccum /= numberOfCores;
printf("----------------\nAverage for the last %d seconds: %f", nWaitSec, usageAccum);
delete[] spi;
return 0;
}
Despite that fact, it seems to be calculated in a wrong way because its output data almost does not change. How could I find CPU usage per core appropriately?
These three arrays are not updated in real time in your source code.So their value is always 0 in the loop.
static ULARGE_INTEGER ul_sys_idle_old[32];
static ULARGE_INTEGER ul_sys_kernel_old[32];
static ULARGE_INTEGER ul_sys_user_old[32];
What you get is the CPU usage time that has been running for a long time, and the base is very large, resulting in basically unchanged.
You can refer to Correct way to get Windows CPU utilization for multiprocessor and update your array to get the correct result.
I found this code on google that calculate of % of usage of current process on win10,but what i'm looking for is a list of % of CPU Usage of every process.
I use GetCurrentProcess() to have the handle of the current process. Is there a way to retrieve the handle of every processes?i'm working on a code that lists running process and calculate usage memory for everyone. Then i need to calculate cpu usage for everyone but i didn't find anything on google.
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;
long double percent;
GetSystemTimeAsFileTime(&ftime);
memcpy(&now, &ftime, sizeof(FILETIME));
GetProcessTimes(GetCurrentProcess(), &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;
}
I'm able to have the list of all running processes but i'm looking for to
calculate cpu usage for every process.
Suggestions?
ok, for effective coding this task need use NtQueryInformationProcess with SystemProcessInformation info class. we got here array of SYSTEM_PROCESS_INFORMATION. here we already have:
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
when in PROCESSENTRY32 no this members. toolhelp functions simply drop this member. without it we need open every process, call GetProcessTimes, etc. with NtQueryInformationProcess all become much more effective and simply. general idea - we need maintain list of processes, and periodic call NtQueryInformationProcess for add new created processes and remove died.
// for debug only 0 <= cpuUsage <= 1000
void PrintCpuUsage(ULONG cpuUsage, PCUNICODE_STRING Name)
{
ULONG p = cpuUsage / 10;
DbgPrint("%02u.%u %wZ\n", p, cpuUsage - p * 10, Name);
}
struct PROCESS_ENTRY : LIST_ENTRY, UNICODE_STRING
{
LARGE_INTEGER _CreateTime, _RunTime;
union {
LARGE_INTEGER _Delta;
ULONG _cpuUsage;
};
HANDLE _UniqueProcessId;
HANDLE _InheritedFromUniqueProcessId;
BOOLEAN _bEnumerated;
PROCESS_ENTRY()
{
RtlInitUnicodeString(this, 0);
InitializeListHead(this);
_RunTime.QuadPart = 0;
_UniqueProcessId = 0;
}
~PROCESS_ENTRY()
{
DbgPrint("--%08x(%08x) %wZ\n", _UniqueProcessId, _InheritedFromUniqueProcessId, static_cast<UNICODE_STRING*>(this));
RtlFreeUnicodeString(this);
RemoveEntryList(this);
}
NTSTATUS Init(PSYSTEM_PROCESS_INFORMATION pspi)
{
_UniqueProcessId = pspi->UniqueProcessId;
_InheritedFromUniqueProcessId = pspi->InheritedFromUniqueProcessId;
_CreateTime = pspi->CreateTime;
DbgPrint("++%08x(%08x) %wZ\n", _UniqueProcessId, _InheritedFromUniqueProcessId, &pspi->ImageName);
return RtlDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, &pspi->ImageName, this);
}
LONGLONG UpdateProcess(PSYSTEM_PROCESS_INFORMATION pspi)
{
_bEnumerated = TRUE;
pspi->KernelTime.QuadPart += pspi->UserTime.QuadPart;
_Delta.QuadPart = pspi->KernelTime.QuadPart - _RunTime.QuadPart;
_RunTime.QuadPart = pspi->KernelTime.QuadPart;
return _Delta.QuadPart;
}
void CalcCpuUsage(LONGLONG QuadPart)
{
_bEnumerated = FALSE;
_cpuUsage = (ULONG)((_Delta.QuadPart * 1000) / QuadPart );
if (_cpuUsage && _UniqueProcessId)
{
PrintCpuUsage(_cpuUsage, this);
}
}
};
struct PROCES_LIST : public LIST_ENTRY
{
LIST_ENTRY _ListHead;
PROCESS_ENTRY IdleProcess;
BOOL _bValid;
PROCES_LIST()
{
InitializeListHead(&_ListHead);
_bValid = FALSE;
}
LONGLONG UpdateOrAddNewProcess(PSYSTEM_PROCESS_INFORMATION pspi);
void RemoveDiedEntries(LONGLONG QuadPart);
void EnumPro();
~PROCES_LIST()
{
RemoveDiedEntries(0);
}
};
LONGLONG PROCES_LIST::UpdateOrAddNewProcess(PSYSTEM_PROCESS_INFORMATION pspi)
{
PROCESS_ENTRY* pe;
PLIST_ENTRY head = &_ListHead, entry = head;
HANDLE UniqueProcessId = pspi->UniqueProcessId;
while ((entry = entry->Flink) != head)
{
pe = static_cast<PROCESS_ENTRY*>(entry);
if (pe->_UniqueProcessId == UniqueProcessId && pe->_CreateTime.QuadPart == pspi->CreateTime.QuadPart)
{
return pe->UpdateProcess(pspi);
}
}
if (pe = new PROCESS_ENTRY)
{
if (0 <= pe->Init(pspi))
{
InsertTailList(head, pe);
return pe->UpdateProcess(pspi);
}
delete pe;
}
return 0;
}
void PROCES_LIST::RemoveDiedEntries(LONGLONG QuadPart)
{
PLIST_ENTRY head = &_ListHead, entry = head->Flink;
while (entry != head)
{
PROCESS_ENTRY* pe = static_cast<PROCESS_ENTRY*>(entry);
entry = entry->Flink;
if (pe->_bEnumerated)
{
pe->CalcCpuUsage(QuadPart);
}
else
{
delete pe;
}
}
}
void PROCES_LIST::EnumPro()
{
ULONG cb = 0, rcb = 0x10000;
PVOID stack = alloca(guz);// volatile UCHAR guz;
union {
PVOID buf;
PBYTE pb;
PSYSTEM_PROCESS_INFORMATION pspi;
};
NTSTATUS status;
do
{
if (cb < rcb)
{
cb = RtlPointerToOffset(buf = alloca(rcb - cb), stack);
}
if (0 <= (status = NtQuerySystemInformation(SystemProcessInformation, buf, cb, &rcb)))
{
LONGLONG QuadPart = 0;
ULONG NextEntryOffset = 0;
do
{
pb += NextEntryOffset;
if (pspi->UniqueProcessId)
{
QuadPart += UpdateOrAddNewProcess(pspi);
}
else
{
QuadPart += IdleProcess.UpdateProcess(pspi);
}
} while (NextEntryOffset = pspi->NextEntryOffset);
RemoveDiedEntries(QuadPart);
IdleProcess.CalcCpuUsage(QuadPart);
if (_bValid)
{
static UNICODE_STRING empty;
PrintCpuUsage(1000 - IdleProcess._cpuUsage, &empty);
}
else
{
_bValid = TRUE;
}
}
} while (status == STATUS_INFO_LENGTH_MISMATCH);
}
I want to use PerformanceCounter to measure how much time I need for some operation.
I don't know much about PerformanceCounter and C++ in general. I found some code here:
How to use QueryPerformanceCounter?
I'm getting weird results with this. Here is my try:
#include <Windows.h>
// ...
double PCFreq = 0.0;
__int64 CounterStart = 0;
void StartCounter()
{
LARGE_INTEGER li;
if (!QueryPerformanceFrequency(&li))
printf("QueryPerformanceFrequency failed!\n");
PCFreq = double(li.QuadPart) / 1000.0;
//printf("Performance counter resolution: %f", PCFreq);
QueryPerformanceCounter(&li);
CounterStart = li.QuadPart;
}
double GetCounter()
{
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
return double(li.QuadPart - CounterStart) / PCFreq;
}
int main(int argc, const char** argv) {
while (true) {
StartCounter();
Sleep(1000); // just a test
printf("Query frame: %d\n", GetCounter());
// ...
}
}
And here is my weird result with negative numbers:
What is wrong with my code?
You print a double as a float, use %f:
printf("Query frame: %f\n", GetCounter());
Sleep on Windows 8.1 x64 always lasts 1 more milliseconds than needed. For instance Sleep(1) lasts approximately 2 milliseconds, Sleep(2) - 3 etc. timeBeginPeriod is set to 1. On Windows 7 works fine as expected (without excess millisecond). Is this behaviour is normal / possible to fix?
#include <Windows.h>
#include <stdio.h>
#pragma comment(lib, "winmm.lib")
LARGE_INTEGER Frequency;
long long int GetCurrent()
{
LARGE_INTEGER counter;
QueryPerformanceCounter(&counter);
return (1000000 * counter.QuadPart / Frequency.QuadPart);
}
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
timeBeginPeriod(1);
QueryPerformanceFrequency(&Frequency);
const unsigned int count = 1000;
long long int buffer[count];
long long int lastTime = GetCurrent(), currentTime;
for (unsigned int i = 0; i < count; i++)
{
currentTime = GetCurrent();
buffer[i] = currentTime - lastTime;
lastTime = currentTime;
Sleep(1);
}
timeEndPeriod(1);
FILE *file = fopen("log.txt", "w");
for (unsigned int i = 0; i < count; i++)
fprintf(file, "%ld\n", buffer[i]);
fclose(file);
return EXIT_SUCCESS;
}
NtDelayExecution workaround thanks to Mehrdad.
static NTSTATUS (__stdcall *NtDelayExecution)(BOOL Alertable, PLARGE_INTEGER DelayInterval) = (NTSTATUS (__stdcall*)(BOOL, PLARGE_INTEGER)) GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtDelayExecution");
LARGE_INTEGER delay;
unsigned int milliseconds = 1;
delay.QuadPart = (milliseconds > 1) ? -10000LL * (milliseconds - 1) : -1LL;
NtDelayExecution(false, &delay);