gtsam  3.2.1
gtsam
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 <string>
21 #include <boost/shared_ptr.hpp>
22 #include <boost/weak_ptr.hpp>
23 #include <boost/version.hpp>
24 #include <gtsam/global_includes.h>
25 #include <gtsam/base/FastMap.h>
26 
27 // This file contains the GTSAM timing instrumentation library, a low-overhead method for
28 // learning at a medium-fine level how much time various components of an algorithm take
29 // in CPU and wall time.
30 //
31 // The output of this instrumentation is a call-tree-like printout containing statistics
32 // about each instrumented code block. To print this output at any time, call
33 // tictoc_print() or tictoc_print_().
34 //
35 // An overall point to be aware of is that there are two versions of each function - one
36 // ending in an underscore '_' and one without the trailing underscore. The underscore
37 // versions always are active, but the versions without an underscore are active only when
38 // GTSAM_ENABLE_TIMING is defined (automatically defined in our CMake Timing build type).
39 // GTSAM algorithms are all instrumented with the non-underscore versions, so generally
40 // you should use the underscore versions in your own code to leave out the GTSAM detail.
41 //
42 // gttic and gttoc start and stop a timed section, respectively. gttic creates a *scoped*
43 // object - when it goes out of scope gttoc is called automatically. Thus, you do not
44 // need to call gttoc if you are timing an entire function (see basic use examples below).
45 // However, you must be *aware* of this scoped nature - putting gttic inside of an if(...)
46 // block, for example, will only time code until the closing brace '}'. See advanced
47 // usage below if you need to avoid this.
48 //
49 // Multiple calls nest automatically - each gttic nests under the previous gttic called
50 // for which gttoc has not been called (or the previous gttic did not go out of scope).
51 //
52 // Basic usage examples are as follows:
53 //
54 // - Timing an entire function:
55 // void myFunction() {
56 // gttic_(myFunction);
57 // ........
58 // }
59 //
60 // - Timing an entire function as well as its component parts:
61 // void myLongFunction() {
62 // gttic_(myLongFunction);
63 // gttic_(step1); // Will nest under the 'myLongFunction' label
64 // ........
65 // gttoc_(step1);
66 // gttic_(step2); // Will nest under the 'myLongFunction' label
67 // ........
68 // gttoc_(step2);
69 // ........
70 // }
71 //
72 // - Timing functions calling/called by other functions:
73 // void oneStep() {
74 // gttic_(oneStep); // Will automatically nest under the gttic label of the calling function
75 // .......
76 // }
77 // void algorithm() {
78 // gttic_(algorithm);
79 // oneStep(); // gttic's inside this function will automatically nest inside our 'algorithm' label
80 // twoStep(); // gttic's inside this function will automatically nest inside our 'algorithm' label
81 // }
82 //
83 //
84 // Advanced usage:
85 //
86 // - "Finishing iterations" - to get correct min/max times for each call, you must define
87 // in your code what constitutes an iteration. A single sum for the min/max times is
88 // accumulated within each iteration. If you don't care about min/max times, you don't
89 // need to worry about this. For example:
90 // void myOuterLoop() {
91 // while(true) {
92 // iterateMyAlgorithm();
93 // tictoc_finishedIteration_();
94 // tictoc_print_(); // Optional
95 // }
96 // }
97 //
98 // - Stopping timing a section in a different scope than it is started. Normally, a gttoc
99 // statement goes out of scope at end of C++ scope. However, you can use longtic and
100 // longtoc to start and stop timing with the specified label at any point, without regard
101 // too scope. Note that if you use these, it may become difficult to ensure that you
102 // have matching gttic/gttoc statments. You may want to consider reorganizing your timing
103 // outline to match the scope of your code.
104 
105 // Automatically use the new Boost timers if version is recent enough.
106 #if BOOST_VERSION >= 104800
107 # ifndef GTSAM_DISABLE_NEW_TIMERS
108 # define GTSAM_USING_NEW_BOOST_TIMERS
109 # endif
110 #endif
111 
112 #ifdef GTSAM_USING_NEW_BOOST_TIMERS
113 # include <boost/timer/timer.hpp>
114 #else
115 # include <boost/timer.hpp>
116 #endif
117 
118 #ifdef GTSAM_USE_TBB
119 # include <tbb/tick_count.h>
120 # undef min
121 # undef max
122 # undef ERROR
123 #endif
124 
125 namespace gtsam {
126 
127  namespace internal {
128  GTSAM_EXPORT size_t getTicTocID(const char *description);
129  GTSAM_EXPORT void ticInternal(size_t id, const char *label);
130  GTSAM_EXPORT void tocInternal(size_t id, const char *label);
131 
135  class GTSAM_EXPORT TimingOutline {
136  protected:
137  size_t myId_;
138  size_t t_;
139  size_t tWall_;
140  double t2_ ;
141  size_t tIt_;
142  size_t tMax_;
143  size_t tMin_;
144  size_t n_;
145  size_t myOrder_;
146  size_t lastChildOrder_;
147  std::string label_;
148 
149  // Tree structure
150  boost::weak_ptr<TimingOutline> parent_;
153 
154 #ifdef GTSAM_USING_NEW_BOOST_TIMERS
155  boost::timer::cpu_timer timer_;
156 #else
157  boost::timer timer_;
159 #endif
160 #ifdef GTSAM_USE_TBB
161  tbb::tick_count tbbTimer_;
162 #endif
163  void add(size_t usecs, size_t usecsWall);
164 
165  public:
167  TimingOutline(const std::string& label, size_t myId);
168  size_t time() const;
169  double secs() const { return double(time()) / 1000000.0;}
170  double self() const { return double(t_) / 1000000.0;}
171  double wall() const { return double(tWall_) / 1000000.0;}
172  double min() const { return double(tMin_) / 1000000.0;}
173  double max() const { return double(tMax_) / 1000000.0;}
174  double mean() const { return self() / double(n_); }
175  void print(const std::string& outline = "") const;
176  void print2(const std::string& outline = "", const double parentTotal = -1.0) const;
177  const boost::shared_ptr<TimingOutline>&
178  child(size_t child, const std::string& label, const boost::weak_ptr<TimingOutline>& thisPtr);
179  void ticInternal();
180  void tocInternal();
181  void finishedIteration();
182 
183  GTSAM_EXPORT friend void tocInternal(size_t id, const char *label);
184  }; // \TimingOutline
185 
189  class AutoTicToc {
190  private:
191  size_t id_;
192  const char *label_;
193  bool isSet_;
194  public:
195  AutoTicToc(size_t id, const char* label) : id_(id), label_(label), isSet_(true) { ticInternal(id_, label_); }
196  void stop() { tocInternal(id_, label_); isSet_ = false; }
197  ~AutoTicToc() { if(isSet_) stop(); }
198  };
199 
200  GTSAM_EXTERN_EXPORT boost::shared_ptr<TimingOutline> timingRoot;
201  GTSAM_EXTERN_EXPORT boost::weak_ptr<TimingOutline> timingCurrent;
202  }
203 
204 // Tic and toc functions that are always active (whether or not ENABLE_TIMING is defined)
205 // There is a trick being used here to achieve near-zero runtime overhead, in that a
206 // static variable is created for each tic/toc statement storing an integer ID, but the
207 // integer ID is only looked up by string once when the static variable is initialized
208 // as the program starts.
209 
210 // tic
211 #define gttic_(label) \
212  static const size_t label##_id_tic = ::gtsam::internal::getTicTocID(#label); \
213  ::gtsam::internal::AutoTicToc label##_obj = ::gtsam::internal::AutoTicToc(label##_id_tic, #label)
214 
215 // toc
216 #define gttoc_(label) \
217  label##_obj.stop()
218 
219 // tic
220 #define longtic_(label) \
221  static const size_t label##_id_tic = ::gtsam::internal::getTicTocID(#label); \
222  ::gtsam::internal::ticInternal(label##_id_tic, #label)
223 
224 // toc
225 #define longtoc_(label) \
226  static const size_t label##_id_toc = ::gtsam::internal::getTicTocID(#label); \
227  ::gtsam::internal::tocInternal(label##_id_toc, #label)
228 
229 // indicate iteration is finished
230 inline void tictoc_finishedIteration_() {
231  ::gtsam::internal::timingRoot->finishedIteration(); }
232 
233 // print
234 inline void tictoc_print_() {
235  ::gtsam::internal::timingRoot->print(); }
236 
237 // print mean and standard deviation
238 inline void tictoc_print2_() {
239  ::gtsam::internal::timingRoot->print2(); }
240 
241 // get a node by label and assign it to variable
242 #define tictoc_getNode(variable, label) \
243  static const size_t label##_id_getnode = ::gtsam::internal::getTicTocID(#label); \
244  const boost::shared_ptr<const ::gtsam::internal::TimingOutline> variable = \
245  ::gtsam::internal::timingCurrent.lock()->child(label##_id_getnode, #label, ::gtsam::internal::timingCurrent);
246 
247 // reset
248 inline void tictoc_reset_() {
249  ::gtsam::internal::timingRoot.reset(new ::gtsam::internal::TimingOutline("Total", ::gtsam::internal::getTicTocID("Total")));
250  ::gtsam::internal::timingCurrent = ::gtsam::internal::timingRoot; }
251 
252 #ifdef ENABLE_TIMING
253 #define gttic(label) gttic_(label)
254 #define gttoc(label) gttoc_(label)
255 #define longtic(label) longtic_(label)
256 #define longtoc(label) longtoc_(label)
257 #define tictoc_finishedIteration tictoc_finishedIteration_
258 #define tictoc_print tictoc_print_
259 #define tictoc_reset tictoc_reset_
260 #else
261 #define gttic(label) ((void)0)
262 #define gttoc(label) ((void)0)
263 #define longtic(label) ((void)0)
264 #define longtoc(label) ((void)0)
265 #define tictoc_finishedIteration() ((void)0)
266 #define tictoc_print() ((void)0)
267 #define tictoc_reset() ((void)0)
268 #endif
269 
270 }
double t2_
cache the t_i^2
Definition: timing.h:140
Definition: FastMap.h:37
double mean() const
mean self time, in seconds
Definition: timing.h:174
No documentation.
Definition: timing.h:189
Included from all GTSAM files.
double max() const
max time, in seconds
Definition: timing.h:173
double min() const
min time, in seconds
Definition: timing.h:172
void print(const Matrix &A, const string &s, ostream &stream)
print a matrix
Definition: Matrix.cpp:183
ChildMap children_
subtrees
Definition: timing.h:152
A thin wrapper around std::map that uses boost's fast_pool_allocator.
boost::weak_ptr< TimingOutline > parent_
parent pointer
Definition: timing.h:150
double wall() const
wall time, in seconds
Definition: timing.h:171
double secs() const
time taken, in seconds, including children
Definition: timing.h:169
Timing Entry, arranged in a tree.
Definition: timing.h:135