HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
timer.h
Go to the documentation of this file.
1 /*
2  Copyright 2008 Larry Gritz and the other authors and contributors.
3  All Rights Reserved.
4 
5  Redistribution and use in source and binary forms, with or without
6  modification, are permitted provided that the following conditions are
7  met:
8  * Redistributions of source code must retain the above copyright
9  notice, this list of conditions and the following disclaimer.
10  * Redistributions in binary form must reproduce the above copyright
11  notice, this list of conditions and the following disclaimer in the
12  documentation and/or other materials provided with the distribution.
13  * Neither the name of the software's owners nor the names of its
14  contributors may be used to endorse or promote products derived from
15  this software without specific prior written permission.
16  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28  (This is the Modified BSD License)
29 */
30 
31 
32 /// @file timer.h
33 /// @brief Simple timer class.
34 
35 
36 #pragma once
37 
38 #include <ctime>
39 #include <functional>
40 #include <iostream>
41 
42 #include <OpenImageIO/export.h>
45 #include <OpenImageIO/platform.h>
46 #include <OpenImageIO/span.h>
47 
48 #ifdef _WIN32
49 //# include <windows.h> // Already done by platform.h
50 #elif defined(__APPLE__)
51 # include <mach/mach_time.h>
52 #else
53 # include <sys/time.h>
54 #endif
55 
56 
58 
59 /// Simple timer class.
60 ///
61 /// This class allows you to time things, for runtime statistics and the
62 /// like. The simplest usage pattern is illustrated by the following
63 /// example:
64 ///
65 /// \code
66 /// Timer mytimer; // automatically starts upon construction
67 /// ...do stuff
68 /// float t = mytimer(); // seconds elapsed since start
69 ///
70 /// Timer another (false); // false means don't start ticking yet
71 /// another.start (); // start ticking now
72 /// another.stop (); // stop ticking
73 /// another.start (); // start again where we left off
74 /// another.stop ();
75 /// another.reset (); // reset to zero time again
76 /// \endcode
77 ///
78 /// These are not very high-resolution timers. A Timer begin/end pair
79 /// takes somewhere in the neighborhood of 0.1 - 0.3 us (microseconds),
80 /// and can vary by OS. This means that (a) it's not useful for timing
81 /// individual events near or below that resolution (things that would
82 /// take only tens or hundreds of processor cycles, for example), and
83 /// (b) calling it millions of times could make your program appreciably
84 /// more expensive due to the timers themselves.
85 ///
86 class OIIO_API Timer {
87 public:
88  typedef long long ticks_t;
89  enum StartNowVal { DontStartNow, StartNow };
90  enum PrintDtrVal { DontPrintDtr, PrintDtr };
91 
92  /// Constructor -- reset at zero, and start timing unless optional
93  /// 'startnow' argument is false.
94  Timer(StartNowVal startnow = StartNow, PrintDtrVal printdtr = DontPrintDtr,
95  const char* name = NULL)
96  : m_ticking(false)
97  , m_printdtr(printdtr == PrintDtr)
98  , m_starttime(0)
99  , m_elapsed_ticks(0)
100  , m_name(name)
101  {
102  if (startnow == StartNow)
103  start();
104  }
105 
106  /// Constructor -- reset at zero, and start timing unless optional
107  /// 'startnow' argument is false.
108  Timer(bool startnow)
109  : m_ticking(false)
110  , m_printdtr(DontPrintDtr)
111  , m_starttime(0)
112  , m_elapsed_ticks(0)
113  , m_name(NULL)
114  {
115  if (startnow)
116  start();
117  }
118 
119  /// Destructor.
121  {
122  if (m_printdtr == PrintDtr)
123  std::cout << "Timer " << (m_name ? m_name : "") << ": "
124  << seconds(ticks()) << "s\n";
125  }
126 
127  /// Start (or restart) ticking, if we are not currently.
128  void start()
129  {
130  if (!m_ticking) {
131  m_starttime = now();
132  m_ticking = true;
133  }
134  }
135 
136  /// Stop ticking, return the total amount of time that has ticked
137  /// (both this round as well as previous laps). Current ticks will
138  /// be added to previous elapsed time.
139  double stop()
140  {
141  if (m_ticking) {
142  ticks_t n = now();
143  m_elapsed_ticks += tickdiff(m_starttime, n);
144  m_ticking = false;
145  }
146  return seconds(m_elapsed_ticks);
147  }
148 
149  /// Reset at zero and stop ticking.
150  ///
151  void reset(void)
152  {
153  m_elapsed_ticks = 0;
154  m_ticking = false;
155  }
156 
157  /// Return just the ticks of the current lap (since the last call to
158  /// start() or lap()), add that to the previous elapsed time, reset
159  /// current start time to now, keep the timer going (if it was).
161  {
162  ticks_t n = now();
163  ticks_t r = m_ticking ? tickdiff(m_starttime, n) : ticks_t(0);
164  m_elapsed_ticks += r;
165  m_starttime = n;
166  m_ticking = true;
167  return r;
168  }
169 
170  /// Return just the time of the current lap (since the last call to
171  /// start() or lap()), add that to the previous elapsed time, reset
172  /// current start time to now, keep the timer going (if it was).
173  double lap() { return seconds(lap_ticks()); }
174 
175  /// Total number of elapsed ticks so far, including both the currently-
176  /// ticking clock as well as any previously elapsed time.
177  ticks_t ticks() const { return ticks_since_start() + m_elapsed_ticks; }
178 
179  /// Operator () returns the elapsed time so far, in seconds, including
180  /// both the currently-ticking clock as well as any previously elapsed
181  /// time.
182  double operator()(void) const { return seconds(ticks()); }
183 
184  /// Return just the ticks since we called start(), not any elapsed
185  /// time in previous start-stop segments.
187  {
188  return m_ticking ? tickdiff(m_starttime, now()) : ticks_t(0);
189  }
190 
191  /// Return just the time since we called start(), not any elapsed
192  /// time in previous start-stop segments.
193  double time_since_start(void) const { return seconds(ticks_since_start()); }
194 
195  /// Convert number of ticks to seconds.
196  static double seconds(ticks_t ticks) { return ticks * seconds_per_tick; }
197 
198  /// Is the timer currently ticking?
199  bool ticking() const { return m_ticking; }
200 
201 private:
202  bool m_ticking; ///< Are we currently ticking?
203  bool m_printdtr; ///< Print upon destruction?
204  ticks_t m_starttime; ///< Time since last call to start()
205  ticks_t m_elapsed_ticks; ///< Time elapsed BEFORE the current start().
206  const char* m_name; ///< Timer name
207 
208  /// Platform-dependent grab of current time, expressed as ticks_t.
209  ///
210  ticks_t now(void) const
211  {
212 #ifdef _WIN32
213  LARGE_INTEGER n;
214  QueryPerformanceCounter(&n); // From MSDN web site
215  return n.QuadPart;
216 #elif defined(__APPLE__)
217  return mach_absolute_time();
218 #else
219  struct timeval t;
220  gettimeofday(&t, NULL);
221  return (long long)t.tv_sec * 1000000ll + t.tv_usec;
222 #endif
223  }
224 
225  /// Difference between two times, expressed in (platform-dependent)
226  /// ticks.
227  ticks_t tickdiff(ticks_t then, ticks_t now) const
228  {
229  return (now > then) ? now - then : then - now;
230  }
231 
232  /// Difference between two times, expressed in seconds.
233  double diff(ticks_t then, ticks_t now) const
234  {
235  return seconds(tickdiff(then, now));
236  }
237 
238  static double seconds_per_tick;
239  friend class TimerSetupOnce;
240 };
241 
242 
243 
244 /// Helper class that starts and stops a timer when the ScopedTimer goes
245 /// in and out of scope.
246 class ScopedTimer {
247 public:
248  /// Given a reference to a timer, start it when this constructor
249  /// occurs.
251  : m_timer(t)
252  {
253  start();
254  }
255 
256  /// Stop the timer from ticking when this object is destroyed (i.e.
257  /// it leaves scope).
259 
260  /// Explicit start of the timer.
261  ///
262  void start() { m_timer.start(); }
263 
264  /// Explicit stop of the timer.
265  ///
266  void stop() { m_timer.stop(); }
267 
268  /// Explicit reset of the timer.
269  ///
270  void reset() { m_timer.reset(); }
271 
272 private:
273  Timer& m_timer;
274 };
275 
276 
277 
279 
280 
281 // DEPRECATED(1.8): for back compatibility with old inclusion of some
282 // functions that used to be here but are now in benchmark.h, include it.
283 #include <OpenImageIO/benchmark.h>
PrintDtrVal
Definition: timer.h:90
GLuint const GLchar * name
Definition: glew.h:1814
Definition: timer.h:86
double stop()
Definition: timer.h:139
Timer(StartNowVal startnow=StartNow, PrintDtrVal printdtr=DontPrintDtr, const char *name=NULL)
Definition: timer.h:94
ScopedTimer(Timer &t)
Definition: timer.h:250
long long ticks_t
Definition: timer.h:88
void start()
Start (or restart) ticking, if we are not currently.
Definition: timer.h:128
ticks_t lap_ticks()
Definition: timer.h:160
Platform-related macros.
Timer(bool startnow)
Definition: timer.h:108
**If you just want to fire and then
Definition: thread.h:634
bool ticking() const
Is the timer currently ticking?
Definition: timer.h:199
~ScopedTimer()
Definition: timer.h:258
double time_since_start(void) const
Definition: timer.h:193
GLsizei n
Definition: glew.h:4040
double lap()
Definition: timer.h:173
ticks_t ticks() const
Definition: timer.h:177
GLuint start
Definition: glew.h:1253
void start()
Definition: timer.h:262
void reset(void)
Definition: timer.h:151
double operator()(void) const
Definition: timer.h:182
void reset()
Definition: timer.h:270
void stop()
Definition: timer.h:266
StartNowVal
Definition: timer.h:89
GLdouble GLdouble GLdouble r
Definition: glew.h:1406
#define OIIO_NAMESPACE_END
Definition: oiioversion.h:66
GLfloat seconds
Definition: wglew.h:950
ticks_t ticks_since_start(void) const
Definition: timer.h:186
~Timer()
Destructor.
Definition: timer.h:120
GLdouble GLdouble t
Definition: glew.h:1398
static double seconds(ticks_t ticks)
Convert number of ticks to seconds.
Definition: timer.h:196
#define OIIO_NAMESPACE_BEGIN
Definition: oiioversion.h:65
#define OIIO_API
Definition: export.h:91