C++ Measures CPU and memory consumption
2015-01-15 00:36 winemike 阅读(1167) 评论(0) 编辑 收藏 举报Firstly,shell goes first.
-------Command 1-------
#shell begin here
#!/bin/ksh
#
# Returns total memory used by process $1 in kb.
#
# See /proc/NNNN/smaps if you want to do something
# more interesting.
#
do
[[ $line =~ ^Size:\s+(\S+) ]] && ((kb += ${.sh.match[1]}))
done
# shell end
-------Command 2-------
OK,next I recommend some usefull advices using C++.
Windows
Memory
case 1:
#include<windows.h>
#include<stdio.h>
#include<tchar.h>
#define DIV 1048576
//#define DIV 1024
// The asterisk in the format specifier "%*I64d" takes an integer
// argument and uses it to pad and right justify the number.
{
MEMORYSTATUSEX statex;
_tprintf (TEXT("There is %*ld percent of memory in use.\n"),WIDTH, statex.dwMemoryLoad);
_tprintf (TEXT("There are %*I64d total Mbytes of physical memory.\n"),WIDTH,statex.ullTotalPhys/DIV);
_tprintf (TEXT("There are %*I64d free Mbytes of physical memory.\n"),WIDTH, statex.ullAvailPhys/DIV);
_tprintf (TEXT("There are %*I64d total Mbytes of paging file.\n"),WIDTH, statex.ullTotalPageFile/DIV);
_tprintf (TEXT("There are %*I64d free Mbytes of paging file.\n"),WIDTH, statex.ullAvailPageFile/DIV);
_tprintf (TEXT("There are %*I64d total Mbytes of virtual memory.\n"),WIDTH, statex.ullTotalVirtual/DIV);
_tprintf (TEXT("There are %*I64d free Mbytes of virtual memory.\n"),WIDTH, statex.ullAvailVirtual/DIV);
_tprintf (TEXT("There are %*I64d free Mbytes of extended memory.\n"),WIDTH, statex.ullAvailExtendedVirtual/DIV);
getchar();
}
Note: You may need divide by (1024 * 1024)
MEMORYSTATUSEX memInfo;
memInfo.dwLength = sizeof(MEMORYSTATUSEX);
GlobalMemoryStatusEx(&memInfo);
DWORDLONG totalVirtualMem = memInfo.ullTotalPageFile;
//Note: The name "TotalPageFile" is a bit misleading here. In reality this parameter gives the "Virtual Memory Size", which is size of swap file plus installed RAM.
Virtual Memory currently used:
DWORDLONG virtualMemUsed = memInfo.ullTotalPageFile - memInfo.ullAvailPageFile;
Virtual Memory currently used by current process :
#include "windows.h" #include "psapi.h"
PROCESS_MEMORY_COUNTERS_EX pmc;
GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc));
SIZE_T virtualMemUsedByMe = pmc.PrivateUsage;
Total Physical Memory (RAM):
DWORDLONG totalPhysMem = memInfo.ullTotalPhys;
Physical Memory currently used:
DWORDLONG physMemUsed = memInfo.ullTotalPhys - memInfo.ullAvailPhys;
Physical Memory currently used by current process:
SIZE_T physMemUsedByMe = pmc.WorkingSetSize;
CPU
CPU currently used:
#include "TCHAR.h" #include "pdh.h"
static PDH_HQUERY cpuQuery; static PDH_HCOUNTER cpuTotal;
void init(){
PdhOpenQuery(NULL, NULL, &cpuQuery);
PdhAddCounter(cpuQuery, L"\\Processor(_Total)\\% Processor Time", NULL, &cpuTotal); PdhCollectQueryData(cpuQuery);
}
double getCurrentValue(){
PDH_FMT_COUNTERVALUE counterVal;
PdhCollectQueryData(cpuQuery);
PdhGetFormattedCounterValue(cpuTotal, PDH_FMT_DOUBLE, NULL, &counterVal); return counterVal.doubleValue;
}
CPU currently used by current process:
#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;
}
Windows Another Get CPU Measures
#include <windows.h>
#include <stdio.h>
// Prototype(s)...
CHAR cpuusage(void);
//-----------------------------------------------------
typedef BOOL ( __stdcall * pfnGetSystemTimes)( LPFILETIME lpIdleTime, LPFILETIME lpKernelTime, LPFILETIME lpUserTime ); static pfnGetSystemTimes s_pfnGetSystemTimes = NULL;
static HMODULE s_hKernel = NULL;
//-----------------------------------------------------
void GetSystemTimesAddress() {
if( s_hKernel == NULL ) {
s_hKernel = LoadLibrary( L"Kernel32.dll" );
if( s_hKernel != NULL ) {
s_pfnGetSystemTimes = (pfnGetSystemTimes)GetProcAddress( s_hKernel, "GetSystemTimes" );
if( s_pfnGetSystemTimes == NULL ) {
FreeLibrary( s_hKernel );
s_hKernel = NULL;
}
}
}
}
// cpuusage(void) // ============== // Return a CHAR value in the range 0 - 100 representing actual CPU usage in percent.
CHAR cpuusage() {
FILETIME ft_sys_idle;
FILETIME ft_sys_kernel;
FILETIME ft_sys_user;
ULARGE_INTEGER ul_sys_idle;
ULARGE_INTEGER ul_sys_kernel;
ULARGE_INTEGER ul_sys_user;
static ULARGE_INTEGER ul_sys_idle_old;
static ULARGE_INTEGER ul_sys_kernel_old;
static ULARGE_INTEGER ul_sys_user_old; CHAR usage = 0;
// we cannot directly use GetSystemTimes on C language
/* add this line :: pfnGetSystemTimes */
s_pfnGetSystemTimes(
&ft_sys_idle, /* System idle time */
&ft_sys_kernel, /* system kernel time */
&ft_sys_user); /* System user time */
CopyMemory(&ul_sys_idle , &ft_sys_idle , sizeof(FILETIME)); // Could been optimized away...
CopyMemory(&ul_sys_kernel, &ft_sys_kernel, sizeof(FILETIME)); // Could been optimized away...
CopyMemory(&ul_sys_user , &ft_sys_user , sizeof(FILETIME)); // Could been optimized away...
usage = (
(
(
(
(ul_sys_kernel.QuadPart - ul_sys_kernel_old.QuadPart)+
(ul_sys_user.QuadPart - ul_sys_user_old.QuadPart) ) -
(ul_sys_idle.QuadPart-ul_sys_idle_old.QuadPart) ) * (100) ) / ( (ul_sys_kernel.QuadPart - ul_sys_kernel_old.QuadPart)+ (ul_sys_user.QuadPart - ul_sys_user_old.QuadPart)
)
);
ul_sys_idle_old.QuadPart = ul_sys_idle.QuadPart;
ul_sys_user_old.QuadPart = ul_sys_user.QuadPart;
ul_sys_kernel_old.QuadPart = ul_sys_kernel.QuadPart; return usage;
}
// Entry point //------------------------------------------------------------------------------------------------------------------
int main(void) {
int n;
GetSystemTimesAddress();
for(n=0;n<20;n++) {
printf("CPU Usage: %3d%%\r",cpuusage());
Sleep(2000);
}
printf("\n");
return 0;
}
LINUX
Memory
Total Virtual Memory:
#include "sys/types.h"
#include "sys/sysinfo.h"
struct sysinfo memInfo;
sysinfo (&memInfo);
long long totalVirtualMem = memInfo.totalram;
//Add other values in next statement to avoid int overflow on right hand side...
totalVirtualMem += memInfo.totalswap;
totalVirtualMem *= memInfo.mem_unit;Virtual Memory currently used:
long long virtualMemUsed = memInfo.totalram - memInfo.freeram;
//Add other values in next statement to avoid int overflow on right hand side...
virtualMemUsed += memInfo.totalswap - memInfo.freeswap;
virtualMemUsed *= memInfo.mem_unit;Virtual Memory currently used by current process:
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
int parseLine(char* line){
int i = strlen(line);
while (*line < '0' || *line > '9') line++;
line[i-3] = '\0';
i = atoi(line); return i;
}
int getValue(){
//Note: this value is in KB!
FILE* file = fopen("/proc/self/status", "r");
int result = -1; char line[128];
while (fgets(line, 128, file) != NULL){
if (strncmp(line, "VmSize:", 7) == 0){
result = parseLine(line);
break;
}
}
fclose(file);
return result;
}
Total Physical Memory (RAM):
long long totalPhysMem = memInfo.totalram;
//Multiply in next statement to avoid int overflow on right hand side...
totalPhysMem *= memInfo.mem_unit;
Physical Memory currently used:
long long physMemUsed = memInfo.totalram - memInfo.freeram;
//Multiply in next statement to avoid int overflow on right hand side...
physMemUsed *= memInfo.mem_unit;Physical Memory currently used by current process:
int getValue(){ //Note: this value is in KB!
FILE* file = fopen("/proc/self/status", "r");
int result = -1; char line[128];
while (fgets(line, 128, file) != NULL){
if (strncmp(line, "VmRSS:", 6) == 0){
result = parseLine(line);
break;
}
}
fclose(file);
return result;
}
CPU CPU currently used:
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
static unsigned long long lastTotalUser, lastTotalUserLow, lastTotalSys, lastTotalIdle;
void init(){
FILE* file = fopen("/proc/stat", "r");
fscanf(file, "cpu %Ld %Ld %Ld %Ld", &lastTotalUser, &lastTotalUserLow, &lastTotalSys, &lastTotalIdle); fclose(file);
}
double getCurrentValue(){
double percent;
FILE* file;
unsigned long long totalUser, totalUserLow, totalSys, totalIdle, total;
file = fopen("/proc/stat", "r");
fscanf(file, "cpu %Ld %Ld %Ld %Ld", &totalUser, &totalUserLow, &totalSys, &totalIdle);
fclose(file);
if (totalUser < lastTotalUser || totalUserLow < lastTotalUserLow || totalSys < lastTotalSys || totalIdle < lastTotalIdle){
//Overflow detection. Just skip this value.
percent = -1.0;
} else{
total = (totalUser - lastTotalUser) + (totalUserLow - lastTotalUserLow) + (totalSys - lastTotalSys); percent = total;
total += (totalIdle - lastTotalIdle);
percent /= total;
percent *= 100;
}
lastTotalUser = totalUser;
lastTotalUserLow = totalUserLow;
lastTotalSys = totalSys;
lastTotalIdle = totalIdle;
return percent;
}CPU currently used by current process:
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "sys/times.h"
#include "sys/vtimes.h"
static clock_t lastCPU, lastSysCPU, lastUserCPU; static int numProcessors;
void init(){
FILE* file;
struct tms timeSample;
char line[128];
lastCPU = times(&timeSample);
lastSysCPU = timeSample.tms_stime;
lastUserCPU = timeSample.tms_utime;
file = fopen("/proc/cpuinfo", "r");
numProcessors = 0;
while(fgets(line, 128, file) != NULL){
if (strncmp(line, "processor", 9) == 0) numProcessors++;
}
fclose(file);
}
double getCurrentValue(){
struct tms timeSample;
clock_t now;
double percent;
now = times(&timeSample);
if (now <= lastCPU || timeSample.tms_stime < lastSysCPU || timeSample.tms_utime < lastUserCPU){ //Overflow detection. Just skip this value.
percent = -1.0;
} else{
percent = (timeSample.tms_stime - lastSysCPU) + (timeSample.tms_utime - lastUserCPU);
percent /= (now - lastCPU);
percent /= numProcessors;
percent *= 100;
}
lastCPU = now;
lastSysCPU = timeSample.tms_stime;
lastUserCPU = timeSample.tms_utime;
return percent;
}
MAC
Memory
Total Virtual Memory
Note: Unlike most Unix-based operating systems, Mac OS X does not use a preallocated swap partition for virtual memory. Instead, it uses all of the available space on the machine’s boot partition.
struct statfs stats;
if (0 == statfs("/", &stats)) { myFreeSwap = (uint64_t)stats.f_bsize * stats.f_bfree;
}
Total Virtual Currently Used
Calling systcl with the "vm.swapusage" key provides interesting information about swap usage:
sysctl -n vm.swapusage vm.swapusage: total = 3072.00M used = 2511.78M free = 560.22M (encrypted)
Not that the total swap usage displayed here can change if more swap is needed as explained in the section above. So the total is actually the current swap total. In C++, this data can be queried this way:
xsw_usage vmusage = {0};
size_t size = sizeof(vmusage); i
f( sysctlbyname("vm.swapusage", &vmusage, &size, NULL, 0)!=0 ) {
perror( "unable to get swap usage by calling sysctlbyname(\"vm.swapusage\",...)" );
}
size_t size = sizeof(vmusage); i
f( sysctlbyname("vm.swapusage", &vmusage, &size, NULL, 0)!=0 ) {
perror( "unable to get swap usage by calling sysctlbyname(\"vm.swapusage\",...)" );
}