1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
| #ifndef TimingREPORT_H
#define TimingREPORT_H
//
//
//
// V 1.1 01/09/2000
// Fast timing on Pentium
// on/off control introduced
// fixed format output
// V 1.2 21/02/2001
// cpu time added
// not thread safe yet...
#include <string>
#ifndef CMS_NO_HASH_MAP
#include <hash_map>
#include "Utilities/GenUtil/interface/stringhash.h"
#else
#include <map>
#endif
#include<iosfwd>
#include "Utilities/Notification/interface/BaseEvent.h"
#include "CommonDet/BasicDet/interface/AlignmentPositionError.h"
#include "Utilities/GenUtil/interface/CMSTimers.h"
/* a class to manage Timing
**/
class TimingReport {
public:
typedef BaseEvent< std::pair<double,double> > ItemObserver;
class Item {
typedef BaseEvent< std::pair<double,double> > MyObserver;
public:
Item() : on(true), cpuon(true), counter(0), o(0){}
Item & switchOn(bool ion) {on=ion; return *this;}
Item & switchCPU(bool ion) {cpuon=ion; return *this;}
void start() { if (on) {counter++; if (cpuon) cpuwatch.start(); stopwatch.start(); }}
void stop(){
if (on) {
stopwatch.stop();
if (cpuon) cpuwatch.stop();
if (active()) return;
if (o) (*o)(std::pair<double,double>(stopwatch.lap().seconds(),
cpuwatch.lap().seconds()));
}
}
public:
bool active() const { return stopwatch.running();}
void setObs(MyObserver * io) { o=io;}
double realsec() const;
double realticks() const;
double cpusec() const;
public:
bool on;
bool cpuon;
int counter;
StopWatch stopwatch;
CPUWatch cpuwatch;
MyObserver * o;
};
public:
static TimingReport * current();
protected:
#ifndef CMS_NO_HASH_MAP
typedef hash_map< std::string, Item, hash<std::string>, std::equal_to<std::string> > SMAP;
#else
typedef std::map< std::string, Item, std::less<std::string> > SMAP;
#endif
TimingReport();
public:
~TimingReport();
///
void dump(std::ostream & co, bool active=false);
/// report in ticks
bool & inTicks() { return inTicks_;}
/// switch all on
void switchOn(bool ion);
/// switch one ion
void switchOn(const std::string& name, bool ion) {
registry[name].switchOn(ion);
}
void start(const std::string& name) {
if(on) registry[name].start();
}
void stop(const std::string& name) {
if (on) registry[name].stop();
}
Item & operator[](const std::string& name) {
SMAP::iterator p = registry.find(name);
if (p!=registry.end()) return (*p).second;
return make(name);
}
const Item & operator[](const std::string& name) const {
SMAP::const_iterator p = registry.find(name);
if (p!=registry.end()) return (*p).second;
return const_cast<TimingReport*>(this)->make(name);
}
Item & make(const std::string& name) {
return registry[name].switchOn(on);
}
const bool & isOn() const { return on;}
private:
bool on;
bool inTicks_;
SMAP registry;
};
/** a class to time a "scope" to be used as a "Sentry".
Just create a TimeMe object giving it a name;
exiting the scope the object will be deleted;
the constuctor starts the timing.
the destructor stops it.
*/
class TimeMe{
public:
///
explicit TimeMe(const std::string& name, bool cpu=true) :
item((*TimingReport::current())[name]) {
item.switchCPU(cpu);
item.start();
}
explicit TimeMe(TimingReport::Item & iitem, bool cpu=true) :
item(iitem) {
item.switchCPU(cpu);
item.start();
}
std::pair<double,double> lap() const {
return std::pair<double,double>(item.stopwatch.lap().seconds(),
item.cpuwatch.lap().seconds());
}
///
~TimeMe() {
item.stop();
}
private:
TimingReport::Item & item;
};
#endif |
Partager