45 using clock = std::chrono::steady_clock;
49 static clock::time_point starttime(clock::now());
50 return chrono::duration<double>(clock::now() - starttime).count();
55 void wallTimer::start()
56 { start(wallTime()); }
57 void wallTimer::stop()
59 double wallTimer::acc()
const 60 {
return acc(wallTime()); }
62 int wallTimerSet::getIndex(
const string &name)
64 maptype::const_iterator it = lut.find(name);
67 timer.push_back(wallTimer());
68 lut[name]=timer.size()-1;
69 return timer.size()-1;
72 void wallTimerSet::start(
int index)
73 { timer[index].start(); }
74 void wallTimerSet::stop(
int index)
75 { timer[index].stop(); }
76 void wallTimerSet::stopstart(
int index1,
int index2)
77 {
double t=wallTime(); timer[index1].stop(t); timer[index2].start(t); }
78 void wallTimerSet::reset(
int index)
79 { timer[index].reset(); }
80 double wallTimerSet::acc(
int index)
81 {
return timer[index].acc(); }
82 void wallTimerSet::start(
const string &name)
83 { start(getIndex(name)); }
84 void wallTimerSet::stop(
const string &name)
85 { stop(getIndex(name)); }
86 void wallTimerSet::stopstart(
const string &name1,
const string &name2)
87 { stopstart(getIndex(name1),getIndex(name2)); }
88 void wallTimerSet::reset(
const string &name)
89 { reset(getIndex(name)); }
90 double wallTimerSet::acc(
const string &name)
91 {
return acc(getIndex(name)); }
93 void wallTimerSet::report()
const 95 cout <<
"\nWall clock timer report:" << endl;
96 for (maptype::const_iterator it=lut.begin(); it!=lut.end(); ++it)
97 printf(
" %-15s: %10.5fs\n", it->first.c_str(), timer[it->second].acc());
98 cout <<
"End wall clock timer report\n" << endl;
101 wallTimerSet wallTimers;
107 typedef map<string,tstack_node>::iterator Ti;
108 typedef map<string,tstack_node>::const_iterator Tci;
109 typedef pair<Tci,double> Tipair;
117 map<string,tstack_node> child;
119 tstack_node(
const string &name_, tstack_node *parent_)
120 : parent(parent_), name(name_) {}
122 int max_namelen()
const 124 int res=name.length();
125 for (Tci it=child.begin(); it!=child.end(); ++it)
126 res=max(res,it->second.max_namelen());
131 tstack_node tstack_root(
"root",0);
132 tstack_node *curnode=0;
137 bool operator() (
const Tipair &a,
const Tipair &b)
const 138 {
return a.second>b.second; }
141 void tstack_report(
const tstack_node &node,
const string &indent,
int twidth,
144 double total=node.wt.acc();
146 for (Tci it=node.child.begin(); it!=node.child.end(); ++it)
147 tmp.push_back(make_pair(it,it->second.wt.acc()));
151 sort(tmp.begin(),tmp.end(),timecomp());
153 printf(
"%s|\n", indent.c_str());
154 for (
unsigned i=0; i<tmp.size(); ++i)
156 printf(
"%s+- %-*s:%6.2f%% (%*.4fs)\n",indent.c_str(),slen,
157 (tmp[i].first->first).c_str(), 100*tmp[i].second/total,twidth,
159 tstack_report(tmp[i].first->second,indent+
"| ",twidth,slen);
162 printf(
"%s+- %-*s:%6.2f%% (%*.4fs)\n%s\n",indent.c_str(),slen,
163 "<unaccounted>",100*(total-tsum)/total,twidth,total-tsum,indent.c_str());
169 void tstack_push(
const string &name)
171 double t0=wallTime();
172 if (curnode==0) curnode=&tstack_root;
173 Ti it=curnode->child.find(name);
174 if (it==curnode->child.end())
175 it=curnode->child.insert (make_pair(name,tstack_node(name,curnode))).first;
176 curnode=&(it->second);
177 double t1=wallTime();
178 curnode->wt.start(0.5*(t0+t1));
181 void tstack_pop(
const string &name)
183 double t0=wallTime();
184 planck_assert(curnode && (curnode->name==name),
"invalid tstack operation");
185 double t1=wallTime();
186 curnode->wt.stop(0.5*(t0+t1));
187 curnode=curnode->parent;
192 double t0=wallTime();
194 double t1=wallTime();
195 curnode->wt.stop(0.5*(t0+t1));
196 curnode=curnode->parent;
199 void tstack_replace(
const string &name2)
201 double t0=wallTime();
203 tstack_node *savenode=curnode;
204 curnode=curnode->parent;
205 Ti it=curnode->child.find(name2);
206 if (it==curnode->child.end())
207 it=curnode->child.insert(make_pair(name2,tstack_node(name2,curnode))).first;
208 curnode=&(it->second);
209 double t1=wallTime();
210 double t=0.5*(t0+t1);
211 savenode->wt.stop(t);
212 curnode->wt.start(t);
215 void tstack_replace(
const string &name1,
const string &name2)
217 planck_assert(curnode && (curnode->name==name1),
"invalid tstack operation");
218 tstack_replace(name2);
221 void tstack_report(
const string &stem)
223 const tstack_node *ptr = 0;
224 for (Tci it=tstack_root.child.begin(); it!=tstack_root.child.end(); ++it)
225 if (it->first==stem) ptr=&(it->second);
227 int slen=string(
"<unaccounted>").size();
228 slen = max(slen,ptr->max_namelen());
230 double total=ptr->wt.acc();
231 printf(
"\nTotal wall clock time for '%s': %1.4fs\n",stem.c_str(),total);
233 int logtime=max(1,
int(log10(total)+1));
234 tstack_report(*ptr,
"",logtime+5,slen);
236 printf(
"\nAccumulated timing overhead: approx. %1.4fs\n",overhead);
#define planck_assert(testval, msg)