hpp-fcl  1.4.4
HPP fork of FCL -- The Flexible Collision Library
profile.h
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2008-2014, Willow Garage, Inc.
5  * Copyright (c) 2014-2015, Open Source Robotics Foundation
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * * Neither the name of Open Source Robotics Foundation nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 
37 /* Author Ioan Sucan */
38 
39 #ifndef HPP_FCL_UTIL_PROFILER
40 #define HPP_FCL_UTIL_PROFILER
41 
42 #define ENABLE_PROFILING 1
43 
44 #ifndef ENABLE_PROFILING
45 
47 
48 # ifdef NDEBUG
49 # define ENABLE_PROFILING 0
50 # else
51 # define ENABLE_PROFILING 1
52 # endif
53 
54 #endif
55 
56 #if ENABLE_PROFILING
57 
58 #include <map>
59 #include <string>
60 #include <iostream>
61 #include <boost/thread.hpp>
62 #include <boost/noncopyable.hpp>
63 #include <boost/date_time/posix_time/posix_time.hpp>
64 
65 namespace hpp
66 {
67 namespace fcl
68 {
69 
71 namespace time
72 {
73 
75 typedef boost::posix_time::ptime point;
76 
78 typedef boost::posix_time::time_duration duration;
79 
81 inline point now(void)
82 {
83  return boost::posix_time::microsec_clock::universal_time();
84 }
85 
87 inline duration seconds(double sec)
88 {
89  long int s = static_cast<long int>(sec);
90  long int us = ((static_cast<long int>(sec) - s) * 1000000);
91  return boost::posix_time::seconds(s) + boost::posix_time::microseconds(us);
92 }
93 
95 inline double seconds(const duration &d)
96 {
97  return (double)d.total_microseconds() / 1000000.0;
98 }
99 
100 }
101 
102 namespace tools
103 {
104 
110 class Profiler : private boost::noncopyable
111 {
112 public:
113 
116  {
117  public:
119  ScopedBlock(const std::string &name, Profiler &prof = Profiler::Instance()) : name_(name), prof_(prof)
120  {
121  prof_.begin(name);
122  }
123 
125  {
126  prof_.end(name_);
127  }
128 
129  private:
130 
131  std::string name_;
132  Profiler &prof_;
133  };
134 
138  {
139  public:
140 
142  ScopedStart(Profiler &prof = Profiler::Instance()) : prof_(prof), wasRunning_(prof_.running())
143  {
144  if (!wasRunning_)
145  prof_.start();
146  }
147 
149  {
150  if (!wasRunning_)
151  prof_.stop();
152  }
153 
154  private:
155 
156  Profiler &prof_;
157  bool wasRunning_;
158  };
159 
161  static Profiler& Instance(void);
162 
165  Profiler(bool printOnDestroy = false, bool autoStart = false) : running_(false), printOnDestroy_(printOnDestroy)
166  {
167  if (autoStart)
168  start();
169  }
170 
172  ~Profiler(void)
173  {
174  if (printOnDestroy_ && !data_.empty())
175  status();
176  }
177 
179  static void Start(void)
180  {
181  Instance().start();
182  }
183 
185  static void Stop(void)
186  {
187  Instance().stop();
188  }
189 
191  static void Clear(void)
192  {
193  Instance().clear();
194  }
195 
197  void start(void);
198 
200  void stop(void);
201 
203  void clear(void);
204 
206  static void Event(const std::string& name, const unsigned int times = 1)
207  {
208  Instance().event(name, times);
209  }
210 
212  void event(const std::string &name, const unsigned int times = 1);
213 
215  static void Average(const std::string& name, const double value)
216  {
217  Instance().average(name, value);
218  }
219 
221  void average(const std::string &name, const double value);
222 
224  static void Begin(const std::string &name)
225  {
226  Instance().begin(name);
227  }
228 
230  static void End(const std::string &name)
231  {
232  Instance().end(name);
233  }
234 
236  void begin(const std::string &name);
237 
239  void end(const std::string &name);
240 
244  static void Status(std::ostream &out = std::cout, bool merge = true)
245  {
246  Instance().status(out, merge);
247  }
248 
252  void status(std::ostream &out = std::cout, bool merge = true);
253 
255  bool running(void) const
256  {
257  return running_;
258  }
259 
261  static bool Running(void)
262  {
263  return Instance().running();
264  }
265 
266 private:
267 
269  struct TimeInfo
270  {
271  TimeInfo(void) : total(0, 0, 0, 0), shortest(boost::posix_time::pos_infin), longest(boost::posix_time::neg_infin), parts(0)
272  {
273  }
274 
276  time::duration total;
277 
279  time::duration shortest;
280 
282  time::duration longest;
283 
285  unsigned long int parts;
286 
288  time::point start;
289 
291  void set(void)
292  {
293  start = time::now();
294  }
295 
297  void update(void)
298  {
299  const time::duration &dt = time::now() - start;
300  if (dt > longest)
301  longest = dt;
302  if (dt < shortest)
303  shortest = dt;
304  total = total + dt;
305  ++parts;
306  }
307  };
308 
310  struct AvgInfo
311  {
313  double total;
314 
316  double totalSqr;
317 
319  unsigned long int parts;
320  };
321 
323  struct PerThread
324  {
326  std::map<std::string, unsigned long int> events;
327 
329  std::map<std::string, AvgInfo> avg;
330 
332  std::map<std::string, TimeInfo> time;
333  };
334 
335  void printThreadInfo(std::ostream &out, const PerThread &data);
336 
337  boost::mutex lock_;
338  std::map<boost::thread::id, PerThread> data_;
339  TimeInfo tinfo_;
340  bool running_;
341  bool printOnDestroy_;
342 
343 };
344 }
345 }
346 
347 #else
348 
349 #include <string>
350 #include <iostream>
351 
353 namespace hpp
354 {
355 namespace fcl
356 {
357 
358 namespace tools
359 {
360 
361 class Profiler
362 {
363 public:
364 
365  class ScopedBlock
366  {
367  public:
368 
369  ScopedBlock(const std::string &, Profiler & = Profiler::Instance())
370  {
371  }
372 
373  ~ScopedBlock(void)
374  {
375  }
376  };
377 
378  class ScopedStart
379  {
380  public:
381 
382  ScopedStart(Profiler & = Profiler::Instance())
383  {
384  }
385 
386  ~ScopedStart(void)
387  {
388  }
389  };
390 
391  static Profiler& Instance(void);
392 
393  Profiler(bool = true, bool = true)
394  {
395  }
396 
397  ~Profiler(void)
398  {
399  }
400 
401  static void Start(void)
402  {
403  }
404 
405  static void Stop(void)
406  {
407  }
408 
409  static void Clear(void)
410  {
411  }
412 
413  void start(void)
414  {
415  }
416 
417  void stop(void)
418  {
419  }
420 
421  void clear(void)
422  {
423  }
424 
425  static void Event(const std::string&, const unsigned int = 1)
426  {
427  }
428 
429  void event(const std::string &, const unsigned int = 1)
430  {
431  }
432 
433  static void Average(const std::string&, const double)
434  {
435  }
436 
437  void average(const std::string &, const double)
438  {
439  }
440 
441  static void Begin(const std::string &)
442  {
443  }
444 
445  static void End(const std::string &)
446  {
447  }
448 
449  void begin(const std::string &)
450  {
451  }
452 
453  void end(const std::string &)
454  {
455  }
456 
457  static void Status(std::ostream & = std::cout, bool = true)
458  {
459  }
460 
461  void status(std::ostream & = std::cout, bool = true)
462  {
463  }
464 
465  bool running(void) const
466  {
467  return false;
468  }
469 
470  static bool Running(void)
471  {
472  return false;
473  }
474 };
475 }
476 }
477 
478 #endif
479 
480 } // namespace hpp
481 
482 #endif
static void Event(const std::string &name, const unsigned int times=1)
Count a specific event for a number of times.
Definition: profile.h:206
void status(std::ostream &out=std::cout, bool merge=true)
Print the status of the profiled code chunks and events. Optionally, computation done by different th...
This is a simple thread-safe tool for counting time spent in various chunks of code. This is different from external profiling tools in that it allows the user to count time spent in various bits of code (sub-function granularity) or count how many times certain pieces of code are executed.
Definition: profile.h:110
boost::posix_time::ptime point
Representation of a point in time.
Definition: profile.h:75
static void Status(std::ostream &out=std::cout, bool merge=true)
Print the status of the profiled code chunks and events. Optionally, computation done by different th...
Definition: profile.h:244
Main namespace.
Definition: AABB.h:43
void end(const std::string &name)
Stop counting time for a specific chunk of code.
static void Start(void)
Start counting time.
Definition: profile.h:179
This instance will call Profiler::start() when constructed and Profiler::stop() when it goes out of s...
Definition: profile.h:137
~ScopedStart(void)
Definition: profile.h:148
static void Average(const std::string &name, const double value)
Maintain the average of a specific value.
Definition: profile.h:215
void start(void)
Start counting time.
double seconds(const duration &d)
Return the number of seconds that a time duration represents.
Definition: profile.h:95
ScopedStart(Profiler &prof=Profiler::Instance())
Take as argument the profiler instance to operate on (prof)
Definition: profile.h:142
bool running(void) const
Check if the profiler is counting time or not.
Definition: profile.h:255
static void Stop(void)
Stop counting time.
Definition: profile.h:185
static void Clear(void)
Clear counted time and events.
Definition: profile.h:191
void event(const std::string &name, const unsigned int times=1)
Count a specific event for a number of times.
void clear(void)
Clear counted time and events.
duration seconds(double sec)
Return the time duration representing a given number of seconds.
Definition: profile.h:87
Profiler(bool printOnDestroy=false, bool autoStart=false)
Constructor. It is allowed to separately instantiate this class (not only as a singleton) ...
Definition: profile.h:165
ScopedBlock(const std::string &name, Profiler &prof=Profiler::Instance())
Start counting time for the block named name of the profiler prof.
Definition: profile.h:119
static void Begin(const std::string &name)
Begin counting time for a specific chunk of code.
Definition: profile.h:224
point now(void)
Get the current time point.
Definition: profile.h:81
~Profiler(void)
Destructor.
Definition: profile.h:172
void average(const std::string &name, const double value)
Maintain the average of a specific value.
This instance will call Profiler::begin() when constructed and Profiler::end() when it goes out of sc...
Definition: profile.h:115
boost::posix_time::time_duration duration
Representation of a time duration.
Definition: profile.h:78
void stop(void)
Stop counting time.
static void End(const std::string &name)
Stop counting time for a specific chunk of code.
Definition: profile.h:230
~ScopedBlock(void)
Definition: profile.h:124
void begin(const std::string &name)
Begin counting time for a specific chunk of code.
static bool Running(void)
Check if the profiler is counting time or not.
Definition: profile.h:261