MFEM  v3.0
 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.googlecode.com.
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  start_utime = std::clock();
114 #elif (MFEM_TIMER_TYPE == 1)
115  real_time = user_time = syst_time = 0;
116  if (Running)
117  Current(&start_rtime, &start_utime, &start_stime);
118 #elif (MFEM_TIMER_TYPE == 2)
119  real_time.tv_sec = user_time.tv_sec = 0;
120  real_time.tv_nsec = user_time.tv_nsec = 0;
121  if (Running)
122  {
123  GetRealTime(start_rtime);
124  GetUserTime(start_utime);
125  }
126 #elif (MFEM_TIMER_TYPE == 3)
127  real_time.QuadPart = 0;
128  if (Running)
129  QueryPerformanceCounter(&start_rtime);
130 #endif
131 }
132 
133 inline void StopWatch::Start()
134 {
135  if (Running) return;
136 #if (MFEM_TIMER_TYPE == 0)
137  start_utime = std::clock();
138 #elif (MFEM_TIMER_TYPE == 1)
139  Current(&start_rtime, &start_utime, &start_stime);
140 #elif (MFEM_TIMER_TYPE == 2)
141  GetRealTime(start_rtime);
142  GetUserTime(start_utime);
143 #elif (MFEM_TIMER_TYPE == 3)
144  QueryPerformanceCounter(&start_rtime);
145 #endif
146  Running = 1;
147 }
148 
149 inline void StopWatch::Stop()
150 {
151  if (!Running) return;
152 #if (MFEM_TIMER_TYPE == 0)
153  user_time += ( std::clock() - start_utime );
154 #elif (MFEM_TIMER_TYPE == 1)
155  clock_t curr_rtime, curr_utime, curr_stime;
156  Current(&curr_rtime, &curr_utime, &curr_stime);
157  real_time += ( curr_rtime - start_rtime );
158  user_time += ( curr_utime - start_utime );
159  syst_time += ( curr_stime - start_stime );
160 #elif (MFEM_TIMER_TYPE == 2)
161  struct timespec curr_rtime, curr_utime;
162  GetRealTime(curr_rtime);
163  GetUserTime(curr_utime);
164  real_time.tv_sec += ( curr_rtime.tv_sec - start_rtime.tv_sec );
165  real_time.tv_nsec += ( curr_rtime.tv_nsec - start_rtime.tv_nsec );
166  user_time.tv_sec += ( curr_utime.tv_sec - start_utime.tv_sec );
167  user_time.tv_nsec += ( curr_utime.tv_nsec - start_utime.tv_nsec );
168 #elif (MFEM_TIMER_TYPE == 3)
169  LARGE_INTEGER curr_rtime;
170  QueryPerformanceCounter(&curr_rtime);
171  real_time.QuadPart += (curr_rtime.QuadPart - start_rtime.QuadPart);
172 #endif
173  Running = 0;
174 }
175 
176 inline double StopWatch::Resolution()
177 {
178 #if (MFEM_TIMER_TYPE == 0)
179  return 1.0 / CLOCKS_PER_SEC; // potential resolution
180 #elif (MFEM_TIMER_TYPE == 1)
181  return 1.0 / my_CLK_TCK;
182 #elif (MFEM_TIMER_TYPE == 2)
183  // return the resolution of the "real time" clock, CLOCK_MONOTONIC, which may
184  // be different from the resolution of the "user time" clock,
185  // CLOCK_PROCESS_CPUTIME_ID.
186  struct timespec res;
187  clock_getres(CLOCK_MONOTONIC, &res);
188  return res.tv_sec + 1e-9*res.tv_nsec;
189 #elif (MFEM_TIMER_TYPE == 3)
190  return 1.0 / frequency.QuadPart;
191 #endif
192 }
193 
194 inline double StopWatch::RealTime()
195 {
196 #if (MFEM_TIMER_TYPE == 0)
197  return UserTime();
198 #elif (MFEM_TIMER_TYPE == 1)
199  clock_t curr_rtime, curr_utime, curr_stime;
200  clock_t rtime = real_time;
201  if (Running)
202  {
203  Current(&curr_rtime, &curr_utime, &curr_stime);
204  rtime += (curr_rtime - start_rtime);
205  }
206  return (double)(rtime) / my_CLK_TCK;
207 #elif (MFEM_TIMER_TYPE == 2)
208  if (Running)
209  {
210  struct timespec curr_rtime;
211  GetRealTime(curr_rtime);
212  return ((real_time.tv_sec + (curr_rtime.tv_sec - start_rtime.tv_sec)) +
213  1e-9*(real_time.tv_nsec +
214  (curr_rtime.tv_nsec - start_rtime.tv_nsec)));
215  }
216  else
217  {
218  return real_time.tv_sec + 1e-9*real_time.tv_nsec;
219  }
220 #elif (MFEM_TIMER_TYPE == 3)
221  LARGE_INTEGER curr_rtime, rtime = real_time;
222  if (Running)
223  {
224  QueryPerformanceCounter(&curr_rtime);
225  rtime.QuadPart += (curr_rtime.QuadPart - start_rtime.QuadPart);
226  }
227  return (double)(rtime.QuadPart) / frequency.QuadPart;
228 #endif
229 }
230 
231 inline double StopWatch::UserTime()
232 {
233 #if (MFEM_TIMER_TYPE == 0)
234  std::clock_t utime = user_time;
235  if (Running)
236  utime += (std::clock() - start_utime);
237  return (double)(utime) / CLOCKS_PER_SEC;
238 #elif (MFEM_TIMER_TYPE == 1)
239  clock_t curr_rtime, curr_utime, curr_stime;
240  clock_t utime = user_time;
241  if (Running)
242  {
243  Current(&curr_rtime, &curr_utime, &curr_stime);
244  utime += (curr_utime - start_utime);
245  }
246  return (double)(utime) / my_CLK_TCK;
247 #elif (MFEM_TIMER_TYPE == 2)
248  if (Running)
249  {
250  struct timespec curr_utime;
251  GetUserTime(curr_utime);
252  return ((user_time.tv_sec + (curr_utime.tv_sec - start_utime.tv_sec)) +
253  1e-9*(user_time.tv_nsec +
254  (curr_utime.tv_nsec - start_utime.tv_nsec)));
255  }
256  else
257  {
258  return user_time.tv_sec + 1e-9*user_time.tv_nsec;
259  }
260 #elif (MFEM_TIMER_TYPE == 3)
261  return RealTime();
262 #endif
263 }
264 
265 inline double StopWatch::SystTime()
266 {
267 #if (MFEM_TIMER_TYPE == 1)
268  clock_t curr_rtime, curr_utime, curr_stime;
269  clock_t stime = syst_time;
270  if (Running)
271  {
272  Current(&curr_rtime, &curr_utime, &curr_stime);
273  stime += (curr_stime - start_stime);
274  }
275  return (double)(stime) / my_CLK_TCK;
276 #else
277  return 0.0;
278 #endif
279 }
280 
281 } // namespace internal
282 
283 
285 {
286  M = new internal::StopWatch;
287 }
288 
290 {
291  M->Clear();
292 }
293 
295 {
296  M->Start();
297 }
298 
300 {
301  M->Stop();
302 }
303 
305 {
306  return M->Resolution();
307 }
308 
310 {
311  return M->RealTime();
312 }
313 
315 {
316  return M->UserTime();
317 }
318 
320 {
321  return M->SystTime();
322 }
323 
325 {
326  delete M;
327 }
328 
329 
331 
332 void tic()
333 {
334  tic_toc.Clear();
335  tic_toc.Start();
336 }
337 
338 double toc()
339 {
340  return tic_toc.UserTime();
341 }
342 
343 }
StopWatch tic_toc
Definition: tic_toc.cpp:330
double RealTime()
Definition: tic_toc.cpp:309
double UserTime()
Definition: tic_toc.cpp:314
Timing object.
Definition: tic_toc.hpp:34
double Resolution()
Definition: tic_toc.cpp:304
void tic()
Start timing.
Definition: tic_toc.cpp:332
double toc()
End timing.
Definition: tic_toc.cpp:338
double SystTime()
Definition: tic_toc.cpp:319