CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/Utilities/Timing/interface/TimingReport.h

Go to the documentation of this file.
00001 #ifndef UTILITIES_TIMING_TIMINGREPORT_H
00002 #define UTILITIES_TIMING_TIMINGREPORT_H
00003 //
00004 //  V 1.1  01/09/2000
00005 //    Fast timing on Pentium
00006 //    on/off control introduced
00007 //    fixed format output
00008 //  V 1.2  21/02/2001
00009 //    cpu time added
00010 //    not thread safe yet...
00011 
00012 #include <string>
00013 #include <map>
00014 #include <iosfwd>
00015 
00016 #include "Utilities/Timing/interface/BaseEvent.h"
00017 #include "Utilities/Timing/interface/PentiumTimer.h"
00018 #include "Utilities/Timing/interface/LinuxCPUTime.h"
00019 
00020 /*  a class to manage Timing
00021 **/
00022 class TimingReport {
00023 public:
00024   typedef BaseEvent< std::pair<double,double> > ItemObserver;
00025 
00026   class Item {
00027     typedef BaseEvent< std::pair<double,double> > MyObserver;
00028   public:
00029     Item() : on(true), cpuon(true), counter(0), o(0){}
00030     Item & switchOn(bool ion) {on=ion; return *this;} 
00031     Item & switchCPU(bool ion) {cpuon=ion; return *this;} 
00032     void start() { if (on) {counter++; if (cpuon) cpuwatch.start(); stopwatch.start(); }}
00033     void stop(){ 
00034       if (on) {
00035         stopwatch.stop(); 
00036         if (cpuon) cpuwatch.stop();
00037         if (active()) return; 
00038         if (o) (*o)(std::pair<double,double>(stopwatch.lap().seconds(),
00039                                         cpuwatch.lap().seconds()));
00040       }
00041     }
00042   public:
00043     bool active() const { return stopwatch.running();}
00044     void setObs(MyObserver * io) { o=io;}
00045     double realsec() const;
00046     double realticks() const;
00047     double cpusec() const;
00048   public:
00049     bool on;
00050     bool cpuon;
00051     int counter;
00052     PentiumTimer stopwatch;
00053     LinuxCPUTimer cpuwatch;
00054     MyObserver * o;
00055 
00056   };
00057 
00058 public:
00059   static TimingReport * current();
00060 
00061 protected:
00062 
00063   typedef std::map< std::string, Item, std::less<std::string> > SMAP;
00064 
00065   TimingReport();
00066 
00067 public:
00068   ~TimingReport();
00069 
00071   void dump(std::ostream & co, bool active=false);
00072 
00074   bool & inTicks() { return inTicks_;}
00075 
00077   void switchOn(bool ion);
00078 
00080   void switchOn(const std::string& name, bool ion) {
00081     registry[name].switchOn(ion);
00082   }
00083 
00084   void start(const std::string& name) {
00085     if(on) registry[name].start();
00086   }
00087   void stop(const std::string& name) {
00088     if (on) registry[name].stop();
00089   }
00090   
00091   Item & operator[](const std::string& name) {
00092     SMAP::iterator p = registry.find(name);
00093     if (p!=registry.end()) return (*p).second;
00094     return make(name);
00095   }
00096   
00097   const Item & operator[](const std::string& name) const {
00098     SMAP::const_iterator p = registry.find(name);
00099     if (p!=registry.end()) return (*p).second;
00100     return const_cast<TimingReport*>(this)->make(name);
00101   }
00102 
00103   Item & make(const std::string& name) {
00104     return registry[name].switchOn(on);
00105   }
00106 
00107   const bool & isOn() const { return on;} 
00108 
00109 private:
00110   
00111   bool on;
00112   bool inTicks_;
00113   SMAP registry;
00114 
00115 
00116 };
00117 
00124 class TimeMe{
00125 
00126 public:
00128   explicit TimeMe(const std::string& name, bool cpu=true) :
00129     item((*TimingReport::current())[name]) {
00130     item.switchCPU(cpu);
00131     item.start();
00132   }
00133 
00134   explicit TimeMe(TimingReport::Item & iitem, bool cpu=true) :
00135     item(iitem) {
00136     item.switchCPU(cpu);
00137     item.start();
00138   }
00139 
00140   std::pair<double,double> lap() const { 
00141     return std::pair<double,double>(item.stopwatch.lap().seconds(),
00142                                item.cpuwatch.lap().seconds());
00143   }
00144  
00146   ~TimeMe() {
00147     item.stop();
00148   }
00149   
00150 private:
00151   
00152   TimingReport::Item & item;
00153   
00154 };
00155 
00156 #endif // UTILITIES_TIMING_TIMINGREPORT_H