perf_log.h
Go to the documentation of this file.00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2012 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 00003 00004 // This library is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public 00006 // License as published by the Free Software Foundation; either 00007 // version 2.1 of the License, or (at your option) any later version. 00008 00009 // This library is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // Lesser General Public License for more details. 00013 00014 // You should have received a copy of the GNU Lesser General Public 00015 // License along with this library; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 00019 00020 #ifndef LIBMESH_PERFLOG_H 00021 #define LIBMESH_PERFLOG_H 00022 00023 00024 // Local includes 00025 #include "libmesh/libmesh_common.h" 00026 00027 // C++ includes 00028 #include <cstddef> 00029 #include <map> 00030 #include <stack> 00031 #include <string> 00032 #include <vector> 00033 #include <sys/time.h> 00034 00035 namespace libMesh 00036 { 00037 00043 // ------------------------------------------------------------ 00044 // PerfData class definition 00045 class PerfData 00046 { 00047 public: 00048 00052 PerfData () : 00053 tot_time(0.), 00054 tot_time_incl_sub(0.), 00055 tstart(), 00056 tstart_incl_sub(), 00057 count(0), 00058 open(false), 00059 called_recursively(0) 00060 {} 00061 00062 00066 double tot_time; 00067 00071 double tot_time_incl_sub; 00072 00077 struct timeval tstart; 00078 00083 struct timeval tstart_incl_sub; 00084 00089 unsigned int count; 00090 00096 bool open; 00097 00098 void start (); 00099 void restart (); 00100 double pause (); 00101 double stopit (); 00102 00103 int called_recursively; 00104 00105 protected: 00106 double stop_or_pause(const bool do_stop); 00107 }; 00108 00109 00110 00111 00121 // ------------------------------------------------------------ 00122 // PerfLog class definition 00123 class PerfLog 00124 { 00125 00126 public: 00127 00135 PerfLog(const std::string& label_name="", 00136 const bool log_events=true); 00137 00141 ~PerfLog(); 00142 00150 void clear(); 00151 00155 void disable_logging() { log_events = false; } 00156 00160 void enable_logging() { log_events = true; } 00161 00165 bool logging_enabled() const { return log_events; } 00166 00170 void push (const std::string &label, 00171 const std::string &header=""); 00172 00176 void pop (const std::string &label, 00177 const std::string &header=""); 00178 00182 void start_event(const std::string &label, 00183 const std::string &header=""); 00184 00188 void stop_event(const std::string &label, 00189 const std::string &header=""); 00190 00194 void pause_event(const std::string &label, 00195 const std::string &header=""); 00196 00200 void restart_event(const std::string &label, 00201 const std::string &header=""); 00202 00208 std::string get_log() const; 00209 00213 std::string get_info_header() const; 00214 00218 std::string get_perf_info() const; 00219 00223 void print_log() const; 00224 00228 double get_elapsed_time() const; 00229 00230 00231 private: 00232 00233 00237 const std::string label_name; 00238 00242 bool log_events; 00243 00247 double total_time; 00248 00252 struct timeval tstart; 00253 00257 std::map<std::pair<std::string, 00258 std::string>, 00259 PerfData> log; 00260 00264 std::stack<PerfData*> log_stack; 00265 00271 static bool called; 00272 00277 void split_on_whitespace(const std::string& input, 00278 std::vector<std::string>& output) const; 00279 }; 00280 00281 00282 00283 // ------------------------------------------------------------ 00284 // PerfData class member funcions 00285 inline 00286 void PerfData::start () 00287 { 00288 this->count++; 00289 this->called_recursively++; 00290 gettimeofday (&(this->tstart), NULL); 00291 this->tstart_incl_sub = this->tstart; 00292 } 00293 00294 00295 00296 inline 00297 void PerfData::restart () 00298 { 00299 gettimeofday (&(this->tstart), NULL); 00300 } 00301 00302 00303 00304 inline 00305 double PerfData::pause () 00306 { 00307 return this->stop_or_pause(false); 00308 } 00309 00310 00311 inline 00312 double PerfData::stop_or_pause(const bool do_stop) 00313 { 00314 // save the start times, reuse the structure we have rather than create 00315 // a new one. 00316 const time_t 00317 tstart_tv_sec = this->tstart.tv_sec, 00318 tstart_tv_usec = this->tstart.tv_usec; 00319 00320 gettimeofday (&(this->tstart), NULL); 00321 00322 const double elapsed_time = (static_cast<double>(this->tstart.tv_sec - tstart_tv_sec) + 00323 static_cast<double>(this->tstart.tv_usec - tstart_tv_usec)*1.e-6); 00324 00325 this->tot_time += elapsed_time; 00326 00327 if(do_stop) 00328 { 00329 const double elapsed_time_incl_sub = (static_cast<double>(this->tstart.tv_sec - this->tstart_incl_sub.tv_sec) + 00330 static_cast<double>(this->tstart.tv_usec - this->tstart_incl_sub.tv_usec)*1.e-6); 00331 00332 this->tot_time_incl_sub += elapsed_time_incl_sub; 00333 } 00334 00335 return elapsed_time; 00336 } 00337 00338 00339 00340 inline 00341 double PerfData::stopit () 00342 { 00343 // stopit is just similar to pause except that it decrements the 00344 // recursive call counter 00345 00346 this->called_recursively--; 00347 return this->stop_or_pause(true); 00348 } 00349 00350 00351 00352 // ------------------------------------------------------------ 00353 // PerfLog class inline member funcions 00354 inline 00355 void PerfLog::push (const std::string &label, 00356 const std::string &header) 00357 { 00358 if (this->log_events) 00359 { 00360 // Get a reference to the event data to avoid 00361 // repeated map lookups 00362 PerfData *perf_data = &(log[std::make_pair(header,label)]); 00363 00364 if (!log_stack.empty()) 00365 total_time += 00366 log_stack.top()->pause(); 00367 00368 perf_data->start(); 00369 log_stack.push(perf_data); 00370 } 00371 } 00372 00373 00374 00375 inline 00376 void PerfLog::pop (const std::string &libmesh_dbg_var(label), 00377 const std::string &libmesh_dbg_var(header)) 00378 { 00379 if (this->log_events) 00380 { 00381 libmesh_assert (!log_stack.empty()); 00382 00383 #ifndef NDEBUG 00384 PerfData *perf_data = &(log[std::make_pair(header,label)]); 00385 if (perf_data != log_stack.top()) 00386 { 00387 std::cerr << "PerfLog can't pop (" << header << ',' << label << ')' << std::endl; 00388 std::cerr << "From top of stack of running logs:" << std::endl; 00389 std::map<std::pair<std::string, std::string>, PerfData>::iterator 00390 i = log.begin(), endi = log.end(); 00391 for (; i != endi; ++i) 00392 if (&(i->second) == log_stack.top()) 00393 std::cerr << '(' << i->first.first << ',' << i->first.second << ')' << std::endl; 00394 00395 libmesh_assert_equal_to (perf_data, log_stack.top()); 00396 } 00397 #endif 00398 00399 total_time += log_stack.top()->stopit(); 00400 00401 log_stack.pop(); 00402 00403 if (!log_stack.empty()) 00404 log_stack.top()->restart(); 00405 } 00406 } 00407 00408 00409 00410 inline 00411 double PerfLog::get_elapsed_time () const 00412 { 00413 struct timeval tnow; 00414 00415 gettimeofday (&tnow, NULL); 00416 00417 const double elapsed_time = (static_cast<double>(tnow.tv_sec - tstart.tv_sec) + 00418 static_cast<double>(tnow.tv_usec - tstart.tv_usec)*1.e-6); 00419 return elapsed_time; 00420 } 00421 00422 00423 } // namespace libMesh 00424 00425 00426 00427 #endif // LIBMESH_PERFLOG_H
Site Created By: libMesh Developers
Last modified: February 05 2013 19:54:48 UTC
Hosted By: