hpp-fcl  1.6.0
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 #include <hpp/fcl/config.hh>
66 
67 namespace hpp
68 {
69 namespace fcl
70 {
71 
73 namespace time
74 {
75 
77 typedef boost::posix_time::ptime point;
78 
80 typedef boost::posix_time::time_duration duration;
81 
83 inline point now(void)
84 {
85  return boost::posix_time::microsec_clock::universal_time();
86 }
87 
89 inline duration seconds(double sec)
90 {
91  long int s = static_cast<long int>(sec);
92  long int us = ((static_cast<long int>(sec) - s) * 1000000);
93  return boost::posix_time::seconds(s) + boost::posix_time::microseconds(us);
94 }
95 
97 inline double seconds(const duration &d)
98 {
99  return (double)d.total_microseconds() / 1000000.0;
100 }
101 
102 }
103 
104 namespace tools
105 {
106 
112 class HPP_FCL_DLLAPI Profiler : private boost::noncopyable
113 {
114 public:
115 
118  {
119  public:
121  ScopedBlock(const std::string &name, Profiler &prof = Profiler::Instance()) : name_(name), prof_(prof)
122  {
123  prof_.begin(name);
124  }
125 
127  {
128  prof_.end(name_);
129  }
130 
131  private:
132 
133  std::string name_;
134  Profiler &prof_;
135  };
136 
140  {
141  public:
142 
144  ScopedStart(Profiler &prof = Profiler::Instance()) : prof_(prof), wasRunning_(prof_.running())
145  {
146  if (!wasRunning_)
147  prof_.start();
148  }
149 
151  {
152  if (!wasRunning_)
153  prof_.stop();
154  }
155 
156  private:
157 
158  Profiler &prof_;
159  bool wasRunning_;
160  };
161 
163  static Profiler& Instance(void);
164 
167  Profiler(bool printOnDestroy = false, bool autoStart = false) : running_(false), printOnDestroy_(printOnDestroy)
168  {
169  if (autoStart)
170  start();
171  }
172 
174  ~Profiler(void)
175  {
176  if (printOnDestroy_ && !data_.empty())
177  status();
178  }
179 
181  static void Start(void)
182  {
183  Instance().start();
184  }
185 
187  static void Stop(void)
188  {
189  Instance().stop();
190  }
191 
193  static void Clear(void)
194  {
195  Instance().clear();
196  }
197 
199  void start(void);
200 
202  void stop(void);
203 
205  void clear(void);
206 
208  static void Event(const std::string& name, const unsigned int times = 1)
209  {
210  Instance().event(name, times);
211  }
212 
214  void event(const std::string &name, const unsigned int times = 1);
215 
217  static void Average(const std::string& name, const double value)
218  {
219  Instance().average(name, value);
220  }
221 
223  void average(const std::string &name, const double value);
224 
226  static void Begin(const std::string &name)
227  {
228  Instance().begin(name);
229  }
230 
232  static void End(const std::string &name)
233  {
234  Instance().end(name);
235  }
236 
238  void begin(const std::string &name);
239 
241  void end(const std::string &name);
242 
246  static void Status(std::ostream &out = std::cout, bool merge = true)
247  {
248  Instance().status(out, merge);
249  }
250 
254  void status(std::ostream &out = std::cout, bool merge = true);
255 
257  bool running(void) const
258  {
259  return running_;
260  }
261 
263  static bool Running(void)
264  {
265  return Instance().running();
266  }
267 
268 private:
269 
271  struct HPP_FCL_DLLAPI TimeInfo
272  {
273  TimeInfo(void) : total(0, 0, 0, 0), shortest(boost::posix_time::pos_infin), longest(boost::posix_time::neg_infin), parts(0)
274  {
275  }
276 
278  time::duration total;
279 
281  time::duration shortest;
282 
284  time::duration longest;
285 
287  unsigned long int parts;
288 
290  time::point start;
291 
293  void set(void)
294  {
295  start = time::now();
296  }
297 
299  void update(void)
300  {
301  const time::duration &dt = time::now() - start;
302  if (dt > longest)
303  longest = dt;
304  if (dt < shortest)
305  shortest = dt;
306  total = total + dt;
307  ++parts;
308  }
309  };
310 
312  struct HPP_FCL_DLLAPI AvgInfo
313  {
315  double total;
316 
318  double totalSqr;
319 
321  unsigned long int parts;
322  };
323 
325  struct HPP_FCL_DLLAPI PerThread
326  {
328  std::map<std::string, unsigned long int> events;
329 
331  std::map<std::string, AvgInfo> avg;
332 
334  std::map<std::string, TimeInfo> time;
335  };
336 
337  void printThreadInfo(std::ostream &out, const PerThread &data);
338 
339  boost::mutex lock_;
340  std::map<boost::thread::id, PerThread> data_;
341  TimeInfo tinfo_;
342  bool running_;
343  bool printOnDestroy_;
344 
345 };
346 }
347 }
348 
349 #else
350 
351 #include <string>
352 #include <iostream>
353 
355 namespace hpp
356 {
357 namespace fcl
358 {
359 
360 namespace tools
361 {
362 
363 class HPP_FCL_DLLAPI Profiler
364 {
365 public:
366 
367  class HPP_FCL_DLLAPI ScopedBlock
368  {
369  public:
370 
371  ScopedBlock(const std::string &, Profiler & = Profiler::Instance())
372  {
373  }
374 
375  ~ScopedBlock(void)
376  {
377  }
378  };
379 
380  class HPP_FCL_DLLAPI ScopedStart
381  {
382  public:
383 
384  ScopedStart(Profiler & = Profiler::Instance())
385  {
386  }
387 
388  ~ScopedStart(void)
389  {
390  }
391  };
392 
393  static Profiler& Instance(void);
394 
395  Profiler(bool = true, bool = true)
396  {
397  }
398 
399  ~Profiler(void)
400  {
401  }
402 
403  static void Start(void)
404  {
405  }
406 
407  static void Stop(void)
408  {
409  }
410 
411  static void Clear(void)
412  {
413  }
414 
415  void start(void)
416  {
417  }
418 
419  void stop(void)
420  {
421  }
422 
423  void clear(void)
424  {
425  }
426 
427  static void Event(const std::string&, const unsigned int = 1)
428  {
429  }
430 
431  void event(const std::string &, const unsigned int = 1)
432  {
433  }
434 
435  static void Average(const std::string&, const double)
436  {
437  }
438 
439  void average(const std::string &, const double)
440  {
441  }
442 
443  static void Begin(const std::string &)
444  {
445  }
446 
447  static void End(const std::string &)
448  {
449  }
450 
451  void begin(const std::string &)
452  {
453  }
454 
455  void end(const std::string &)
456  {
457  }
458 
459  static void Status(std::ostream & = std::cout, bool = true)
460  {
461  }
462 
463  void status(std::ostream & = std::cout, bool = true)
464  {
465  }
466 
467  bool running(void) const
468  {
469  return false;
470  }
471 
472  static bool Running(void)
473  {
474  return false;
475  }
476 };
477 }
478 }
479 
480 #endif
481 
482 } // namespace hpp
483 
484 #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:208
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:112
boost::posix_time::ptime point
Representation of a point in time.
Definition: profile.h:77
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:246
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:181
This instance will call Profiler::start() when constructed and Profiler::stop() when it goes out of s...
Definition: profile.h:139
~ScopedStart(void)
Definition: profile.h:150
static void Average(const std::string &name, const double value)
Maintain the average of a specific value.
Definition: profile.h:217
void start(void)
Start counting time.
double seconds(const duration &d)
Return the number of seconds that a time duration represents.
Definition: profile.h:97
ScopedStart(Profiler &prof=Profiler::Instance())
Take as argument the profiler instance to operate on (prof)
Definition: profile.h:144
bool running(void) const
Check if the profiler is counting time or not.
Definition: profile.h:257
static void Stop(void)
Stop counting time.
Definition: profile.h:187
static void Clear(void)
Clear counted time and events.
Definition: profile.h:193
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:89
Profiler(bool printOnDestroy=false, bool autoStart=false)
Constructor. It is allowed to separately instantiate this class (not only as a singleton) ...
Definition: profile.h:167
ScopedBlock(const std::string &name, Profiler &prof=Profiler::Instance())
Start counting time for the block named name of the profiler prof.
Definition: profile.h:121
static void Begin(const std::string &name)
Begin counting time for a specific chunk of code.
Definition: profile.h:226
point now(void)
Get the current time point.
Definition: profile.h:83
~Profiler(void)
Destructor.
Definition: profile.h:174
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:117
boost::posix_time::time_duration duration
Representation of a time duration.
Definition: profile.h:80
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:232
~ScopedBlock(void)
Definition: profile.h:126
void begin(const std::string &name)
Begin counting time for a specific chunk of code.
#define HPP_FCL_DLLAPI
Definition: config.hh:64
static bool Running(void)
Check if the profiler is counting time or not.
Definition: profile.h:263