timer.h
1 /*
2  @copyright Russell Standish 2000-2013
3  @author Russell Standish
4  This file is part of EcoLab
5 
6  Open source licensed under the MIT license. See LICENSE for details.
7 */
8 
9 #ifndef TIMER_H
10 #define TIMER_H
11 #if !defined(__MINGW32__) && !defined(__MINGW32_VERSION)
12 #include <unistd.h>
13 #include <sys/times.h>
14 #endif
15 #include <stdio.h>
16 #include <iostream>
17 #include <vector>
18 #include <map>
19 #include <string>
20 #include <algorithm>
21 
22 namespace ecolab
23 {
24  struct Times
25  {
26  unsigned long counts;
27  double elapsed, user, system;
28  clock_t start_e, start_u, start_s;
29  bool started;
30  Times(): counts(0), elapsed(0), user(0), system(0), started(false) {}
31  };
32 
36  inline std::map<std::string, Times>& timers() {
37  static std::map<std::string, Times> _timers;
38  return _timers;
39  }
40 
43  inline void start_timer(const std::string& s)
44  {
45 #ifdef _OPENMP
46 #pragma omp critical(ecolab_timers)
47 #endif
48  {
49 #if !defined(__MINGW32__) && !defined(__MINGW32_VERSION)
50  Times& t=timers()[s];
51  if (!t.started)
52  {
53  t.started = true;
54 
55  struct tms tbuf;
56  t.start_e = times(&tbuf);
57  t.start_u = tbuf.tms_utime;
58  t.start_s = tbuf.tms_stime;
59  }
60 #endif
61  }
62  }
63 
66  inline void stop_timer(const std::string& s)
67  {
68 #if !defined(__MINGW32__) && !defined(__MINGW32_VERSION)
69  Times& t=timers()[s];
70  if (!t.started)
71  {
72  t.started = true;
73 
74  struct tms tbuf;
75  t.start_e = times(&tbuf);
76  t.start_u = tbuf.tms_utime;
77  t.start_s = tbuf.tms_stime;
78  }
79 #endif
80  }
81 
82 
84  class Timer
85  {
86  std::string name;
87  public:
88  Timer(const std::string& name): name(name) {start_timer(name);}
89  ~Timer() {stop_timer(name);}
90  };
91 
92  struct SortElapsed
93  {
94  bool operator()(const std::pair<std::string, Times>& x,
95  const std::pair<std::string, Times>& y)
96  {
97  return x.second.elapsed < y.second.elapsed;
98  }
99  };
100 
101  // output the timer values, sorted in elapsed time order
102  inline void print_timers()
103  {
104  std::vector<std::pair<std::string, Times> > times
105  (timers().begin(), timers().end());
106  std::sort(times.begin(), times.end(), SortElapsed());
107  // use printf rather than cout, as we may wish to call this from a
108  // static object destructor
109  std::cout << "------------------ Times --------------------------------\n";
110  for (size_t i=0; i<times.size(); ++i)
111  std::cout << "Elapsed: "<<times[i].second.elapsed<<
112  " User: "<<times[i].second.user<<" System: "<<times[i].second.system <<
113  " Counts: "<<times[i].second.counts<<" "<<times[i].first<<std::endl;
114  std::cout << "----------------------------------------------------------"<<
115  std::endl;
116  }
117 }
118 #endif
void start_timer(const std::string &s)
Definition: timer.h:43
std::map< std::string, Times > & timers()
Definition: timer.h:36
Definition: timer.h:92
RAII class for timing code blocks.
Definition: timer.h:84
void stop_timer(const std::string &s)
Definition: timer.h:66
_OPENMP
Definition: accessor.h:16
Definition: timer.h:24