MFEM  v4.2.0
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
tic_toc.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-806117.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability visit https://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #include "tic_toc.hpp"
13 
14 #if (MFEM_TIMER_TYPE == 0)
15 #include <ctime>
16 #elif (MFEM_TIMER_TYPE == 1)
17 #include <sys/times.h>
18 #include <climits>
19 #include <unistd.h>
20 #elif (MFEM_TIMER_TYPE == 2)
21 #include <time.h>
22 #if (!defined(CLOCK_MONOTONIC) || !defined(CLOCK_PROCESS_CPUTIME_ID))
23 #error "CLOCK_MONOTONIC and CLOCK_PROCESS_CPUTIME_ID not defined in <time.h>"
24 #endif
25 #elif (MFEM_TIMER_TYPE == 3)
26 #define NOMINMAX
27 #include <windows.h>
28 #undef NOMINMAX
29 #elif (MFEM_TIMER_TYPE == 4)
30 #include <ctime>
31 #include <mach/mach_time.h>
32 #elif (MFEM_TIMER_TYPE == 5)
33 #include <sys/time.h> // gettimeofday
34 #elif (MFEM_TIMER_TYPE == 6)
35 #include <mpi.h> // MPI_Wtime()
36 #else
37 #error "Unknown MFEM_TIMER_TYPE"
38 #endif
39 
40 namespace mfem
41 {
42 
43 namespace internal
44 {
45 
46 class StopWatch
47 {
48 private:
49 #if (MFEM_TIMER_TYPE == 0)
50  std::clock_t user_time, start_utime;
51 #elif (MFEM_TIMER_TYPE == 1)
52  clock_t real_time, user_time, syst_time;
53  clock_t start_rtime, start_utime, start_stime;
54  long my_CLK_TCK;
55  inline void Current(clock_t *, clock_t *, clock_t *);
56 #elif (MFEM_TIMER_TYPE == 2)
57  struct timespec real_time, user_time;
58  struct timespec start_rtime, start_utime;
59  inline void GetRealTime(struct timespec &tp);
60  inline void GetUserTime(struct timespec &tp);
61 #elif (MFEM_TIMER_TYPE == 3)
62  LARGE_INTEGER frequency, real_time, start_rtime;
63 #elif (MFEM_TIMER_TYPE == 4)
64  std::clock_t user_time, start_utime;
65  mach_timebase_info_data_t ratio;
66  uint64_t real_time, start_rtime;
67 #elif (MFEM_TIMER_TYPE == 5)
68  struct timeval real_time, start_rtime;
69 #elif (MFEM_TIMER_TYPE == 6)
70  double real_time, start_rtime;
71 #endif
72  short Running;
73 
74 public:
75  StopWatch();
76  inline void Clear();
77  inline void Start();
78  inline void Stop();
79  inline double Resolution();
80  inline double RealTime();
81  inline double UserTime();
82  inline double SystTime();
83 };
84 
86 {
87 #if (MFEM_TIMER_TYPE == 0)
88  user_time = 0;
89 #elif (MFEM_TIMER_TYPE == 1)
90  my_CLK_TCK = sysconf(_SC_CLK_TCK);
91  real_time = user_time = syst_time = 0;
92 #elif (MFEM_TIMER_TYPE == 2)
93  real_time.tv_sec = user_time.tv_sec = 0;
94  real_time.tv_nsec = user_time.tv_nsec = 0;
95 #elif (MFEM_TIMER_TYPE == 3)
96  QueryPerformanceFrequency(&frequency);
97  real_time.QuadPart = 0;
98 #elif (MFEM_TIMER_TYPE == 4)
99  user_time = 0;
100  real_time = 0;
101  mach_timebase_info(&ratio);
102 #elif (MFEM_TIMER_TYPE == 5)
103  real_time.tv_sec = 0;
104  real_time.tv_usec = 0;
105 #elif (MFEM_TIMER_TYPE == 6)
106  real_time = 0.0;
107 #endif
108  Running = 0;
109 }
110 
111 #if (MFEM_TIMER_TYPE == 1)
112 inline void StopWatch::Current(clock_t *r, clock_t *u, clock_t *s)
113 {
114  struct tms my_tms;
115 
116  *r = times(&my_tms);
117  *u = my_tms.tms_utime;
118  *s = my_tms.tms_stime;
119 }
120 #elif (MFEM_TIMER_TYPE == 2)
121 inline void StopWatch::GetRealTime(struct timespec &tp)
122 {
123  clock_gettime(CLOCK_MONOTONIC, &tp);
124 }
125 
126 inline void StopWatch::GetUserTime(struct timespec &tp)
127 {
128  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp);
129 }
130 #endif
131 
132 inline void StopWatch::Clear()
133 {
134 #if (MFEM_TIMER_TYPE == 0)
135  user_time = 0;
136  if (Running)
137  {
138  start_utime = std::clock();
139  }
140 #elif (MFEM_TIMER_TYPE == 1)
141  real_time = user_time = syst_time = 0;
142  if (Running)
143  {
144  Current(&start_rtime, &start_utime, &start_stime);
145  }
146 #elif (MFEM_TIMER_TYPE == 2)
147  real_time.tv_sec = user_time.tv_sec = 0;
148  real_time.tv_nsec = user_time.tv_nsec = 0;
149  if (Running)
150  {
151  GetRealTime(start_rtime);
152  GetUserTime(start_utime);
153  }
154 #elif (MFEM_TIMER_TYPE == 3)
155  real_time.QuadPart = 0;
156  if (Running)
157  {
158  QueryPerformanceCounter(&start_rtime);
159  }
160 #elif (MFEM_TIMER_TYPE == 4)
161  user_time = 0;
162  real_time = 0;
163  if (Running)
164  {
165  start_utime = std::clock();
166  start_rtime = mach_absolute_time();
167  }
168 #elif (MFEM_TIMER_TYPE == 5)
169  real_time.tv_sec = 0;
170  real_time.tv_usec = 0;
171  if (Running)
172  {
173  gettimeofday(&start_rtime, NULL);
174  }
175 #elif (MFEM_TIMER_TYPE == 6)
176  real_time = 0.0;
177  if (Running)
178  {
179  start_rtime = MPI_Wtime();
180  }
181 #endif
182 }
183 
184 inline void StopWatch::Start()
185 {
186  if (Running) { return; }
187 #if (MFEM_TIMER_TYPE == 0)
188  start_utime = std::clock();
189 #elif (MFEM_TIMER_TYPE == 1)
190  Current(&start_rtime, &start_utime, &start_stime);
191 #elif (MFEM_TIMER_TYPE == 2)
192  GetRealTime(start_rtime);
193  GetUserTime(start_utime);
194 #elif (MFEM_TIMER_TYPE == 3)
195  QueryPerformanceCounter(&start_rtime);
196 #elif (MFEM_TIMER_TYPE == 4)
197  start_utime = std::clock();
198  start_rtime = mach_absolute_time();
199 #elif (MFEM_TIMER_TYPE == 5)
200  gettimeofday(&start_rtime, NULL);
201 #elif (MFEM_TIMER_TYPE == 6)
202  start_rtime = MPI_Wtime();
203 #endif
204  Running = 1;
205 }
206 
207 inline void StopWatch::Stop()
208 {
209  if (!Running) { return; }
210 #if (MFEM_TIMER_TYPE == 0)
211  user_time += ( std::clock() - start_utime );
212 #elif (MFEM_TIMER_TYPE == 1)
213  clock_t curr_rtime, curr_utime, curr_stime;
214  Current(&curr_rtime, &curr_utime, &curr_stime);
215  real_time += ( curr_rtime - start_rtime );
216  user_time += ( curr_utime - start_utime );
217  syst_time += ( curr_stime - start_stime );
218 #elif (MFEM_TIMER_TYPE == 2)
219  struct timespec curr_rtime, curr_utime;
220  GetRealTime(curr_rtime);
221  GetUserTime(curr_utime);
222  real_time.tv_sec += ( curr_rtime.tv_sec - start_rtime.tv_sec );
223  real_time.tv_nsec += ( curr_rtime.tv_nsec - start_rtime.tv_nsec );
224  user_time.tv_sec += ( curr_utime.tv_sec - start_utime.tv_sec );
225  user_time.tv_nsec += ( curr_utime.tv_nsec - start_utime.tv_nsec );
226 #elif (MFEM_TIMER_TYPE == 3)
227  LARGE_INTEGER curr_rtime;
228  QueryPerformanceCounter(&curr_rtime);
229  real_time.QuadPart += (curr_rtime.QuadPart - start_rtime.QuadPart);
230 #elif (MFEM_TIMER_TYPE == 4)
231  user_time += ( std::clock() - start_utime );
232  real_time += (mach_absolute_time() - start_rtime);
233 #elif (MFEM_TIMER_TYPE == 5)
234  struct timeval curr_rtime;
235  gettimeofday(&curr_rtime, NULL);
236  real_time.tv_sec += ( curr_rtime.tv_sec - start_rtime.tv_sec );
237  real_time.tv_usec += ( curr_rtime.tv_usec - start_rtime.tv_usec );
238 #elif (MFEM_TIMER_TYPE == 6)
239  real_time += (MPI_Wtime() - start_rtime);
240 #endif
241  Running = 0;
242 }
243 
244 inline double StopWatch::Resolution()
245 {
246 #if (MFEM_TIMER_TYPE == 0)
247  return 1.0 / CLOCKS_PER_SEC; // potential resolution
248 #elif (MFEM_TIMER_TYPE == 1)
249  return 1.0 / my_CLK_TCK;
250 #elif (MFEM_TIMER_TYPE == 2)
251  // return the resolution of the "real time" clock, CLOCK_MONOTONIC, which may
252  // be different from the resolution of the "user time" clock,
253  // CLOCK_PROCESS_CPUTIME_ID.
254  struct timespec res;
255  clock_getres(CLOCK_MONOTONIC, &res);
256  return res.tv_sec + 1e-9*res.tv_nsec;
257 #elif (MFEM_TIMER_TYPE == 3)
258  return 1.0 / frequency.QuadPart;
259 #elif (MFEM_TIMER_TYPE == 4)
260  return 1.0 / CLOCKS_PER_SEC; // potential resolution
261  // return 1e-9; // not real resolution
262 #elif (MFEM_TIMER_TYPE == 5)
263  return 1e-6; // not real resolution
264 #elif (MFEM_TIMER_TYPE == 6)
265  return MPI_Wtick();
266 #endif
267 }
268 
269 inline double StopWatch::RealTime()
270 {
271 #if (MFEM_TIMER_TYPE == 0)
272  return UserTime();
273 #elif (MFEM_TIMER_TYPE == 1)
274  clock_t curr_rtime, curr_utime, curr_stime;
275  clock_t rtime = real_time;
276  if (Running)
277  {
278  Current(&curr_rtime, &curr_utime, &curr_stime);
279  rtime += (curr_rtime - start_rtime);
280  }
281  return (double)(rtime) / my_CLK_TCK;
282 #elif (MFEM_TIMER_TYPE == 2)
283  if (Running)
284  {
285  struct timespec curr_rtime;
286  GetRealTime(curr_rtime);
287  return ((real_time.tv_sec + (curr_rtime.tv_sec - start_rtime.tv_sec)) +
288  1e-9*(real_time.tv_nsec +
289  (curr_rtime.tv_nsec - start_rtime.tv_nsec)));
290  }
291  else
292  {
293  return real_time.tv_sec + 1e-9*real_time.tv_nsec;
294  }
295 #elif (MFEM_TIMER_TYPE == 3)
296  LARGE_INTEGER curr_rtime, rtime = real_time;
297  if (Running)
298  {
299  QueryPerformanceCounter(&curr_rtime);
300  rtime.QuadPart += (curr_rtime.QuadPart - start_rtime.QuadPart);
301  }
302  return (double)(rtime.QuadPart) / frequency.QuadPart;
303 #elif (MFEM_TIMER_TYPE == 4)
304  uint64_t rtime = real_time;
305  if (Running)
306  {
307  rtime += (mach_absolute_time() - start_rtime);
308  }
309  return 1e-9*rtime*ratio.numer/ratio.denom;
310 #elif (MFEM_TIMER_TYPE == 5)
311  if (Running)
312  {
313  struct timeval curr_rtime;
314  gettimeofday(&curr_rtime, NULL);
315  real_time.tv_sec += ( curr_rtime.tv_sec - start_rtime.tv_sec );
316  real_time.tv_usec += ( curr_rtime.tv_usec - start_rtime.tv_usec );
317  return ((real_time.tv_sec + (curr_rtime.tv_sec - start_rtime.tv_sec)) +
318  1e-6*(real_time.tv_usec +
319  (curr_rtime.tv_usec - start_rtime.tv_usec)));
320  }
321  else
322  {
323  return real_time.tv_sec + 1e-6*real_time.tv_usec;
324  }
325 #elif (MFEM_TIMER_TYPE == 6)
326  double rtime = real_time;
327  if (Running)
328  {
329  rtime += (MPI_Wtime() - start_rtime);
330  }
331  return rtime;
332 #endif
333 }
334 
335 inline double StopWatch::UserTime()
336 {
337 #if (MFEM_TIMER_TYPE == 0)
338  std::clock_t utime = user_time;
339  if (Running)
340  {
341  utime += (std::clock() - start_utime);
342  }
343  return (double)(utime) / CLOCKS_PER_SEC;
344 #elif (MFEM_TIMER_TYPE == 1)
345  clock_t curr_rtime, curr_utime, curr_stime;
346  clock_t utime = user_time;
347  if (Running)
348  {
349  Current(&curr_rtime, &curr_utime, &curr_stime);
350  utime += (curr_utime - start_utime);
351  }
352  return (double)(utime) / my_CLK_TCK;
353 #elif (MFEM_TIMER_TYPE == 2)
354  if (Running)
355  {
356  struct timespec curr_utime;
357  GetUserTime(curr_utime);
358  return ((user_time.tv_sec + (curr_utime.tv_sec - start_utime.tv_sec)) +
359  1e-9*(user_time.tv_nsec +
360  (curr_utime.tv_nsec - start_utime.tv_nsec)));
361  }
362  else
363  {
364  return user_time.tv_sec + 1e-9*user_time.tv_nsec;
365  }
366 #elif (MFEM_TIMER_TYPE == 3)
367  return RealTime();
368 #elif (MFEM_TIMER_TYPE == 4)
369  std::clock_t utime = user_time;
370  if (Running)
371  {
372  utime += (std::clock() - start_utime);
373  }
374  return (double)(utime) / CLOCKS_PER_SEC;
375 #elif (MFEM_TIMER_TYPE == 5)
376  return RealTime();
377 #elif (MFEM_TIMER_TYPE == 6)
378  return RealTime();
379 #endif
380 }
381 
382 inline double StopWatch::SystTime()
383 {
384 #if (MFEM_TIMER_TYPE == 1)
385  clock_t curr_rtime, curr_utime, curr_stime;
386  clock_t stime = syst_time;
387  if (Running)
388  {
389  Current(&curr_rtime, &curr_utime, &curr_stime);
390  stime += (curr_stime - start_stime);
391  }
392  return (double)(stime) / my_CLK_TCK;
393 #else
394  return 0.0;
395 #endif
396 }
397 
398 } // namespace internal
399 
400 
402 {
403  M = new internal::StopWatch;
404 }
405 
407 {
408  M->Clear();
409 }
410 
412 {
413  M->Start();
414 }
415 
417 {
418  M->Stop();
419 }
420 
422 {
423  return M->Resolution();
424 }
425 
427 {
428  return M->RealTime();
429 }
430 
432 {
433  return M->UserTime();
434 }
435 
437 {
438  return M->SystTime();
439 }
440 
442 {
443  delete M;
444 }
445 
446 
448 
449 void tic()
450 {
451  tic_toc.Clear();
452  tic_toc.Start();
453 }
454 
455 double toc()
456 {
457  return tic_toc.UserTime();
458 }
459 
460 }
StopWatch tic_toc
Definition: tic_toc.cpp:447
double RealTime()
Definition: tic_toc.cpp:426
void Stop()
Stop the stopwatch.
Definition: tic_toc.cpp:416
double UserTime()
Definition: tic_toc.cpp:431
Timing object.
Definition: tic_toc.hpp:34
double Resolution()
Return the time resolution available to the stopwatch.
Definition: tic_toc.cpp:421
void Start()
Clear the elapsed time and start the stopwatch.
Definition: tic_toc.cpp:411
void tic()
Start the tic_toc timer.
Definition: tic_toc.cpp:449
double toc()
End timing and return the time from tic() to toc() in seconds.
Definition: tic_toc.cpp:455
void Clear()
Clear the elapsed time on the stopwatch and restart it if it&#39;s running.
Definition: tic_toc.cpp:406
double SystTime()
Definition: tic_toc.cpp:436