IMP  2.0.1
The Integrative Modeling Platform
benchmark_macros.h
Go to the documentation of this file.
1 /**
2  * \file IMP/benchmark/benchmark_macros.h
3  * \brief Various general useful macros for IMP.
4  *
5  * Copyright 2007-2013 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPBENCHMARK_MACROS_H
10 #define IMPBENCHMARK_MACROS_H
11 
12 #include <IMP/benchmark/benchmark_config.h>
13 #include <IMP/base/flags.h>
14 #include <boost/timer.hpp>
15 #include <boost/scoped_ptr.hpp>
16 #include "internal/control.h"
17 #include "internal/flags.h"
18 #include <IMP/base/exception.h>
19 #include <boost/date_time/posix_time/posix_time.hpp>
20 #include <boost/date_time/posix_time/posix_time_types.hpp>
21 #include <boost/date_time/posix_time/posix_time_duration.hpp>
22 
23 #if IMP_BASE_HAS_GPERFTOOLS
24 #include <gperftools/profiler.h>
25 #endif
26 #if IMP_BASE_HAS_TCMALLOC_HEAPPROFILER
27 #include <gperftools/heap-profiler.h>
28 #endif
29 #if IMP_BASE_HAS_TCMALLOC_HEAPCHECKER
30 #include <gperftools/heap-checker.h>
31 #endif
32 
33 #define IMP_BENCHMARK_RUN \
34  ++IMP::benchmark::internal::current_benchmark; \
35  if ((IMP::benchmark::internal::run_only <0 \
36  || (IMP::benchmark::internal::run_only>=0 \
37  && IMP::benchmark::internal::run_only \
38  == IMP::benchmark::internal::current_benchmark)))
39 
40 #if IMP_BASE_HAS_GPERFTOOLS
41 #define IMP_BENCHMARK_CPU_PROFILING_BEGIN \
42  if (IMP::benchmark::internal::cpu_profile_benchmarks) { \
43  ProfilerStart(IMP::benchmark::internal::get_file_name(".pprof").c_str()); \
44  }
45 #define IMP_BENCHMARK_CPU_PROFILING_END \
46  if (IMP::benchmark::internal::cpu_profile_benchmarks) { \
47  ProfilerStop(); \
48  }
49 #else
50 #define IMP_BENCHMARK_CPU_PROFILING_BEGIN
51 #define IMP_BENCHMARK_CPU_PROFILING_END
52 #endif
53 
54 #if IMP_BASE_HAS_TCMALLOC_HEAPPROFILER
55 #define IMP_BENCHMARK_HEAP_PROFILING_BEGIN \
56  if (IMP::benchmark::internal::heap_profile_benchmarks) { \
57  HeapProfilerStart(IMP::benchmark::internal \
58  ::get_file_name(".hprof").c_str()); \
59  }
60 #define IMP_BENCHMARK_HEAP_PROFILING_END \
61  if (IMP::benchmark::internal::heap_profile_benchmarks) { \
62  HeapProfilerStop(); \
63  }
64 #else
65 #define IMP_BENCHMARK_HEAP_PROFILING_BEGIN
66 #define IMP_BENCHMARK_HEAP_PROFILING_END
67 #endif
68 
69 #if IMP_BASE_HAS_TCMALLOC_HEAPCHECKER
70 #define IMP_BENCHMARK_HEAP_CHECKING_BEGIN \
71  boost::scoped_ptr<HeapLeakChecker> heap_checker; \
72  if (IMP::benchmark::internal::heap_check_benchmarks) { \
73  heap_checker.reset(new HeapLeakChecker(IMP::benchmark \
74  ::internal::get_file_name("").c_str())); \
75  }
76 #define IMP_BENCHMARK_HEAP_CHECKING_END \
77  if (IMP::benchmark::internal::heap_check_benchmarks) { \
78  if (!heap_checker->NoLeaks()) std::cerr << "Leaks found\n"; \
79  heap_checker.reset(nullptr); \
80  }
81 #else
82 #define IMP_BENCHMARK_HEAP_CHECKING_BEGIN
83 #define IMP_BENCHMARK_HEAP_CHECKING_END
84 #endif
85 
86 #define IMP_BENCHMARK_PROFILING_BEGIN \
87  IMP_BENCHMARK_CPU_PROFILING_BEGIN \
88  IMP_BENCHMARK_HEAP_CHECKING_BEGIN \
89  IMP_BENCHMARK_HEAP_PROFILING_BEGIN
90 
91 #define IMP_BENCHMARK_PROFILING_END \
92  IMP_BENCHMARK_CPU_PROFILING_END \
93  IMP_BENCHMARK_HEAP_CHECKING_END \
94  IMP_BENCHMARK_HEAP_PROFILING_END
95 
96 
97 //! Time the given command and assign the time of one iteration to the variable
98 /** The units for the time are in seconds. See also IMP_TIME_N */
99 #define IMP_TIME(block, timev) \
100  IMP_BENCHMARK_RUN { \
101  boost::timer imp_timer; \
102  unsigned int imp_reps=0; \
103  IMP_BENCHMARK_PROFILING_BEGIN; \
104  try { \
105  do { \
106  block; \
107  ++imp_reps; \
108  } while (imp_timer.elapsed() < 2.5 && !IMP::base::run_quick_test); \
109  } catch (const IMP::base::Exception &e) { \
110  std::cerr<< "Caught exception " \
111  << e.what() << std::endl; \
112  } \
113  IMP_BENCHMARK_PROFILING_END; \
114  timev= imp_timer.elapsed()/imp_reps; \
115  } else { \
116  timev=-1; \
117  }
118 
119 //! Time the given command and assign the time of one iteration to the variable
120 /** The units for the time are in seconds. See also IMP_TIME_N */
121 #define IMP_WALLTIME(block, timev) \
122  IMP_BENCHMARK_RUN { \
123  using namespace boost::posix_time; \
124  ptime start=microsec_clock::local_time(); \
125  unsigned int imp_reps=0; \
126  IMP_BENCHMARK_PROFILING_BEGIN; \
127  try { \
128  do { \
129  block; \
130  ++imp_reps; \
131  } while (microsec_clock::local_time()-start < seconds(2) \
132  && !IMP::base::run_quick_test); \
133  } catch (const IMP::base::Exception &e) { \
134  std::cerr<< "Caught exception " \
135  << e.what() << std::endl; \
136  } \
137  IMP_BENCHMARK_PROFILING_END; \
138  timev= (microsec_clock::local_time()-start) \
139  .total_milliseconds()/1000.0 \
140  /imp_reps; \
141  } else { \
142  timev=-1; \
143  }
144 
145 //! Time the given command and assign the time of one iteration to the variable
146 /** The units for the time are in seconds. The bit of code is run
147  exact N times. See also IMP_TIME */
148 #define IMP_TIME_N(block, timev, N) \
149  IMP_BENCHMARK_RUN { \
150  boost::timer imp_timer; \
151  IMP_BENCHMARK_PROFILING_BEGIN; \
152  for (unsigned int i=0; i< (N); ++i) { \
153  try { \
154  block; \
155  } catch (const IMP::base::Exception &e) { \
156  std::cerr<< "Caught exception " \
157  << e.what() << std::endl; \
158  break; \
159  } \
160  if (IMP::base::run_quick_test) break; \
161  } \
162  IMP_BENCHMARK_PROFILING_END; \
163  timev= imp_timer.elapsed()/(N); \
164  } else { \
165  timev=-1; \
166  }
167 
168 
169 #endif /* IMPBENCHMARK_MACROS_H */