1 #ifndef DUNE_PDELAB_COMMON_BENCHMARKHELPER_HH
2 #define DUNE_PDELAB_COMMON_BENCHMARKHELPER_HH
12 #include <dune/common/exceptions.hh>
13 #include <dune/common/ios_state.hh>
25 return static_cast<double>(std::clock()) /
static_cast<double>(CLOCKS_PER_SEC);
33 struct MPIWallTimeSource
36 double operator()()
const
72 template<
typename TimeSource = DefaultTimeSource>
76 BenchmarkHelper(std::string name, std::size_t max_runs = 1, TimeSource timeSource = TimeSource())
81 , _statistics_stale(true)
83 _run_times.
timings.resize(max_runs);
89 if (_run >= _max_runs)
91 DUNE_THROW(Dune::RangeError,
"maximum number of benchmark runs exceeded");
93 _statistics_stale =
true;
94 _run_times.
timings[_run].start = _time();
100 ios_base_all_saver ios_saver(
s);
101 s << _name <<
" (" << std::setw(2) << _run <<
" of " << std::setw(2) << _max_runs <<
") " << std::flush;
107 _run_times.
timings[_run].end = _time();
114 ios_base_all_saver ios_saver(
s);
115 s <<
" " << std::setw(10) << std::setprecision(3) << _run_times.
timings[_run-1].elapsed() <<
" sec" << std::endl;
121 std::map<std::string,BenchmarkEntry>::iterator,
125 res.first->second.timings.resize(_max_runs);
126 res.first->second.timings[_run].start = _time();
127 _statistics_stale =
true;
130 void start(std::string task, std::ostream&
s)
135 void end(std::string task)
137 _tasks[task].timings[_run].end = _time();
138 _statistics_stale =
true;
141 void end(std::string task, std::ostream&
s)
144 s <<
"." << std::flush;
149 entry.
min = std::numeric_limits<double>::max();
154 for (std::vector<Timing>::iterator it = entry.
timings.begin(),
end = entry.
timings.end();
158 const double elapsed = it->elapsed();
159 entry.
min = std::min(entry.
min,elapsed);
160 entry.
max = std::max(entry.
max,elapsed);
161 entry.
avg += elapsed;
162 entry.
std_dev += elapsed*elapsed;
173 for (std::map<std::string,BenchmarkEntry>::iterator it = _tasks.begin(),
end = _tasks.end();
177 _max_name_len = std::max(_max_name_len,it->first.size());
183 _statistics_stale =
false;
188 s << std::setw(_max_name_len + 1) << std::left << name
189 << std::right << std::scientific << std::setw(10) << std::setprecision(2);
191 for (std::vector<Timing>::const_iterator it = entry.
timings.begin(),
196 s << std::setw(10) << it->elapsed();
198 s << std::setw(10) << entry.
min
199 << std::setw(10) << entry.
max
200 << std::setw(10) << entry.
avg
201 << std::setw(10) << entry.
std_dev;
206 void print(std::ostream&
s,
bool summary_only =
false)
208 ios_base_all_saver ios_saver(
s);
210 if (_statistics_stale)
213 s << _name <<
" (" << std::setw(2) << _run <<
" of " << std::setw(2) << _max_runs <<
") runs" << std::endl;
215 s << std::setw(_max_name_len + 1) <<
"";
218 for (std::size_t i = 0; i < _max_runs; ++i)
219 s << std::setw(10) << i;
221 s << std::setw(10) <<
"min"
222 << std::setw(10) <<
"max"
223 << std::setw(10) <<
"avg"
224 << std::setw(10) <<
"std_dev" << std::endl;
226 for (std::map<std::string,BenchmarkEntry>::const_iterator it = _tasks.begin(),
end = _tasks.end();
235 const std::string _name;
238 const std::size_t _max_runs;
239 std::map<std::string,BenchmarkEntry> _tasks;
240 bool _statistics_stale;
242 std::size_t _max_name_len;
251 #endif // DUNE_PDELAB_COMMON_BENCHMARKHELPER_HH