MFEM  v3.1
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, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
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 #else
30 #error "Unknown MFEM_TIMER_TYPE"
31 #endif
32 
33 namespace mfem
34 {
35 
36 namespace internal
37 {
38 
39 class StopWatch
40 {
41 private:
42 #if (MFEM_TIMER_TYPE == 0)
43  std::clock_t user_time, start_utime;
44 #elif (MFEM_TIMER_TYPE == 1)
45  clock_t real_time, user_time, syst_time;
46  clock_t start_rtime, start_utime, start_stime;
47  long my_CLK_TCK;
48  inline void Current(clock_t *, clock_t *, clock_t *);
49 #elif (MFEM_TIMER_TYPE == 2)
50  struct timespec real_time, user_time;
51  struct timespec start_rtime, start_utime;
52  inline void GetRealTime(struct timespec &tp);
53  inline void GetUserTime(struct timespec &tp);
54 #elif (MFEM_TIMER_TYPE == 3)
55  LARGE_INTEGER frequency, real_time, start_rtime;
56 #endif
57  short Running;
58 
59 public:
60  StopWatch();
61  inline void Clear();
62  inline void Start();
63  inline void Stop();
64  inline double Resolution();
65  inline double RealTime();
66  inline double UserTime();
67  inline double SystTime();
68 };
69 
71 {
72 #if (MFEM_TIMER_TYPE == 0)
73  user_time = 0;
74 #elif (MFEM_TIMER_TYPE == 1)
75  my_CLK_TCK = sysconf(_SC_CLK_TCK);
76  real_time = user_time = syst_time = 0;
77 #elif (MFEM_TIMER_TYPE == 2)
78  real_time.tv_sec = user_time.tv_sec = 0;
79  real_time.tv_nsec = user_time.tv_nsec = 0;
80 #elif (MFEM_TIMER_TYPE == 3)
81  QueryPerformanceFrequency(&frequency);
82  real_time.QuadPart = 0;
83 #endif
84  Running = 0;
85 }
86 
87 #if (MFEM_TIMER_TYPE == 1)
88 inline void StopWatch::Current(clock_t *r, clock_t *u, clock_t *s)
89 {
90  struct tms my_tms;
91 
92  *r = times(&my_tms);
93  *u = my_tms.tms_utime;
94  *s = my_tms.tms_stime;
95 }
96 #elif (MFEM_TIMER_TYPE == 2)
97 inline void StopWatch::GetRealTime(struct timespec &tp)
98 {
99  clock_gettime(CLOCK_MONOTONIC, &tp);
100 }
101 
102 inline void StopWatch::GetUserTime(struct timespec &tp)
103 {
104  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp);
105 }
106 #endif
107 
108 inline void StopWatch::Clear()
109 {
110 #if (MFEM_TIMER_TYPE == 0)
111  user_time = 0;
112  if (Running)
113  {
114  start_utime = std::clock();
115  }
116 #elif (MFEM_TIMER_TYPE == 1)
117  real_time = user_time = syst_time = 0;
118  if (Running)
119  {
120  Current(&start_rtime, &start_utime, &start_stime);
121  }
122 #elif (MFEM_TIMER_TYPE == 2)
123  real_time.tv_sec = user_time.tv_sec = 0;
124  real_time.tv_nsec = user_time.tv_nsec = 0;
125  if (Running)
126  {
127  GetRealTime(start_rtime);
128  GetUserTime(start_utime);
129  }
130 #elif (MFEM_TIMER_TYPE == 3)
131  real_time.QuadPart = 0;
132  if (Running)
133  {
134  QueryPerformanceCounter(&start_rtime);
135  }
136 #endif
137 }
138 
139 inline void StopWatch::Start()
140 {
141  if (Running) { return; }
142 #if (MFEM_TIMER_TYPE == 0)
143  start_utime = std::clock();
144 #elif (MFEM_TIMER_TYPE == 1)
145  Current(&start_rtime, &start_utime, &start_stime);
146 #elif (MFEM_TIMER_TYPE == 2)
147  GetRealTime(start_rtime);
148  GetUserTime(start_utime);
149 #elif (MFEM_TIMER_TYPE == 3)
150  QueryPerformanceCounter(&start_rtime);
151 #endif
152  Running = 1;
153 }
154 
155 inline void StopWatch::Stop()
156 {
157  if (!Running) { return; }
158 #if (MFEM_TIMER_TYPE == 0)
159  user_time += ( std::clock() - start_utime );
160 #elif (MFEM_TIMER_TYPE == 1)
161  clock_t curr_rtime, curr_utime, curr_stime;
162  Current(&curr_rtime, &curr_utime, &curr_stime);
163  real_time += ( curr_rtime - start_rtime );
164  user_time += ( curr_utime - start_utime );
165  syst_time += ( curr_stime - start_stime );
166 #elif (MFEM_TIMER_TYPE == 2)
167  struct timespec curr_rtime, curr_utime;
168  GetRealTime(curr_rtime);
169  GetUserTime(curr_utime);
170  real_time.tv_sec += ( curr_rtime.tv_sec - start_rtime.tv_sec );
171  real_time.tv_nsec += ( curr_rtime.tv_nsec - start_rtime.tv_nsec );
172  user_time.tv_sec += ( curr_utime.tv_sec - start_utime.tv_sec );
173  user_time.tv_nsec += ( curr_utime.tv_nsec - start_utime.tv_nsec );
174 #elif (MFEM_TIMER_TYPE == 3)
175  LARGE_INTEGER curr_rtime;
176  QueryPerformanceCounter(&curr_rtime);
177  real_time.QuadPart += (curr_rtime.QuadPart - start_rtime.QuadPart);
178 #endif
179  Running = 0;
180 }
181 
182 inline double StopWatch::Resolution()
183 {
184 #if (MFEM_TIMER_TYPE == 0)
185  return 1.0 / CLOCKS_PER_SEC; // potential resolution
186 #elif (MFEM_TIMER_TYPE == 1)
187  return 1.0 / my_CLK_TCK;
188 #elif (MFEM_TIMER_TYPE == 2)
189  // return the resolution of the "real time" clock, CLOCK_MONOTONIC, which may
190  // be different from the resolution of the "user time" clock,
191  // CLOCK_PROCESS_CPUTIME_ID.
192  struct timespec res;
193  clock_getres(CLOCK_MONOTONIC, &res);
194  return res.tv_sec + 1e-9*res.tv_nsec;
195 #elif (MFEM_TIMER_TYPE == 3)
196  return 1.0 / frequency.QuadPart;
197 #endif
198 }
199 
200 inline double StopWatch::RealTime()
201 {
202 #if (MFEM_TIMER_TYPE == 0)
203  return UserTime();
204 #elif (MFEM_TIMER_TYPE == 1)
205  clock_t curr_rtime, curr_utime, curr_stime;
206  clock_t rtime = real_time;
207  if (Running)
208  {
209  Current(&curr_rtime, &curr_utime, &curr_stime);
210  rtime += (curr_rtime - start_rtime);
211  }
212  return (double)(rtime) / my_CLK_TCK;
213 #elif (MFEM_TIMER_TYPE == 2)
214  if (Running)
215  {
216  struct timespec curr_rtime;
217  GetRealTime(curr_rtime);
218  return ((real_time.tv_sec + (curr_rtime.tv_sec - start_rtime.tv_sec)) +
219  1e-9*(real_time.tv_nsec +
220  (curr_rtime.tv_nsec - start_rtime.tv_nsec)));
221  }
222  else
223  {
224  return real_time.tv_sec + 1e-9*real_time.tv_nsec;
225  }
226 #elif (MFEM_TIMER_TYPE == 3)
227  LARGE_INTEGER curr_rtime, rtime = real_time;
228  if (Running)
229  {
230  QueryPerformanceCounter(&curr_rtime);
231  rtime.QuadPart += (curr_rtime.QuadPart - start_rtime.QuadPart);
232  }
233  return (double)(rtime.QuadPart) / frequency.QuadPart;
234 #endif
235 }
236 
237 inline double StopWatch::UserTime()
238 {
239 #if (MFEM_TIMER_TYPE == 0)
240  std::clock_t utime = user_time;
241  if (Running)
242  {
243  utime += (std::clock() - start_utime);
244  }
245  return (double)(utime) / CLOCKS_PER_SEC;
246 #elif (MFEM_TIMER_TYPE == 1)
247  clock_t curr_rtime, curr_utime, curr_stime;
248  clock_t utime = user_time;
249  if (Running)
250  {
251  Current(&curr_rtime, &curr_utime, &curr_stime);
252  utime += (curr_utime - start_utime);
253  }
254  return (double)(utime) / my_CLK_TCK;
255 #elif (MFEM_TIMER_TYPE == 2)
256  if (Running)
257  {
258  struct timespec curr_utime;
259  GetUserTime(curr_utime);
260  return ((user_time.tv_sec + (curr_utime.tv_sec - start_utime.tv_sec)) +
261  1e-9*(user_time.tv_nsec +
262  (curr_utime.tv_nsec - start_utime.tv_nsec)));
263  }
264  else
265  {
266  return user_time.tv_sec + 1e-9*user_time.tv_nsec;
267  }
268 #elif (MFEM_TIMER_TYPE == 3)
269  return RealTime();
270 #endif
271 }
272 
273 inline double StopWatch::SystTime()
274 {
275 #if (MFEM_TIMER_TYPE == 1)
276  clock_t curr_rtime, curr_utime, curr_stime;
277  clock_t stime = syst_time;
278  if (Running)
279  {
280  Current(&curr_rtime, &curr_utime, &curr_stime);
281  stime += (curr_stime - start_stime);
282  }
283  return (double)(stime) / my_CLK_TCK;
284 #else
285  return 0.0;
286 #endif
287 }
288 
289 } // namespace internal
290 
291 
293 {
294  M = new internal::StopWatch;
295 }
296 
298 {
299  M->Clear();
300 }
301 
303 {
304  M->Start();
305 }
306 
308 {
309  M->Stop();
310 }
311 
313 {
314  return M->Resolution();
315 }
316 
318 {
319  return M->RealTime();
320 }
321 
323 {
324  return M->UserTime();
325 }
326 
328 {
329  return M->SystTime();
330 }
331 
333 {
334  delete M;
335 }
336 
337 
339 
340 void tic()
341 {
342  tic_toc.Clear();
343  tic_toc.Start();
344 }
345 
346 double toc()
347 {
348  return tic_toc.UserTime();
349 }
350 
351 }
StopWatch tic_toc
Definition: tic_toc.cpp:338
double RealTime()
Definition: tic_toc.cpp:317
double UserTime()
Definition: tic_toc.cpp:322
Timing object.
Definition: tic_toc.hpp:34
double Resolution()
Definition: tic_toc.cpp:312
void tic()
Start timing.
Definition: tic_toc.cpp:340
double toc()
End timing.
Definition: tic_toc.cpp:346
double SystTime()
Definition: tic_toc.cpp:327