libMesh
perf_log.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 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 #include "libmesh/perf_log.h"
19 
20 // Local includes
21 #include "libmesh/int_range.h"
22 #include "libmesh/timestamp.h"
23 
24 // C++ includes
25 #include <algorithm>
26 #include <iostream>
27 #include <iomanip>
28 #include <cstring>
29 #include <ctime>
30 #include <unistd.h>
31 #include <sys/types.h>
32 #include <vector>
33 #include <sstream>
34 
35 #ifdef LIBMESH_HAVE_SYS_UTSNAME_H
36 #include <sys/utsname.h>
37 #endif
38 
39 #ifdef LIBMESH_HAVE_PWD_H
40 #include <pwd.h>
41 #endif
42 
43 namespace libMesh
44 {
45 
46 
47 // ------------------------------------------------------------
48 // PerfLog class member functions
49 
50 bool PerfLog::called = false;
51 
52 
53 PerfLog::PerfLog(const std::string & ln,
54  const bool le) :
55  label_name(ln),
56  log_events(le),
57  total_time(0.)
58 {
59  gettimeofday (&tstart, nullptr);
60 
61  if (log_events)
62  this->clear();
63 }
64 
65 
66 
68 {
69  if (log_events)
70  this->print_log();
71 
72  for (const auto & pos : non_temporary_strings)
73  delete [] pos.second;
74 }
75 
76 
77 
79 {
80  if (log_events)
81  {
82  // check that all events are closed
83  for (auto pos : log)
84  if (pos.second.open)
85  libmesh_error_msg("ERROR clearing performance log for class " \
86  << label_name \
87  << "\nevent " \
88  << pos.first.second \
89  << " is still being monitored!");
90 
91  gettimeofday (&tstart, nullptr);
92 
93  log.clear();
94 
95  while (!log_stack.empty())
96  log_stack.pop();
97  }
98 }
99 
100 
101 
102 void PerfLog::push (const std::string & label,
103  const std::string & header)
104 {
105  const char * label_c_str;
106  const char * header_c_str;
107  if (non_temporary_strings.count(label))
108  label_c_str = non_temporary_strings[label];
109  else
110  {
111  char * newcopy = new char [label.size()+1];
112  strcpy(newcopy, label.c_str());
113  label_c_str = newcopy;
114  non_temporary_strings[label] = label_c_str;
115  }
116 
117  if (non_temporary_strings.count(header))
118  header_c_str = non_temporary_strings[header];
119  else
120  {
121  char * newcopy = new char [header.size()+1];
122  strcpy(newcopy, header.c_str());
123  header_c_str = newcopy;
124  non_temporary_strings[header] = header_c_str;
125  }
126 
127  if (this->log_events)
128  this->fast_push(label_c_str, header_c_str);
129 }
130 
131 
132 
133 void PerfLog::push (const char * label,
134  const char * header)
135 {
136  this->push(std::string(label), std::string(header));
137 }
138 
139 
140 
141 
142 
143 void PerfLog::pop (const std::string & label,
144  const std::string & header)
145 {
146 
147  const char * label_c_str = non_temporary_strings[label];
148  const char * header_c_str = non_temporary_strings[header];
149 
150  // This could happen if users are *mixing* string and char* APIs for
151  // the same label/header combination. For perfect backwards
152  // compatibility we should handle that, but there's just no fast way
153  // to do so.
154  libmesh_assert(label_c_str);
155  libmesh_assert(header_c_str);
156 
157  if (this->log_events)
158  this->fast_pop(label_c_str, header_c_str);
159 }
160 
161 
162 
163 void PerfLog::pop (const char * label,
164  const char * header)
165 {
166  this->pop(std::string(label), std::string(header));
167 }
168 
169 
170 
171 std::string PerfLog::get_info_header() const
172 {
173  std::ostringstream oss;
174 
175  if (log_events)
176  {
177  std::string date = Utility::get_timestamp();
178 
179 #ifdef LIBMESH_HAVE_SYS_UTSNAME_H
180  // Get system information
181  struct utsname sysInfo;
182  uname(&sysInfo);
183 #endif
184 
185  // Get user information
186  //
187  // Some systems, for example Crays, actually have getpwuid on the head-node
188  // but (if I understand correctly) a dynamically-linked glibc is not available
189  // on the backend, which is running a reduced operating system like Compute
190  // Node Linux. Thus functions like getpwuid cannot be called. This makes
191  // automatically testing for the existence of getpwuid on the login node
192  // difficult. The configure test would work on the login node but will fail
193  // on the backend. Hence we have added a configure flag, --disable-getpwuid,
194  // to manually turn this off.
195 #ifdef LIBMESH_HAVE_GETPWUID
196  struct passwd * p = getpwuid(getuid());
197 #endif
198  oss << "\n";
199 
200  // Construct string stream objects for each of the outputs
201  std::ostringstream
202  pid_stream,
203  nprocs_stream,
204  time_stream,
205  os_stream,
206  host_stream,
207  osrel_stream,
208  osver_stream,
209  machine_stream,
210  user_stream;
211 
212 
213  // Put pointers to these streams in a vector
214  std::vector<std::ostringstream*> v;
215  v.push_back(&pid_stream);
216  v.push_back(&nprocs_stream);
217  v.push_back(&time_stream);
218  v.push_back(&os_stream);
219  v.push_back(&host_stream);
220  v.push_back(&osrel_stream);
221  v.push_back(&osver_stream);
222  v.push_back(&machine_stream);
223  v.push_back(&user_stream);
224 
225  // Fill string stream objects
227  {
228  pid_stream << "| Processor id: " << libMesh::global_processor_id();
229  nprocs_stream << "| Num Processors: " << libMesh::global_n_processors();
230  }
231 
232  time_stream << "| Time: ";
233  os_stream << "| OS: ";
234  host_stream << "| HostName: ";
235  osrel_stream << "| OS Release: ";
236  osver_stream << "| OS Version: ";
237  machine_stream << "| Machine: ";
238 
239  time_stream << date;
240 #ifdef LIBMESH_HAVE_SYS_UTSNAME_H
241  os_stream << sysInfo.sysname ;
242  host_stream << sysInfo.nodename ;
243  osrel_stream << sysInfo.release ;
244  osver_stream << sysInfo.version ;
245  machine_stream << sysInfo.machine ;
246 #else
247  os_stream << "Unknown";
248  host_stream << "Unknown";
249  osrel_stream << "Unknown";
250  osver_stream << "Unknown";
251  machine_stream << "Unknown";
252 
253 #endif
254  user_stream << "| Username: ";
255 #ifdef LIBMESH_HAVE_GETPWUID
256  if (p && p->pw_name)
257  user_stream << p->pw_name;
258  else
259 #endif
260  user_stream << "Unknown";
261 
262  // Parse the LIBMESH_CONFIGURE_INFO string literal before using it in PerfLog output
263  std::string libmesh_configure_info(LIBMESH_CONFIGURE_INFO);
264  std::vector<std::string> parsed_libmesh_configure_info;
265  this->split_on_whitespace(libmesh_configure_info,
266  parsed_libmesh_configure_info);
267 
268  // There should always be at at least one entry in
269  // parsed_libmesh_configure_info, even if the user just ran
270  // ../configure.
271  libmesh_assert_greater (parsed_libmesh_configure_info.size(), 0);
272 
273  // Find the longest string in all the streams
274  unsigned int max_length = 0;
275  for (auto & v_i : v)
276  if (v_i->str().size() > max_length)
277  max_length = cast_int<unsigned int>
278  (v_i->str().size());
279 
280  // Find the longest string in the parsed_libmesh_configure_info
281  for (auto & plci_i : parsed_libmesh_configure_info)
282  if (plci_i.size() > max_length)
283  max_length = cast_int<unsigned int> (plci_i.size());
284 
285  // Print dashed line for the header
286  oss << ' '
287  << std::string(max_length+1, '-')
288  << '\n';
289 
290  // Loop over all the strings and add end formatting
291  for (auto & v_i : v)
292  {
293  if (v_i->str().size())
294  oss << v_i->str()
295  << std::setw (cast_int<int>
296  (max_length + 4 - v_i->str().size()))
297  << std::right
298  << "|\n";
299  }
300 
301  // Print out configuration header plus first parsed string. The
302  // magic number 18 below accounts for the length of the word
303  // 'Configuration'.
304  oss << "| Configuration: "
305  << parsed_libmesh_configure_info[0]
306  << std::setw (cast_int<int>
307  (max_length + 4 -
308  parsed_libmesh_configure_info[0].size() - 18))
309  << std::right
310  << "|\n";
311 
312  // Loop over the parsed_libmesh_configure_info and add end formatting. The magic
313  // number 3 below accounts for the leading 'pipe' character and indentation
314  for (auto i : IntRange<std::size_t>(1, parsed_libmesh_configure_info.size()))
315  {
316  oss << "| "
317  << parsed_libmesh_configure_info[i]
318  << std::setw (cast_int<int>
319  (max_length + 4 -
320  parsed_libmesh_configure_info[i].size() - 3))
321  << std::right
322  << "|\n";
323  }
324 
325 
326  // Print dashed line
327  oss << ' '
328  << std::string(max_length+1, '-')
329  << '\n';
330  }
331 
332  return oss.str();
333 }
334 
335 
336 
337 
338 std::string PerfLog::get_perf_info() const
339 {
340  std::ostringstream oss;
341 
342  if (log_events && !log.empty())
343  {
344  // Stop timing for this event.
345  struct timeval tstop;
346 
347  gettimeofday (&tstop, nullptr);
348 
349  const double elapsed_time = (static_cast<double>(tstop.tv_sec - tstart.tv_sec) +
350  static_cast<double>(tstop.tv_usec - tstart.tv_usec)*1.e-6);
351 
352  // Figure out the formatting required based on the event names
353  // Unsigned ints for each of the column widths
354  unsigned int event_col_width = 30;
355  const unsigned int ncalls_col_width = 11;
356  const unsigned int tot_time_col_width = 12;
357  const unsigned int avg_time_col_width = 12;
358  const unsigned int tot_time_incl_sub_col_width = 12;
359  const unsigned int avg_time_incl_sub_col_width = 12;
360  const unsigned int pct_active_col_width = 9;
361  const unsigned int pct_active_incl_sub_col_width = 9;
362 
363  // Reset the event column width based on the longest event name plus
364  // a possible 2-character indentation, plus a space.
365  for (auto pos : log)
366  if (std::strlen(pos.first.second)+3 > event_col_width)
367  event_col_width = cast_int<unsigned int>
368  (std::strlen(pos.first.second)+3);
369 
370  // Set the total width of the column
371  const unsigned int total_col_width =
372  event_col_width +
373  ncalls_col_width +
374  tot_time_col_width +
375  avg_time_col_width +
376  tot_time_incl_sub_col_width +
377  avg_time_incl_sub_col_width +
378  pct_active_col_width+
379  pct_active_incl_sub_col_width+1;
380 
381  // Print dashed line
382  oss << ' '
383  << std::string(total_col_width, '-')
384  << '\n';
385 
386  {
387  // Construct temporary message string
388  std::ostringstream temp;
389  temp << "| " << label_name << " Performance: Alive time=" << elapsed_time
390  << ", Active time=" << total_time;
391 
392  // Get the size of the temporary string
393  const unsigned int temp_size = cast_int<unsigned int>
394  (temp.str().size());
395 
396  // Send the temporary message to the output
397  oss << temp.str();
398 
399  // If this string is longer than the previously computed total
400  // column width, skip the additional formatting... this shouldn't
401  // happen often, hopefully. Add two additional characters for a
402  // space and a "|" character at the end.
403  if (temp_size < total_col_width+2)
404  oss << std::setw(total_col_width - temp_size + 2)
405  << std::right
406  << "|";
407 
408  oss << '\n';
409  }
410 
411  // Print dashed line
412  oss << ' '
413  << std::string(total_col_width, '-')
414  << '\n';
415 
416 
417  // Write out the header for the events listing
418  oss << "| "
419  << std::setw(event_col_width)
420  << std::left
421  << "Event"
422  << std::setw(ncalls_col_width)
423  << std::left
424  << "nCalls"
425  << std::setw(tot_time_col_width)
426  << std::left
427  << "Total Time"
428  << std::setw(avg_time_col_width)
429  << std::left
430  << "Avg Time"
431  << std::setw(tot_time_incl_sub_col_width)
432  << std::left
433  << "Total Time"
434  << std::setw(avg_time_incl_sub_col_width)
435  << std::left
436  << "Avg Time"
437  << std::setw(pct_active_col_width+pct_active_incl_sub_col_width)
438  << std::left
439  << "% of Active Time"
440  << "|\n"
441  << "| "
442  << std::setw(event_col_width)
443  << std::left
444  << ""
445  << std::setw(ncalls_col_width)
446  << std::left
447  << ""
448  << std::setw(tot_time_col_width)
449  << std::left
450  << "w/o Sub"
451  << std::setw(avg_time_col_width)
452  << std::left
453  << "w/o Sub"
454  << std::setw(tot_time_incl_sub_col_width)
455  << std::left
456  << "With Sub"
457  << std::setw(avg_time_incl_sub_col_width)
458  << std::left
459  << "With Sub"
460  << std::setw(pct_active_col_width)
461  << std::left
462  << "w/o S"
463  << std::setw(pct_active_incl_sub_col_width)
464  << std::left
465  << "With S"
466  << "|\n|"
467  << std::string(total_col_width, '-')
468  << "|\n|"
469  << std::string(total_col_width, ' ')
470  << "|\n";
471 
472  unsigned int summed_function_calls = 0;
473  double summed_total_time = 0;
474  double summed_percentage = 0;
475 
476  std::string last_header("");
477 
478  // Make a new log to sort entries alphabetically
479  std::map<std::pair<std::string, std::string>, PerfData> string_log;
480 
481  for (auto char_data : log)
482  string_log[std::make_pair(char_data.first.first,
483  char_data.first.second)] =
484  char_data.second;
485 
486  for (auto pos : string_log)
487  {
488  const PerfData & perf_data = pos.second;
489 
490  // Only print the event if the count is non-zero.
491  if (perf_data.count != 0)
492  {
493  const unsigned int perf_count = perf_data.count;
494  const double perf_time = perf_data.tot_time;
495  const double perf_avg_time = perf_time / static_cast<double>(perf_count);
496  const double perf_time_incl_sub = perf_data.tot_time_incl_sub;
497  const double perf_avg_time_incl_sub = perf_time_incl_sub / static_cast<double>(perf_count);
498  const double perf_percent = (total_time != 0.) ? perf_time / total_time * 100. : 0.;
499  const double perf_percent_incl_sub = (total_time != 0.) ? perf_time_incl_sub / total_time * 100. : 0.;
500 
501  summed_function_calls += perf_count;
502  summed_total_time += perf_time;
503  summed_percentage += perf_percent;
504 
505  // Print the event name
506  if (pos.first.first == "")
507  oss << "| "
508  << std::setw(event_col_width)
509  << std::left
510  << pos.first.second;
511 
512  else
513  {
514  if (last_header != pos.first.first)
515  {
516  last_header = pos.first.first;
517 
518  // print blank line followed by header name
519  // (account for additional space before the
520  // header)
521  oss << "|"
522  << std::string(total_col_width, ' ')
523  << "|\n| "
524  << std::setw(total_col_width-1)
525  << std::left
526  << pos.first.first
527  << "|\n";
528  }
529 
530  oss << "| "
531  << std::setw(event_col_width-2)
532  << std::left
533  << pos.first.second;
534  }
535 
536 
537  // Print the number of calls to the event.
538  oss << std::setw(ncalls_col_width)
539  << perf_count;
540 
541  // Save the original stream flags
542  std::ios_base::fmtflags out_flags = oss.flags();
543 
544  // Print the total time spent in the event
545  oss << std::fixed
546  << std::setprecision(4)
547  << std::setw(tot_time_col_width)
548  << std::left
549  << perf_time;
550 
551 
552  // Print the average time per function call
553  oss << std::fixed
554  << std::setprecision(6)
555  << std::setw(avg_time_col_width)
556  << std::left
557  << perf_avg_time;
558 
559  // Print the total time spent in the event incl. sub-events
560  oss << std::fixed
561  << std::setprecision(4)
562  << std::setw(tot_time_incl_sub_col_width)
563  << std::left
564  << perf_time_incl_sub;
565 
566  // Print the average time per function call incl. sub-events
567  oss << std::fixed
568  << std::setprecision(6)
569  << std::setw(avg_time_incl_sub_col_width)
570  << std::left
571  << perf_avg_time_incl_sub;
572 
573  // Print the percentage of the time spent in the event
574  oss << std::fixed
575  << std::setprecision(2)
576  << std::setw(pct_active_col_width)
577  << std::left
578  << perf_percent;
579 
580  // Print the percentage of the time spent in the event incl. sub-events
581  oss << std::fixed
582  << std::setprecision(2)
583  << std::setw(pct_active_incl_sub_col_width)
584  << std::left
585  << perf_percent_incl_sub;
586 
587  // Reset the stream flags
588  oss.flags(out_flags);
589 
590  oss << "|\n";
591  }
592  }
593 
594  oss << ' '
595  << std::string(total_col_width, '-')
596  << "\n| "
597  << std::setw(event_col_width)
598  << std::left
599  << "Totals:";
600 
601  // Print the total number of logged function calls
602  // For routines which are called many times, summed_function_calls may
603  // exceed 7 digits. If this happens use, scientific notation.
604  if (summed_function_calls < 9999999)
605  oss << std::setw(ncalls_col_width)
606  << summed_function_calls;
607 
608  else
609  {
610  // Save the original stream flags
611  std::ios_base::fmtflags out_flags = oss.flags();
612 
613  oss << std::scientific
614  << std::setprecision(3)
615  << std::setw(ncalls_col_width)
616  << std::left
617  << static_cast<Real>(summed_function_calls);
618 
619  // Reset the stream flags
620  oss.flags(out_flags);
621  }
622 
623  // Print the total time spent in logged function calls. Don't bother saving/restoring
624  // the flags here since we are almost done with this stream anyway...
625  oss << std::fixed
626  << std::setprecision(4)
627  << std::setw(tot_time_col_width)
628  << std::left
629  << summed_total_time;
630 
631  // Null, the average time doesn't make sense as a total
632  oss << std::setw(avg_time_col_width) << "";
633 
634  // Same for times that include sub-events
635  oss << std::setw(tot_time_incl_sub_col_width)
636  << ""
637  << std::setw(avg_time_incl_sub_col_width)
638  << "";
639 
640  // Print the total percentage followed by dashed line
641  oss << std::fixed
642  << std::setprecision(2)
643  << std::setw(pct_active_col_width)
644  << std::left
645  << summed_percentage
646  << std::setw(pct_active_incl_sub_col_width)
647  << ""
648  << "|\n "
649  << std::string(total_col_width, '-')
650  << '\n';
651  }
652 
653  return oss.str();
654 }
655 
656 
657 
658 std::string PerfLog::get_log() const
659 {
660  std::ostringstream oss;
661 
662  if (log_events)
663  {
664  // Only print the log
665  // if it isn't empty
666  if (!log.empty())
667  {
668  // Possibly print machine info,
669  // but only do this once
670  if (!called)
671  {
672  called = true;
673  oss << get_info_header();
674  }
675  oss << get_perf_info();
676  }
677  }
678 
679  return oss.str();
680 }
681 
682 
683 
684 void PerfLog::print_log() const
685 {
686  if (log_events)
687  {
688  // Check to see if the log_string is empty, and if so,
689  // avoid printing an unnecessary newline.
690  std::string log_string = this->get_log();
691  if (log_string.size() > 0)
692  libMesh::out << log_string << std::endl;
693  }
694 }
695 
696 PerfData PerfLog::get_perf_data(const std::string & label, const std::string & header)
697 {
698  if (non_temporary_strings.count(label) &&
699  non_temporary_strings.count(header))
700  {
701  const char * label_c_str = non_temporary_strings[label];
702  const char * header_c_str = non_temporary_strings[header];
703  return log[std::make_pair(header_c_str, label_c_str)];
704  }
705 
706  auto iter = std::find_if
707  (log.begin(), log.end(),
708  [&label, &header] (log_type::const_reference a)
709  {
710  return
711  !std::strcmp(header.c_str(), a.first.first) &&
712  !std::strcmp(label.c_str(), a.first.second);
713  });
714 
715  libmesh_assert(iter != log.end());
716 
717  return iter->second;
718 }
719 
720 void PerfLog::start_event(const std::string & label,
721  const std::string & header)
722 {
723  this->push(label,header);
724 }
725 
726 
727 
728 void PerfLog::stop_event(const std::string & label,
729  const std::string & header)
730 {
731  this->pop(label,header);
732 }
733 
734 
735 
736 void PerfLog::pause_event(const std::string &,
737  const std::string &)
738 {
739  // nothing to do. pushing the next object on the stack will handle it
740 }
741 
742 
743 
744 void PerfLog::restart_event(const std::string &,
745  const std::string &)
746 {
747  // nothing to do. popping the top off the stack will handle it.
748 }
749 
750 
751 
752 void PerfLog::split_on_whitespace(const std::string & input, std::vector<std::string> & output) const
753 {
754  // Check for easy return
755  if (input.size()==0)
756  return;
757 
758  // Here we hard-code the string to split on, since the algorithm below
759  // is somewhat specific to it...
760  const std::string split_on("' '");
761 
762  size_t current_pos = 0;
763  while (true)
764  {
765  // Find next end location
766  size_t end_pos = input.find(split_on, current_pos);
767 
768  if (end_pos != std::string::npos)
769  {
770  // Create substring. Note: the second argument to substr is
771  // the *length* of string to create, not the ending position!
772  output.push_back( input.substr(current_pos, end_pos - current_pos + 1) );
773 
774  // Update search starting position, make sure to go past the end of the split_on string, but
775  // include the previous single quote (hence the -1).
776  current_pos = end_pos + split_on.size() - 1;
777  }
778  else
779  {
780  // Push back whatever remains of the string onto the output.
781  // Note that substr with only 1 argument pushes back
782  // whatever remains of the string. This also handles the
783  // case where the string does not contain any matches.
784  output.push_back( input.substr(current_pos) );
785 
786  // We are done searching the string, so break out of the while loop
787  break;
788  }
789  }
790 }
791 
792 } // namespace libMesh
libMesh::PerfLog::split_on_whitespace
void split_on_whitespace(const std::string &input, std::vector< std::string > &output) const
Splits a string on whitespace into a vector of separate strings.
Definition: perf_log.C:752
libMesh::PerfData
The PerfData class simply contains the performance data that is recorded for individual events.
Definition: perf_log.h:46
libMesh::global_n_processors
processor_id_type global_n_processors()
Definition: libmesh_base.h:75
libMesh::PerfLog::fast_push
void fast_push(const char *label, const char *header="")
Push the event label onto the stack, pausing any active event.
Definition: perf_log.h:466
libMesh::PerfLog::clear
void clear()
Clears all the internal data and restores the data structures to a pristine state.
Definition: perf_log.C:78
libMesh::PerfLog::print_log
void print_log() const
Print the log.
Definition: perf_log.C:684
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::PerfLog::get_perf_data
PerfData get_perf_data(const std::string &label, const std::string &header="")
Return the PerfData object associated with a label and header.
Definition: perf_log.C:696
libMesh::PerfLog::get_log
std::string get_log() const
Definition: perf_log.C:658
libMesh::PerfLog::stop_event
void stop_event(const std::string &label, const std::string &header="")
Stop monitoring the event named label.
Definition: perf_log.C:728
libMesh::PerfLog::log_events
bool log_events
Flag to optionally disable all logging.
Definition: perf_log.h:323
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::IntRange
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
Definition: int_range.h:53
libMesh::PerfLog::get_info_header
std::string get_info_header() const
Definition: perf_log.C:171
libMesh::PerfLog::log
log_type log
The actual log.
Definition: perf_log.h:342
libMesh::PerfLog::pop
void pop(const char *label, const char *header="")
Pop the event label off the stack, resuming any lower event.
Definition: perf_log.C:163
libMesh::PerfLog::PerfLog
PerfLog(const std::string &label_name="", const bool log_events=true)
Constructor.
Definition: perf_log.C:53
libMesh::PerfLog::pause_event
void pause_event(const std::string &label, const std::string &header="")
Suspend monitoring of the event.
Definition: perf_log.C:736
libMesh::PerfLog::fast_pop
void fast_pop(const char *label, const char *header="")
Pop the event label off the stack, resuming any lower event.
Definition: perf_log.h:486
libMesh::PerfLog::~PerfLog
~PerfLog()
Destructor.
Definition: perf_log.C:67
libMesh::PerfLog::tstart
struct timeval tstart
The time we were constructed or last cleared.
Definition: perf_log.h:333
libMesh::PerfLog::log_stack
std::stack< PerfData * > log_stack
A stack to hold the current performance log trace.
Definition: perf_log.h:347
libMesh::PerfLog::get_perf_info
std::string get_perf_info() const
Definition: perf_log.C:338
libMesh::PerfData::tot_time
double tot_time
Total time spent in this event.
Definition: perf_log.h:67
libMesh::Utility::get_timestamp
std::string get_timestamp()
Definition: timestamp.C:37
libMesh::PerfData::count
unsigned int count
The number of times this event has been executed.
Definition: perf_log.h:90
libMesh::PerfLog::called
static bool called
Flag indicating if print_log() has been called.
Definition: perf_log.h:354
libMesh::PerfLog::push
void push(const char *label, const char *header="")
Push the event label onto the stack, pausing any active event.
Definition: perf_log.C:133
libMesh::PerfLog::label_name
const std::string label_name
The label for this object.
Definition: perf_log.h:318
libMesh::PerfLog::restart_event
void restart_event(const std::string &label, const std::string &header="")
Restart monitoring the event.
Definition: perf_log.C:744
libMesh::out
OStreamProxy out
libMesh::global_processor_id
processor_id_type global_processor_id()
Definition: libmesh_base.h:85
libMesh::PerfLog::total_time
double total_time
The total running time for recorded events.
Definition: perf_log.h:328
libMesh::PerfData::tot_time_incl_sub
double tot_time_incl_sub
Total time spent in this event, including sub-events.
Definition: perf_log.h:72
libMesh::PerfLog::start_event
void start_event(const std::string &label, const std::string &header="")
Start monitoring the event named label.
Definition: perf_log.C:720
libMesh::PerfLog::non_temporary_strings
std::map< std::string, const char * > non_temporary_strings
Workaround to give us fixed pointers to character arrays for every string.
Definition: perf_log.h:371