timing.h
Go to the documentation of this file.
1 /* ----------------------------------------------------------------------------
2 
3  * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4  * Atlanta, Georgia 30332-0415
5  * All Rights Reserved
6  * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7 
8  * See LICENSE for the license information
9 
10  * -------------------------------------------------------------------------- */
11 
18 #pragma once
19 
20 #include <gtsam/base/FastMap.h>
21 #include <gtsam/dllexport.h>
22 #include <gtsam/config.h> // for GTSAM_USE_TBB
23 
24 #ifdef GTSAM_USE_BOOST_FEATURES
25 #include <boost/version.hpp>
26 #endif
27 
28 #include <memory>
29 #include <cstddef>
30 #include <string>
31 
32 // This file contains the GTSAM timing instrumentation library, a low-overhead method for
33 // learning at a medium-fine level how much time various components of an algorithm take
34 // in CPU and wall time.
35 //
36 // The output of this instrumentation is a call-tree-like printout containing statistics
37 // about each instrumented code block. To print this output at any time, call
38 // tictoc_print() or tictoc_print_().
39 //
40 // An overall point to be aware of is that there are two versions of each function - one
41 // ending in an underscore '_' and one without the trailing underscore. The underscore
42 // versions always are active, but the versions without an underscore are active only when
43 // GTSAM_ENABLE_TIMING is defined (automatically defined in our CMake Timing build type).
44 // GTSAM algorithms are all instrumented with the non-underscore versions, so generally
45 // you should use the underscore versions in your own code to leave out the GTSAM detail.
46 //
47 // gttic and gttoc start and stop a timed section, respectively. gttic creates a *scoped*
48 // object - when it goes out of scope gttoc is called automatically. Thus, you do not
49 // need to call gttoc if you are timing an entire function (see basic use examples below).
50 // However, you must be *aware* of this scoped nature - putting gttic inside of an if(...)
51 // block, for example, will only time code until the closing brace '}'. See advanced
52 // usage below if you need to avoid this.
53 //
54 // Multiple calls nest automatically - each gttic nests under the previous gttic called
55 // for which gttoc has not been called (or the previous gttic did not go out of scope).
56 //
57 // Basic usage examples are as follows:
58 //
59 // - Timing an entire function:
60 // void myFunction() {
61 // gttic_(myFunction);
62 // ........
63 // }
64 //
65 // - Timing an entire function as well as its component parts:
66 // void myLongFunction() {
67 // gttic_(myLongFunction);
68 // gttic_(step1); // Will nest under the 'myLongFunction' label
69 // ........
70 // gttoc_(step1);
71 // gttic_(step2); // Will nest under the 'myLongFunction' label
72 // ........
73 // gttoc_(step2);
74 // ........
75 // }
76 //
77 // - Timing functions calling/called by other functions:
78 // void oneStep() {
79 // gttic_(oneStep); // Will automatically nest under the gttic label of the calling function
80 // .......
81 // }
82 // void algorithm() {
83 // gttic_(algorithm);
84 // oneStep(); // gttic's inside this function will automatically nest inside our 'algorithm' label
85 // twoStep(); // gttic's inside this function will automatically nest inside our 'algorithm' label
86 // }
87 //
88 //
89 // Advanced usage:
90 //
91 // - "Finishing iterations" - to get correct min/max times for each call, you must define
92 // in your code what constitutes an iteration. A single sum for the min/max times is
93 // accumulated within each iteration. If you don't care about min/max times, you don't
94 // need to worry about this. For example:
95 // void myOuterLoop() {
96 // while(true) {
97 // iterateMyAlgorithm();
98 // tictoc_finishedIteration_();
99 // tictoc_print_(); // Optional
100 // }
101 // }
102 //
103 // - Stopping timing a section in a different scope than it is started. Normally, a gttoc
104 // statement goes out of scope at end of C++ scope. However, you can use longtic and
105 // longtoc to start and stop timing with the specified label at any point, without regard
106 // too scope. Note that if you use these, it may become difficult to ensure that you
107 // have matching gttic/gttoc statments. You may want to consider reorganizing your timing
108 // outline to match the scope of your code.
109 
110 #ifdef GTSAM_USE_BOOST_FEATURES
111 // Automatically use the new Boost timers if version is recent enough.
112 #if BOOST_VERSION >= 104800
113 # ifndef GTSAM_DISABLE_NEW_TIMERS
114 # define GTSAM_USING_NEW_BOOST_TIMERS
115 # endif
116 #endif
117 
118 #ifdef GTSAM_USING_NEW_BOOST_TIMERS
119 # include <boost/timer/timer.hpp>
120 #else
121 # include <boost/timer.hpp>
122 # include <gtsam/base/types.h>
123 #endif
124 #endif
125 
126 #ifdef GTSAM_USE_TBB
127 # include <tbb/tick_count.h>
128 # undef min
129 # undef max
130 # undef ERROR
131 #endif
132 
133 namespace gtsam {
134 
135  namespace internal {
136  // Generate/retrieve a unique global ID number that will be used to look up tic/toc statements
137  GTSAM_EXPORT size_t getTicTocID(const char *description);
138 
139  // Create new TimingOutline child for gCurrentTimer, make it gCurrentTimer, and call tic method
140  GTSAM_EXPORT void tic(size_t id, const char *label);
141 
142  // Call toc on gCurrentTimer and then set gCurrentTimer to the parent of gCurrentTimer
143  GTSAM_EXPORT void toc(size_t id, const char *label);
144 
149  protected:
150  size_t id_;
151  size_t t_;
152  size_t tWall_;
153  double t2_ ;
154  size_t tIt_;
155  size_t tMax_;
156  size_t tMin_;
157  size_t n_;
158  size_t myOrder_;
160  std::string label_;
161 
162  // Tree structure
163  std::weak_ptr<TimingOutline> parent_;
165  ChildMap children_;
166 
167 // disable all timers if not using boost
168 #ifdef GTSAM_USE_BOOST_FEATURES
169 #ifdef GTSAM_USING_NEW_BOOST_TIMERS
170  boost::timer::cpu_timer timer_;
171 #else
172  boost::timer timer_;
174 #endif
175 #ifdef GTSAM_USE_TBB
176  tbb::tick_count tbbTimer_;
177 #endif
178 #endif
179  void add(size_t usecs, size_t usecsWall);
180 
181  public:
183  GTSAM_EXPORT TimingOutline(const std::string& label, size_t myId);
184  GTSAM_EXPORT size_t time() const;
185  double secs() const { return double(time()) / 1000000.0;}
186 #ifdef GTSAM_USE_BOOST_FEATURES
187  double self() const { return double(t_) / 1000000.0;}
188  double wall() const { return double(tWall_) / 1000000.0;}
189  double min() const { return double(tMin_) / 1000000.0;}
190  double max() const { return double(tMax_) / 1000000.0;}
191  double mean() const { return self() / double(n_); }
192 #else
193  // make them no-ops if not using boost
194  double self() const { return -1.; }
195  double wall() const { return -1.; }
196  double min() const { return -1.; }
197  double max() const { return -1.; }
198  double mean() const { return -1.; }
199 #endif
200  GTSAM_EXPORT void print(const std::string& outline = "") const;
201  GTSAM_EXPORT void print2(const std::string& outline = "", const double parentTotal = -1.0) const;
202  GTSAM_EXPORT const std::shared_ptr<TimingOutline>&
203  child(size_t child, const std::string& label, const std::weak_ptr<TimingOutline>& thisPtr);
204  GTSAM_EXPORT void tic();
205  GTSAM_EXPORT void toc();
206  GTSAM_EXPORT void finishedIteration();
207 
208  GTSAM_EXPORT friend void toc(size_t id, const char *label);
209  }; // \TimingOutline
210 
214  class GTSAM_EXPORT AutoTicToc {
215  private:
216  size_t id_;
217  const char* label_;
218  bool isSet_;
219 
220  public:
221  AutoTicToc(size_t id, const char* label)
222  : id_(id), label_(label), isSet_(true) {
223  tic(id_, label_);
224  }
225  void stop() {
226  toc(id_, label_);
227  isSet_ = false;
228  }
230  if (isSet_) stop();
231  }
232  };
233 
234  GTSAM_EXTERN_EXPORT std::shared_ptr<TimingOutline> gTimingRoot;
235  GTSAM_EXTERN_EXPORT std::weak_ptr<TimingOutline> gCurrentTimer;
236  }
237 
238 // Tic and toc functions that are always active (whether or not ENABLE_TIMING is defined)
239 // There is a trick being used here to achieve near-zero runtime overhead, in that a
240 // static variable is created for each tic/toc statement storing an integer ID, but the
241 // integer ID is only looked up by string once when the static variable is initialized
242 // as the program starts.
243 
244 // tic
245 #define gttic_(label) \
246  static const size_t label##_id_tic = ::gtsam::internal::getTicTocID(#label); \
247  ::gtsam::internal::AutoTicToc label##_obj(label##_id_tic, #label)
248 
249 // toc
250 #define gttoc_(label) \
251  label##_obj.stop()
252 
253 // tic
254 #define longtic_(label) \
255  static const size_t label##_id_tic = ::gtsam::internal::getTicTocID(#label); \
256  ::gtsam::internal::ticInternal(label##_id_tic, #label)
257 
258 // toc
259 #define longtoc_(label) \
260  static const size_t label##_id_toc = ::gtsam::internal::getTicTocID(#label); \
261  ::gtsam::internal::tocInternal(label##_id_toc, #label)
262 
263 // indicate iteration is finished
265  ::gtsam::internal::gTimingRoot->finishedIteration(); }
266 
267 // print
268 inline void tictoc_print_() {
270 
271 // print mean and standard deviation
272 inline void tictoc_print2_() {
273  ::gtsam::internal::gTimingRoot->print2(); }
274 
275 // get a node by label and assign it to variable
276 #define tictoc_getNode(variable, label) \
277  static const size_t label##_id_getnode = ::gtsam::internal::getTicTocID(#label); \
278  const std::shared_ptr<const ::gtsam::internal::TimingOutline> variable = \
279  ::gtsam::internal::gCurrentTimer.lock()->child(label##_id_getnode, #label, ::gtsam::internal::gCurrentTimer);
280 
281 // reset
282 inline void tictoc_reset_() {
283  ::gtsam::internal::gTimingRoot.reset(new ::gtsam::internal::TimingOutline("Total", ::gtsam::internal::getTicTocID("Total")));
285 
286 #ifdef ENABLE_TIMING
287 #define gttic(label) gttic_(label)
288 #define gttoc(label) gttoc_(label)
289 #define longtic(label) longtic_(label)
290 #define longtoc(label) longtoc_(label)
291 #define tictoc_finishedIteration tictoc_finishedIteration_
292 #define tictoc_print tictoc_print_
293 #define tictoc_reset tictoc_reset_
294 #else
295 #define gttic(label) ((void)0)
296 #define gttoc(label) ((void)0)
297 #define longtic(label) ((void)0)
298 #define longtoc(label) ((void)0)
299 #define tictoc_finishedIteration() ((void)0)
300 #define tictoc_print() ((void)0)
301 #define tictoc_reset() ((void)0)
302 #endif
303 
304 }
double max() const
max time, in seconds
Definition: timing.h:197
double t2_
cache the
Definition: timing.h:153
Typedefs for easier changing of types.
GTSAM_EXPORT size_t time() const
time taken, including children
Definition: timing.cpp:67
double secs() const
time taken, in seconds, including children
Definition: timing.h:185
void tictoc_reset_()
Definition: timing.h:282
GTSAM_EXPORT void finishedIteration()
Definition: timing.cpp:226
GTSAM_EXPORT void tic()
Definition: timing.cpp:172
void toc(size_t id, const char *labelC)
Definition: timing.cpp:275
FastMap< size_t, std::shared_ptr< TimingOutline > > ChildMap
Definition: timing.h:164
AutoTicToc(size_t id, const char *label)
Definition: timing.h:221
double min() const
min time, in seconds
Definition: timing.h:196
void tic(size_t id, const char *labelC)
Definition: timing.cpp:263
GTSAM_EXPORT void print2(const std::string &outline="", const double parentTotal=-1.0) const
Definition: timing.cpp:108
double wall() const
wall time, in seconds
Definition: timing.h:195
GTSAM_EXPORT const std::shared_ptr< TimingOutline > & child(size_t child, const std::string &label, const std::weak_ptr< TimingOutline > &thisPtr)
Definition: timing.cpp:153
GTSAM_EXTERN_EXPORT std::shared_ptr< TimingOutline > gTimingRoot
Definition: timing.h:234
GTSAM_EXPORT TimingOutline(const std::string &label, size_t myId)
Constructor.
Definition: timing.cpp:56
void tictoc_print_()
Definition: timing.h:268
void add(size_t usecs, size_t usecsWall)
Definition: timing.cpp:46
std::weak_ptr< TimingOutline > parent_
parent pointer
Definition: timing.h:163
size_t getTicTocID(const char *descriptionC)
Definition: timing.cpp:240
traits
Definition: chartTesting.h:28
A thin wrapper around std::map that uses boost&#39;s fast_pool_allocator.
GTSAM_EXTERN_EXPORT std::weak_ptr< TimingOutline > gCurrentTimer
Definition: timing.h:235
double mean() const
mean self time, in seconds
Definition: timing.h:198
void tictoc_finishedIteration_()
Definition: timing.h:264
ChildMap children_
subtrees
Definition: timing.h:165
static BenchTimer timer
GTSAM_EXPORT void toc()
Definition: timing.cpp:191
GTSAM_EXPORT void print(const std::string &outline="") const
Definition: timing.cpp:85
void tictoc_print2_()
Definition: timing.h:272


gtsam
Author(s):
autogenerated on Tue Jul 4 2023 02:40:20