gtsam
Loading...
Searching...
No Matches
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#if GTSAM_USE_BOOST_FEATURES
25#include <boost/version.hpp>
26#else
27#include <chrono>
28#include <ctime>
29#endif
30
31#include <memory>
32#include <cstddef>
33#include <string>
34
35// This file contains the GTSAM timing instrumentation library, a low-overhead method for
36// learning at a medium-fine level how much time various components of an algorithm take
37// in CPU and wall time.
38//
39// The output of this instrumentation is a call-tree-like printout containing statistics
40// about each instrumented code block. To print this output at any time, call
41// tictoc_print() or tictoc_print_().
42//
43// An overall point to be aware of is that there are two versions of each function - one
44// ending in an underscore '_' and one without the trailing underscore. The underscore
45// versions always are active, but the versions without an underscore are active only when
46// GTSAM_ENABLE_TIMING is defined (automatically defined in our CMake Timing build type).
47// GTSAM algorithms are all instrumented with the non-underscore versions, so generally
48// you should use the underscore versions in your own code to leave out the GTSAM detail.
49//
50// gttic and gttoc start and stop a timed section, respectively. gttic creates a *scoped*
51// object - when it goes out of scope gttoc is called automatically. Thus, you do not
52// need to call gttoc if you are timing an entire function (see basic use examples below).
53// However, you must be *aware* of this scoped nature - putting gttic inside of an if(...)
54// block, for example, will only time code until the closing brace '}'. See advanced
55// usage below if you need to avoid this.
56//
57// Multiple calls nest automatically - each gttic nests under the previous gttic called
58// for which gttoc has not been called (or the previous gttic did not go out of scope).
59//
60// Basic usage examples are as follows:
61//
62// - Timing an entire function:
63// void myFunction() {
64// gttic_(myFunction);
65// ........
66// }
67//
68// - Timing an entire function as well as its component parts:
69// void myLongFunction() {
70// gttic_(myLongFunction);
71// gttic_(step1); // Will nest under the 'myLongFunction' label
72// ........
73// gttoc_(step1);
74// gttic_(step2); // Will nest under the 'myLongFunction' label
75// ........
76// gttoc_(step2);
77// ........
78// }
79//
80// - Timing functions calling/called by other functions:
81// void oneStep() {
82// gttic_(oneStep); // Will automatically nest under the gttic label of the calling function
83// .......
84// }
85// void algorithm() {
86// gttic_(algorithm);
87// oneStep(); // gttic's inside this function will automatically nest inside our 'algorithm' label
88// twoStep(); // gttic's inside this function will automatically nest inside our 'algorithm' label
89// }
90//
91//
92// Advanced usage:
93//
94// - "Finishing iterations" - to get correct min/max times for each call, you must define
95// in your code what constitutes an iteration. A single sum for the min/max times is
96// accumulated within each iteration. If you don't care about min/max times, you don't
97// need to worry about this. For example:
98// void myOuterLoop() {
99// while(true) {
100// iterateMyAlgorithm();
101// tictoc_finishedIteration_();
102// tictoc_print_(); // Optional
103// }
104// }
105//
106// - Stopping timing a section in a different scope than it is started. Normally, a gttoc
107// statement goes out of scope at end of C++ scope. However, you can use longtic and
108// longtoc to start and stop timing with the specified label at any point, without regard
109// too scope. Note that if you use these, it may become difficult to ensure that you
110// have matching gttic/gttoc statments. You may want to consider reorganizing your timing
111// outline to match the scope of your code.
112
113#if GTSAM_USE_BOOST_FEATURES
114// Automatically use the new Boost timers if version is recent enough.
115#if BOOST_VERSION >= 104800
116# ifndef GTSAM_DISABLE_NEW_TIMERS
117# define GTSAM_USING_NEW_BOOST_TIMERS
118# endif
119#endif
120
121#ifdef GTSAM_USING_NEW_BOOST_TIMERS
122# include <boost/timer/timer.hpp>
123#else
124# include <boost/timer.hpp>
125# include <gtsam/base/types.h>
126#endif
127#endif
128
129#ifdef GTSAM_USE_TBB
130# include <tbb/tick_count.h>
131# undef min
132# undef max
133# undef ERROR
134#endif
135
136namespace gtsam {
137
138 namespace internal {
139 // Generate/retrieve a unique global ID number that will be used to look up tic/toc statements
140 GTSAM_EXPORT size_t getTicTocID(const char *description);
141
142 // Create new TimingOutline child for gCurrentTimer, make it gCurrentTimer, and call tic method
143 GTSAM_EXPORT void tic(size_t id, const char *label);
144
145 // Call toc on gCurrentTimer and then set gCurrentTimer to the parent of gCurrentTimer
146 GTSAM_EXPORT void toc(size_t id, const char *label);
147
152 protected:
153 size_t id_;
154 size_t t_;
155 size_t tWall_;
156 double t2_ ;
157 size_t tIt_;
158 size_t tMax_;
159 size_t tMin_;
160 size_t n_;
161 size_t myOrder_;
162 size_t lastChildOrder_;
163 std::string label_;
164
165 // Tree structure
166 std::weak_ptr<TimingOutline> parent_;
168 ChildMap children_;
169
170// disable all timers if not using boost
171#if GTSAM_USE_BOOST_FEATURES
172#ifdef GTSAM_USING_NEW_BOOST_TIMERS
173 boost::timer::cpu_timer timer_;
174#else
175 boost::timer timer_;
177#endif
178#ifdef GTSAM_USE_TBB
179 tbb::tick_count tbbTimer_;
180#endif
181#else
182 std::chrono::time_point<std::chrono::steady_clock> wall_timer_start_;
183 std::clock_t cpu_timer_start_;
184 bool timer_active_ = false;
185#endif
186 void add(size_t usecs, size_t usecsWall);
187
188 public:
190 GTSAM_EXPORT TimingOutline(const std::string& label, size_t myId);
191 GTSAM_EXPORT size_t time() const;
192 double secs() const { return double(time()) / 1000000.0;}
193#if GTSAM_USE_BOOST_FEATURES
194 double self() const { return double(t_) / 1000000.0;}
195 double wall() const { return double(tWall_) / 1000000.0;}
196 double min() const { return double(tMin_) / 1000000.0;}
197 double max() const { return double(tMax_) / 1000000.0;}
198 double mean() const { return self() / double(n_); }
199#else
200 // make them no-ops if not using boost
201 double self() const { return double(t_) / 1000000.0;}
202 double wall() const { return double(tWall_) / 1000000.0;}
203 double min() const { return double(tMin_) / 1000000.0;}
204 double max() const { return double(tMax_) / 1000000.0;}
205 double mean() const { return n_ > 0 ? self() / double(n_) : 0.0; }
206#endif
207 GTSAM_EXPORT void print(const std::string& outline = "") const;
208 GTSAM_EXPORT void print2(const std::string& outline = "", const double parentTotal = -1.0) const;
209
219 GTSAM_EXPORT void printCsvHeader(bool addLineBreak = false) const;
220
230 GTSAM_EXPORT void printCsv(bool addLineBreak = false) const;
231
232 GTSAM_EXPORT const std::shared_ptr<TimingOutline>&
233 child(size_t child, const std::string& label, const std::weak_ptr<TimingOutline>& thisPtr);
234 GTSAM_EXPORT void tic();
235 GTSAM_EXPORT void toc();
236 GTSAM_EXPORT void finishedIteration();
237
238 GTSAM_EXPORT friend void toc(size_t id, const char *label);
239 }; // \TimingOutline
240
244 class GTSAM_EXPORT AutoTicToc {
245 private:
246 size_t id_;
247 const char* label_;
248 bool isSet_;
249
250 public:
251 AutoTicToc(size_t id, const char* label)
252 : id_(id), label_(label), isSet_(true) {
253 tic(id_, label_);
254 }
255 void stop() {
256 toc(id_, label_);
257 isSet_ = false;
258 }
259 ~AutoTicToc() {
260 if (isSet_) stop();
261 }
262 };
263
264 GTSAM_EXTERN_EXPORT std::shared_ptr<TimingOutline> gTimingRoot;
265 GTSAM_EXTERN_EXPORT std::weak_ptr<TimingOutline> gCurrentTimer;
266 }
267
268// Tic and toc functions that are always active (whether or not ENABLE_TIMING is defined)
269// There is a trick being used here to achieve near-zero runtime overhead, in that a
270// static variable is created for each tic/toc statement storing an integer ID, but the
271// integer ID is only looked up by string once when the static variable is initialized
272// as the program starts.
273
274// tic
275#define gttic_(label) \
276 static const size_t label##_id_tic = ::gtsam::internal::getTicTocID(#label); \
277 ::gtsam::internal::AutoTicToc label##_obj(label##_id_tic, #label)
278
279// toc
280#define gttoc_(label) \
281 label##_obj.stop()
282
283// tic
284#define longtic_(label) \
285 static const size_t label##_id_tic = ::gtsam::internal::getTicTocID(#label); \
286 ::gtsam::internal::ticInternal(label##_id_tic, #label)
287
288// toc
289#define longtoc_(label) \
290 static const size_t label##_id_toc = ::gtsam::internal::getTicTocID(#label); \
291 ::gtsam::internal::tocInternal(label##_id_toc, #label)
292
293// indicate iteration is finished
294inline void tictoc_finishedIteration_() {
295 ::gtsam::internal::gTimingRoot->finishedIteration(); }
296
297// print
298inline void tictoc_print_() {
299 ::gtsam::internal::gTimingRoot->print(); }
300
301// print timing in CSV format
302inline void tictoc_printCsv_(bool displayHeader = false) {
303 if (displayHeader) {
304 ::gtsam::internal::gTimingRoot->printCsvHeader(true);
305 }
306 ::gtsam::internal::gTimingRoot->printCsv(true);
307}
308
309// print mean and standard deviation
310inline void tictoc_print2_() {
311 ::gtsam::internal::gTimingRoot->print2(); }
312
313// get a node by label and assign it to variable
314#define tictoc_getNode(variable, label) \
315 static const size_t label##_id_getnode = ::gtsam::internal::getTicTocID(#label); \
316 const std::shared_ptr<const ::gtsam::internal::TimingOutline> variable = \
317 ::gtsam::internal::gCurrentTimer.lock()->child(label##_id_getnode, #label, ::gtsam::internal::gCurrentTimer);
318
319// reset
320inline void tictoc_reset_() {
321 ::gtsam::internal::gTimingRoot.reset(new ::gtsam::internal::TimingOutline("Total", ::gtsam::internal::getTicTocID("Total")));
322 ::gtsam::internal::gCurrentTimer = ::gtsam::internal::gTimingRoot; }
323
324#ifdef ENABLE_TIMING
325#define gttic(label) gttic_(label)
326#define gttoc(label) gttoc_(label)
327#define longtic(label) longtic_(label)
328#define longtoc(label) longtoc_(label)
329#define tictoc_finishedIteration tictoc_finishedIteration_
330#define tictoc_print tictoc_print_
331#define tictoc_reset tictoc_reset_
332#else
333#define gttic(label) ((void)0)
334#define gttoc(label) ((void)0)
335#define longtic(label) ((void)0)
336#define longtoc(label) ((void)0)
337#define tictoc_finishedIteration() ((void)0)
338#define tictoc_print() ((void)0)
339#define tictoc_reset() ((void)0)
340#endif
341
342}
Typedefs for easier changing of types.
A thin wrapper around std::map that uses boost's fast_pool_allocator.
Global functions in a separate testing namespace.
Definition chartTesting.h:28
void print(const Matrix &A, const string &s, ostream &stream)
print without optional string, must specify cout yourself
Definition Matrix.cpp:143
FastMap is a thin wrapper around std::map that uses the boost fast_pool_allocator instead of the defa...
Definition FastMap.h:40
double t2_
cache the
Definition timing.h:156
ChildMap children_
subtrees
Definition timing.h:168
std::weak_ptr< TimingOutline > parent_
parent pointer
Definition timing.h:166
double max() const
max time, in seconds
Definition timing.h:204
GTSAM_EXPORT void printCsv(bool addLineBreak=false) const
Print the times recursively from parent to child in CSV format.
Definition timing.cpp:135
double wall() const
wall time, in seconds
Definition timing.h:202
double secs() const
time taken, in seconds, including children
Definition timing.h:192
double self() const
self time only, in seconds
Definition timing.h:201
GTSAM_EXPORT TimingOutline(const std::string &label, size_t myId)
Constructor.
Definition timing.cpp:65
double min() const
min time, in seconds
Definition timing.h:203
double mean() const
mean self time, in seconds
Definition timing.h:205
GTSAM_EXPORT size_t time() const
time taken, including children
Definition timing.cpp:77
GTSAM_EXPORT void printCsvHeader(bool addLineBreak=false) const
Print the CSV header.
Definition timing.cpp:112
Helper struct that encapsulates a value with a default, this is just used as a member object so you d...
Definition types.h:58