STXXL  1.4-dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
timing.h
Go to the documentation of this file.
1 /***************************************************************************
2  * include/stxxl/bits/parallel/timing.h
3  *
4  * Provides a simple tool to do performance debugging, also in parallel code.
5  * Extracted from MCSTL - http://algo2.iti.uni-karlsruhe.de/singler/mcstl/
6  *
7  * Part of the STXXL. See http://stxxl.sourceforge.net
8  *
9  * Copyright (C) 2006 Johannes Singler <[email protected]>
10  * Copyright (C) 2014 Timo Bingmann <[email protected]>
11  *
12  * Distributed under the Boost Software License, Version 1.0.
13  * (See accompanying file LICENSE_1_0.txt or copy at
14  * http://www.boost.org/LICENSE_1_0.txt)
15  **************************************************************************/
16 
17 #ifndef STXXL_PARALLEL_TIMING_HEADER
18 #define STXXL_PARALLEL_TIMING_HEADER
19 
20 #include <cstdio>
21 #include <cstring>
22 #include <cassert>
23 
24 #include <stxxl/bits/config.h>
26 
27 #if STXXL_PARALLEL
28  #include <omp.h>
29 #endif
30 
32 
33 namespace parallel {
34 
35 /** Type of of point in time, used for the Timing classes. */
36 typedef double point_in_time;
37 
38 template <typename tag, typename must_be_int = int>
39 class Timing;
40 
41 #if STXXL_PARALLEL
42 
43 /** A class that provides simple run time measurements, also for parallel code.
44  * \param tag If active_tag, then the measurements are actually done.
45  * Otherwise, no code at all is emitted by the compiler. */
46 template <typename must_be_int>
47 class Timing<active_tag, must_be_int>
48 {
49 private:
50  static const int max_points_in_time = 100;
51  point_in_time points_in_time[max_points_in_time];
52  point_in_time active, last_start;
53  int pos;
54  char* str;
55  const char* tags[max_points_in_time];
56 
57 public:
58  Timing()
59  {
60  str = NULL;
61  pos = 0;
62  active = 0.0;
63  last_start = -1.0;
64  }
65 
66  ~Timing()
67  {
68  delete[] str;
69  }
70 
71  /** Take a running time measurement.
72  * \param tag Optional description that will be output again with the timings.
73  * It should describe the operation before the tic(). To time a series of \c n
74  * operations, there should be \c n+1 calls to tic(), and one call to print(). */
75  inline void tic(const char* tag = NULL)
76  {
77  points_in_time[pos] = omp_get_wtime();
78  tags[pos] = tag;
79  pos++;
80  }
81 
82  /** Start the running time measurement.
83  *
84  * Should be paired with stop(). */
85  inline void start()
86  {
87  assert(last_start == -1.0);
88  last_start = omp_get_wtime();
89  }
90 
91  /** Stop the running time measurement.
92  *
93  * Should be paired with start(). */
94  inline void stop()
95  {
96  assert(last_start != -1.0);
97  active += (omp_get_wtime() - last_start);
98  last_start = -1.0;
99  }
100 
101  /** Reset running time accumulation. */
102  inline void reset()
103  {
104  active = 0.0;
105  last_start = -1.0;
106  }
107 
108  /** Accumulate the time between all pairs of start() and stop() so far */
109  inline point_in_time active_time()
110  {
111  return active;
112  }
113 
114  /** Total time between first and last tic() */
115  inline point_in_time total_time()
116  {
117  return (points_in_time[pos - 1] - points_in_time[0]) * 1000.0;
118  }
119 
120 private:
121  /** Construct string to print out, presenting the timings. */
122  const char * c_str()
123  {
124  //avoid stream library here, to avoid cyclic dependencies in header files
125 
126  char tmp[1000];
127 
128  if (!str)
129  str = new char[pos * 200];
130  else
131  str[0] = '\0';
132 
133  sprintf(str, "t %2d T[ms]", omp_get_thread_num());
134  strcat(str, "\n");
135 
136  for (int i = 0; i < pos; )
137  {
138  point_in_time last = points_in_time[i];
139  i++;
140  if (i == pos)
141  break;
142  if (tags[i] == NULL)
143  sprintf(tmp, "%2d: ", i - 1);
144  else
145  sprintf(tmp, "%20s: ", tags[i]);
146  strcat(str, tmp);
147 
148  sprintf(tmp, "%7.2f ", (points_in_time[i] - last) * 1000.0);
149  strcat(str, tmp);
150  strcat(str, "\n");
151  }
152 
153  return str;
154  }
155 
156 public:
157  /** Print the running times between the tic()s. */
158  void print()
159  {
160  printf("print\n");
161 
162 #pragma omp barrier
163 
164 #pragma omp master
165  printf("\n\n");
166 
167 #pragma omp critical
168  printf("%s\n", c_str());
169  }
170 };
171 
172 #endif // STXXL_PARALLEL
173 
174 /** A class that provides simple run time measurements, also for parallel code.
175  * \param tag If active_tag, then the measurements are actually done,
176  * otherwise, no code at all is emitted by the compiler. */
177 template <typename must_be_int>
178 class Timing<inactive_tag, must_be_int>
179 {
180 private:
181  static const char* empty_string;
182 
183 public:
184  inline void tic(const char* /*tag*/ = NULL) { }
185  inline void start() { }
186  inline void stop() { }
187  inline void reset() { }
188  inline point_in_time active_time() { return -1.0; }
189  inline point_in_time total_time() { return -1.0; }
190  inline const char * c_str() { return empty_string; }
191  inline void print() { }
192 };
193 
194 template <typename must_be_int>
195 const char* Timing<inactive_tag, must_be_int>::empty_string = "";
196 
197 } // namespace parallel
198 
200 
201 #endif // !STXXL_PARALLEL_TIMING_HEADER
#define STXXL_BEGIN_NAMESPACE
Definition: namespace.h:16
double point_in_time
Definition: timing.h:36
#define STXXL_END_NAMESPACE
Definition: namespace.h:17