PandA-2024.02
cpu_stats.cpp
Go to the documentation of this file.
1 /*
2  *
3  * _/_/_/ _/_/ _/ _/ _/_/_/ _/_/
4  * _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/
5  * _/_/_/ _/_/_/_/ _/ _/_/ _/ _/ _/_/_/_/
6  * _/ _/ _/ _/ _/ _/ _/ _/ _/
7  * _/ _/ _/ _/ _/ _/_/_/ _/ _/
8  *
9  * ***********************************************
10  * PandA Project
11  * URL: http://panda.dei.polimi.it
12  * Politecnico di Milano - DEIB
13  * System Architectures Group
14  * ***********************************************
15  * Copyright (C) 2004-2024 Politecnico di Milano
16  *
17  * This file is part of the PandA framework.
18  *
19  * The PandA framework is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program. If not, see <http://www.gnu.org/licenses/>.
31  *
32  */
44 #include "cpu_stats.hpp"
45 #include "string_manipulation.hpp"
46 #ifdef _WIN32
47 #include <windows.h>
48 
49 #include <psapi.h>
50 #include <winsock2.h>
51 #else
52 #include <sys/resource.h>
53 #include <sys/time.h>
54 #endif
55 #include <unistd.h>
56 #pragma GCC diagnostic ignored "-Wold-style-cast"
57 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
58 
60 {
61 #ifdef _WIN32
62  return STR("unavailable");
63 #elif defined(__APPLE__)
64  return STR("unavailable");
65 #else
66  extern int end, etext, edata;
67  long vm_init_data, vm_uninit_data, vm_sbrk_data;
68  long int temp;
69  /* Get the virtual memory sizes */
70  temp = (long)(&edata) - (long)(&etext);
71  vm_init_data = temp / 1024 + (((temp % 1024) > 512) ? 1 : 0);
72  temp = (long)(&end) - (long)(&edata);
73  vm_uninit_data = temp / 1024 + (((temp % 1024) > 512) ? 1 : 0);
74  temp = (long)sbrk(0) - (long)(&end);
75  vm_sbrk_data = temp / 1024 + (((temp % 1024) > 512) ? 1 : 0);
76  return STR((vm_init_data + vm_uninit_data + vm_sbrk_data) / 1024) + "MB";
77 #endif
78 }
79 
80 void util_print_cpu_stats(std::ostream& os)
81 {
82 #ifdef _WIN32
83  char hostname[257];
84  WSADATA wsaData;
85  FILETIME creationTime, exitTime, kernelTime, userTime;
86  double user, system;
87  MEMORYSTATUSEX statex;
88  size_t vm_limit;
89  PROCESS_MEMORY_COUNTERS pmc;
90  size_t peak_working_set;
91  long page_faults;
92 
93  /* Get the hostname */
94  WSAStartup(MAKEWORD(2, 2), &wsaData);
95  (void)gethostname(hostname, sizeof(hostname));
96  hostname[sizeof(hostname) - 1] = '\0'; /* just in case */
97  WSACleanup();
98 
99  /* Get usage stats */
100  if(GetProcessTimes(GetCurrentProcess(), &creationTime, &exitTime, &kernelTime, &userTime))
101  {
102  ULARGE_INTEGER integerSystemTime, integerUserTime;
103  integerUserTime.u.LowPart = userTime.dwLowDateTime;
104  integerUserTime.u.HighPart = userTime.dwHighDateTime;
105  user = (double)integerUserTime.QuadPart * 1e-7;
106  integerSystemTime.u.LowPart = kernelTime.dwLowDateTime;
107  integerSystemTime.u.HighPart = kernelTime.dwHighDateTime;
108  system = (double)integerSystemTime.QuadPart * 1e-7;
109  }
110  else
111  {
112  user = system = 0.0;
113  }
114  statex.dwLength = sizeof(statex);
115  if(GlobalMemoryStatusEx(&statex))
116  {
117  vm_limit = (size_t)(statex.ullTotalVirtual / 1024.0 + 0.5);
118  }
119  else
120  {
121  vm_limit = 0;
122  }
123  if(GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)))
124  {
125  peak_working_set = (size_t)(pmc.PeakWorkingSetSize / 1024.0 + 0.5);
126  page_faults = (long)pmc.PageFaultCount;
127  }
128  else
129  {
130  peak_working_set = 0;
131  page_faults = 0;
132  }
133  os << "Runtime Statistics\n";
134  os << "------------------\n";
135  os << "Machine name: " << hostname << std::endl;
136  os << "User time " << user << " seconds\n";
137  os << "System time " << system << " seconds\n\n";
138  os << "Maximum resident size = ";
139  if(peak_working_set == 0)
140  os << "unavailable\n";
141  else
142  os << peak_working_set << "\n";
143  os << "Virtual memory limit = ";
144  if(vm_limit == 0)
145  os << "unavailable\n";
146  else
147  os << vm_limit << "\n";
148  os << "Page faults = " << page_faults << "\n";
149 #elif defined(__APPLE__)
150  ; // do nothing
151 #else
152  extern int end, etext, edata;
153  struct rusage rusage
154  {
155  };
156  struct rlimit rlp
157  {
158  };
159  int text, data, stack;
160  rlim_t vm_limit, vm_soft_limit;
161  long double user, system, scale;
162  long int temp;
163  char hostname[257];
164  long vm_text, vm_init_data, vm_uninit_data, vm_sbrk_data;
165 
166  /* Get the hostname */
167  (void)gethostname(hostname, 256);
168  hostname[256] = '\0'; /* just in case */
169 
170  /* Get the virtual memory sizes */
171  temp = (long)(&etext);
172  vm_text = temp / 1024 + (((temp % 1024) > 512) ? 1 : 0);
173  temp = (long)(&edata) - (long)(&etext);
174  vm_init_data = temp / 1024 + (((temp % 1024) > 512) ? 1 : 0);
175  temp = (long)(&end) - (long)(&edata);
176  vm_uninit_data = temp / 1024 + (((temp % 1024) > 512) ? 1 : 0);
177  temp = (long)sbrk(0) - (long)(&end);
178  vm_sbrk_data = temp / 1024 + (((temp % 1024) > 512) ? 1 : 0);
179 
180  /* Get virtual memory limits */
181  (void)getrlimit(RLIMIT_DATA, &rlp);
182  vm_limit = rlp.rlim_max / 1024 + (((rlp.rlim_max % 1024) > 512) ? 1 : 0);
183  vm_soft_limit = rlp.rlim_cur / 1024 + (((rlp.rlim_cur % 1024) > 512) ? 1 : 0);
184 
185  /* Get usage stats */
186  (void)getrusage(RUSAGE_SELF, &rusage);
187  user = rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec / 1000000.L;
188  system = rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec / 1000000.L;
189  scale = (user + system) * 100.0L;
190  if(scale == 0.0L)
191  {
192  scale = 0.001L;
193  }
194 
195  os << "Runtime Statistics\n";
196  os << "------------------\n";
197  os << "Machine name: " << hostname << std::endl;
198  os << "User time " << user << " seconds\n";
199  os << "System time " << system << " seconds\n\n";
200 
201  text = (int)(rusage.ru_ixrss / scale + 0.5L);
202  data = (int)((rusage.ru_idrss) / scale + 0.5L);
203  stack = (int)((rusage.ru_isrss) / scale + 0.5L);
204  os << "Average resident text size = " << text << "K\n";
205  os << "Average resident data size = " << data << "K\n";
206  os << "Average resident stack size = " << stack << "K\n";
207  os << "Maximum resident size = " << rusage.ru_maxrss / 2 << "K\n\n";
208  os << "Virtual text size = " << vm_text << "K\n";
209  os << "Virtual data size = " << vm_init_data + vm_uninit_data + vm_sbrk_data << "K\n";
210  os << " data size initialized = " << vm_init_data << "K\n";
211  os << " data size uninitialized = " << vm_uninit_data << "K\n";
212  os << " data size sbrk = " << vm_sbrk_data << "K\n";
213  os << "Virtual memory limit = ";
214  if(rlp.rlim_cur == RLIM_INFINITY)
215  {
216  os << "unlimited";
217  }
218  else
219  {
220  os << vm_soft_limit << "K";
221  }
222  os << " (";
223  if(rlp.rlim_max == RLIM_INFINITY)
224  {
225  os << "unlimited";
226  }
227  else
228  {
229  os << vm_limit << "K";
230  }
231  os << ")\n\n";
232 
233  os << "Major page faults = " << rusage.ru_majflt << "\n";
234  os << "Minor page faults = " << rusage.ru_minflt << "\n";
235  os << "Swaps = " << rusage.ru_nswap << "\n";
236  os << "Input blocks = " << rusage.ru_inblock << "\n";
237  os << "Output blocks = " << rusage.ru_oublock << "\n";
238  os << "Context switch (voluntary) = " << rusage.ru_nvcsw << "\n";
239  os << "Context switch (involuntary) = " << rusage.ru_nivcsw << "\n";
240 #endif
241 }
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
std::string PrintVirtualDataMemoryUsage()
Definition: cpu_stats.cpp:59
#define L
Definition: spmv.h:13
Definition: tree.c:10
unsigned int size_t
Definition: test.c:1
void util_print_cpu_stats(std::ostream &os)
Definition: cpu_stats.cpp:80
Utility managing CPU statistics.

Generated on Mon Feb 12 2024 13:02:56 for PandA-2024.02 by doxygen 1.8.13