perf_log.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 #ifndef LIBMESH_PERFLOG_H
21 #define LIBMESH_PERFLOG_H
22 
23 
24 // Local includes
25 #include "libmesh/libmesh_common.h"
26 
27 // C++ includes
28 #include <cstddef>
29 #include <map>
30 #include <stack>
31 #include <string>
32 #include <vector>
33 #include <sys/time.h>
34 
35 namespace libMesh
36 {
37 
43 // ------------------------------------------------------------
44 // PerfData class definition
45 class PerfData
46 {
47  public:
48 
52  PerfData () :
53  tot_time(0.),
55  tstart(),
57  count(0),
58  open(false),
60  {}
61 
62 
66  double tot_time;
67 
72 
77  struct timeval tstart;
78 
83  struct timeval tstart_incl_sub;
84 
89  unsigned int count;
90 
96  bool open;
97 
98  void start ();
99  void restart ();
100  double pause ();
101  double stopit ();
102 
104 
105  protected:
106  double stop_or_pause(const bool do_stop);
107 };
108 
109 
110 
111 
121 // ------------------------------------------------------------
122 // PerfLog class definition
123 class PerfLog
124 {
125 
126  public:
127 
135  PerfLog(const std::string& label_name="",
136  const bool log_events=true);
137 
141  ~PerfLog();
142 
150  void clear();
151 
155  void disable_logging() { log_events = false; }
156 
160  void enable_logging() { log_events = true; }
161 
165  bool logging_enabled() const { return log_events; }
166 
170  void push (const std::string &label,
171  const std::string &header="");
172 
176  void pop (const std::string &label,
177  const std::string &header="");
178 
182  void start_event(const std::string &label,
183  const std::string &header="");
184 
188  void stop_event(const std::string &label,
189  const std::string &header="");
190 
194  void pause_event(const std::string &label,
195  const std::string &header="");
196 
200  void restart_event(const std::string &label,
201  const std::string &header="");
202 
208  std::string get_log() const;
209 
213  std::string get_info_header() const;
214 
218  std::string get_perf_info() const;
219 
223  void print_log() const;
224 
228  double get_elapsed_time() const;
229 
233  double get_active_time() const;
234 
238  PerfData get_perf_data(const std::string &label, const std::string &header="");
239 
240  private:
241 
242 
246  const std::string label_name;
247 
252 
256  double total_time;
257 
261  struct timeval tstart;
262 
266  std::map<std::pair<std::string,
267  std::string>,
269 
273  std::stack<PerfData*> log_stack;
274 
280  static bool called;
281 
286  void split_on_whitespace(const std::string& input,
287  std::vector<std::string>& output) const;
288 };
289 
290 
291 
292 // ------------------------------------------------------------
293 // PerfData class member funcions
294 inline
296 {
297  this->count++;
298  this->called_recursively++;
299  gettimeofday (&(this->tstart), NULL);
300  this->tstart_incl_sub = this->tstart;
301 }
302 
303 
304 
305 inline
307 {
308  gettimeofday (&(this->tstart), NULL);
309 }
310 
311 
312 
313 inline
315 {
316  return this->stop_or_pause(false);
317 }
318 
319 
320 inline
321 double PerfData::stop_or_pause(const bool do_stop)
322 {
323  // save the start times, reuse the structure we have rather than create
324  // a new one.
325  const time_t
326  tstart_tv_sec = this->tstart.tv_sec,
327  tstart_tv_usec = this->tstart.tv_usec;
328 
329  gettimeofday (&(this->tstart), NULL);
330 
331  const double elapsed_time = (static_cast<double>(this->tstart.tv_sec - tstart_tv_sec) +
332  static_cast<double>(this->tstart.tv_usec - tstart_tv_usec)*1.e-6);
333 
334  this->tot_time += elapsed_time;
335 
336  if(do_stop)
337  {
338  const double elapsed_time_incl_sub = (static_cast<double>(this->tstart.tv_sec - this->tstart_incl_sub.tv_sec) +
339  static_cast<double>(this->tstart.tv_usec - this->tstart_incl_sub.tv_usec)*1.e-6);
340 
341  this->tot_time_incl_sub += elapsed_time_incl_sub;
342  }
343 
344  return elapsed_time;
345 }
346 
347 
348 
349 inline
351 {
352  // stopit is just similar to pause except that it decrements the
353  // recursive call counter
354 
355  this->called_recursively--;
356  return this->stop_or_pause(true);
357 }
358 
359 
360 
361 // ------------------------------------------------------------
362 // PerfLog class inline member funcions
363 inline
364 void PerfLog::push (const std::string &label,
365  const std::string &header)
366 {
367  if (this->log_events)
368  {
369  // Get a reference to the event data to avoid
370  // repeated map lookups
371  PerfData *perf_data = &(log[std::make_pair(header,label)]);
372 
373  if (!log_stack.empty())
374  total_time +=
375  log_stack.top()->pause();
376 
377  perf_data->start();
378  log_stack.push(perf_data);
379  }
380 }
381 
382 
383 
384 inline
385 void PerfLog::pop (const std::string &libmesh_dbg_var(label),
386  const std::string &libmesh_dbg_var(header))
387 {
388  if (this->log_events)
389  {
390  libmesh_assert (!log_stack.empty());
391 
392 #ifndef NDEBUG
393  PerfData *perf_data = &(log[std::make_pair(header,label)]);
394  if (perf_data != log_stack.top())
395  {
396  libMesh::err << "PerfLog can't pop (" << header << ',' << label << ')' << std::endl;
397  libMesh::err << "From top of stack of running logs:" << std::endl;
398  std::map<std::pair<std::string, std::string>, PerfData>::iterator
399  i = log.begin(), endi = log.end();
400  for (; i != endi; ++i)
401  if (&(i->second) == log_stack.top())
402  libMesh::err << '(' << i->first.first << ',' << i->first.second << ')' << std::endl;
403 
404  libmesh_assert_equal_to (perf_data, log_stack.top());
405  }
406 #endif
407 
408  total_time += log_stack.top()->stopit();
409 
410  log_stack.pop();
411 
412  if (!log_stack.empty())
413  log_stack.top()->restart();
414  }
415 }
416 
417 
418 
419 inline
421 {
422  struct timeval tnow;
423 
424  gettimeofday (&tnow, NULL);
425 
426  const double elapsed_time = (static_cast<double>(tnow.tv_sec - tstart.tv_sec) +
427  static_cast<double>(tnow.tv_usec - tstart.tv_usec)*1.e-6);
428  return elapsed_time;
429 }
430 
431 inline
433 {
434  return total_time;
435 }
436 
437 } // namespace libMesh
438 
439 
440 
441 #endif // LIBMESH_PERFLOG_H

Site Created By: libMesh Developers
Last modified: February 07 2014 16:57:06 UTC

Hosted By:
SourceForge.net Logo