代码改变世界

C++ Measures CPU and memory consumption

2015-01-15 00:36  winemike  阅读(1167)  评论(0编辑  收藏  举报
We all know monitor, just as Windows Task Manager,can measure cpu used and memory cost. Now I record that today I studied.
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.
#
IFS=$'\n'
for line in $(</proc/$1/smaps)
do
   [[ $line =~ ^Size:\s+(\S+) ]] && ((kb += ${.sh.match[1]}))
done
print $kb
# shell end
 -------Command 2-------
ps -eo size,pid,user,command --sort -size | awk '{ hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }' | awk '{total=total + $1} END {print total}'
OK,next I  recommend some usefull advices using C++.
 Windows
 Memory
case 1:
 #include<windows.h>
#include<stdio.h>  
#include<tchar.h>
// Use to convert bytes to MB
#define DIV 1048576
// Use to convert bytes to MB
//#define DIV 1024
// Specify the width of the field in which to print the numbers.
// The asterisk in the format specifier "%*I64d" takes an integer
// argument and uses it to pad and right justify the number.
#define WIDTH 7
void _tmain()
{
  MEMORYSTATUSEX statex;
  statex.dwLength = sizeof (statex);
  GlobalMemoryStatusEx (&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(); 
}
 case 2:
Note: You may need divide  by (1024 * 1024) 
Total Virtual Memory:
 
 #include "windows.h"
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\",...)" );
 }

Note that the "xsw_usage", declared in sysctl.h, seems not documented and I suspect there there is a more portable way of accessing these values.

 Virtual Memory Currently Used by my Process
#include<mach/mach.h>
 struct task_basic_info t_info;
 mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
if (
 KERN_SUCCESS != task_info(
            mach_task_self(),
            TASK_BASIC_INFO, 
            (task_info_t)&t_info, 
            &t_info_count)
)
 { return -1; } // resident size is in t_info.resident_size; // virtual size is in t_info.virtual_size; 
 Total RAM available

#include <sys/types.h>
#include <sys/sysctl.h>
int mib[2];
int64_t physical_memory; 
mib[0] = CTL_HW; mib[1] = HW_MEMSIZE;
length = sizeof(int64_t);
sysctl(mib, 2, &physical_memory, &length, NULL, 0);
RAM Currently Used 
#include <mach/vm_statistics.h>
#include <mach/mach_types.h>
#include <mach/mach_init.h>
#include <mach/mach_host.h>
vm_size_t page_size;
mach_port_t mach_port;
mach_msg_type_number_t count;
vm_statistics_data_t vm_stats;
mach_port = mach_host_self();
count = sizeof(vm_stats) / sizeof(natural_t);
if (KERN_SUCCESS == host_page_size(mach_port, &page_size) && KERN_SUCCESS == host_statistics(mach_port, HOST_VM_INFO, (host_info_t)&vm_stats, &count))
{ myFreeMemory = (int64_t)vm_stats.free_count * (int64_t)page_size;
used_memory = ((int64_t)vm_stats.active_count + (int64_t)vm_stats.inactive_count + (int64_t)vm_stats.wire_count) * (int64_t)page_size;
 } 
RAM Currently Used by my Process 

See the "Virtual Memory Currently Used by my Process" above. The same code applies

Ios Get IP And Address
 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/sockio.h>
#include <net/if.h>
#include <errno.h>
#include <net/if_dl.h>
//#include "GetAddresses.h"
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
#define BUFFERSIZE 4000
char *if_names[MAXADDRS];
char *ip_names[MAXADDRS];
char *hw_addrs[MAXADDRS];
unsigned long ip_addrs[MAXADDRS];
static int nextAddr = 0;
void InitAddresses() {
    int i;
    for (i=0; i<MAXADDRS; ++i) {
if_names[i] = ip_names[i] = hw_addrs[i] = NULL;
ip_addrs[i] = 0;
}
}
void FreeAddresses() {
int i;
for (i=0; i<MAXADDRS; ++i) {
if (if_names[i] != 0) free(if_names[i]);
if (ip_names[i] != 0) free(ip_names[i]);
if (hw_addrs[i] != 0) free(hw_addrs[i]);
ip_addrs[i] = 0;
}
InitAddresses();
}
void GetIPAddresses() {
int i, len, flags;
char buffer[BUFFERSIZE], *ptr, lastname[IFNAMSIZ], *cptr; struct ifconf ifc;
struct ifreq *ifr, ifrcopy;
struct sockaddr_in *sin;
char temp[80];
int sockfd;
for (i=0; i<MAXADDRS; ++i) {
if_names[i] = ip_names[i] = NULL;
ip_addrs[i] = 0;
}
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
perror("socket failed");
return;
}
ifc.ifc_len = BUFFERSIZE;
ifc.ifc_buf = buffer;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
perror("ioctl error");
return;
}
lastname[0] = 0;
for (ptr = buffer; ptr < buffer + ifc.ifc_len; ) {
ifr = (struct ifreq *)ptr;
len = max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len);
ptr += sizeof(ifr->ifr_name) + len;
// for next one in buffer
if (ifr->ifr_addr.sa_family != AF_INET) {
continue; // ignore if not desired address family
}
if ((cptr = (char *)strchr(ifr->ifr_name, ':')) != NULL) {
*cptr = 0; // replace colon will null
}
if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) {
continue; /* already processed this interface */
}
memcpy(lastname, ifr->ifr_name, IFNAMSIZ);
ifrcopy = *ifr;
ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy);
flags = ifrcopy.ifr_flags;
if ((flags & IFF_UP) == 0) {
continue; // ignore if interface not up
}
if_names[nextAddr] = (char *)malloc(strlen(ifr->ifr_name)+1);
if (if_names[nextAddr] == NULL) { return; }
strcpy(if_names[nextAddr], ifr->ifr_name);
sin = (struct sockaddr_in *)&ifr->ifr_addr; strcpy(temp, inet_ntoa(sin->sin_addr));
ip_names[nextAddr] = (char *)malloc(strlen(temp)+1);
if (ip_names[nextAddr] == NULL) { return; }
strcpy(ip_names[nextAddr], temp);
ip_addrs[nextAddr] = sin->sin_addr.s_addr; ++nextAddr;
}
close(sockfd);
}
void GetHWAddresses() {
struct ifconf ifc;
struct ifreq *ifr;
int i, sockfd;
char buffer[BUFFERSIZE], *cp, *cplim; char temp[80];
for (i=0; i<MAXADDRS; ++i) { hw_addrs[i] = NULL; } s
ockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
perror("socket failed");
return;
}
ifc.ifc_len = BUFFERSIZE;
ifc.ifc_buf = buffer;
if (ioctl(sockfd, SIOCGIFCONF, (char *)&ifc) < 0) {
perror("ioctl error");
close(sockfd);
return;
}
ifr = ifc.ifc_req;
cplim = buffer + ifc.ifc_len;
for (cp=buffer; cp < cplim; ) {
ifr = (struct ifreq *)cp;
if (ifr->ifr_addr.sa_family == AF_LINK) {
struct sockaddr_dl *sdl = (struct sockaddr_dl *)&ifr->ifr_addr;
int a,b,c,d,e,f; int i;
strcpy(temp, (char *)ether_ntoa(LLADDR(sdl)));
sscanf(temp, "%x:%x:%x:%x:%x:%x", &a, &b, &c, &d, &e, &f);
sprintf(temp, "%02X:%02X:%02X:%02X:%02X:%02X",a,b,c,d,e,f);
for (i=0; i<MAXADDRS; ++i) {
if ((if_names[i] != NULL) && (strcmp(ifr->ifr_name, if_names[i]) == 0)) {
if (hw_addrs[i] == NULL) {
hw_addrs[i] = (char *)malloc(strlen(temp)+1);
strcpy(hw_addrs[i], temp);
break;
}
}
}
}
cp += sizeof(ifr->ifr_name) + max(sizeof(ifr->ifr_addr), ifr->ifr_addr.sa_len);
}
close(sockfd);
}
Use case:
InitAddresses();
GetIPAddresses();
GetHWAddresses();