Proto
Proto_Timer.H
1 
2 #ifndef _PR_TIMER_H_
3 #define _PR_TIMER_H_
4 
5 #include <cstdlib>
6 #include <cstdio>
7 #include <vector>
8 #include <string>
9 #include <iostream>
10 #include "implem/Proto_ClockTicks.H"
11 #include <iostream>
12 #include <fstream>
13 #include <list>
14 #include <vector>
15 #include <cstdio>
16 #include <cstring>
17 #include <sys/time.h>
18 
19 using std::string;
20 
165 namespace Proto
166 {
167 #ifndef PR_TURN_OFF_TIMERS
168  inline double TimerGetTimeStampWC()
169  {
170 
171  struct timeval tv; // Values from call to gettimeofday
172  struct timezone tz;
173  gettimeofday(&tv, &tz);
174  return((double)tv.tv_sec + 0.000001 * (double)tv.tv_usec);
175 
176  }
177 
179  {
180  public:
181  virtual ~TraceTimer()
182  {
183  for(unsigned int i=0; i<m_children.size(); ++i)
184  {
185  delete m_children[i];
186  }
187  }
188 
189  TraceTimer()
190  {
191  m_filename = string("/dev/null");
192  }
193  inline void start(char* mutex);
194  inline unsigned long long int stop(char* mutex);
195  inline void report(bool a_closeAfter=false);
196  inline void reset();
197 
198 
199  inline void leafStart();
200  inline void leafStop();
201 
202  unsigned long long int time() const
203  {
204  return m_accumulated_WCtime;
205  }
206 
207  int rank() const
208  {
209  return m_rank;
210  }
211  long long int count() const
212  {
213  return m_count;
214  }
215 
216  void prune();
217  bool isPruned() const {return m_pruned;}
218 
219 
221  void setTimerFileName(string a_filename)
222  {
223 
224  std::vector<TraceTimer*>* troots = getRootTimerPtr();
225  (*troots)[0]->m_filename = a_filename;
226  }
227 
228  inline TraceTimer* getTimer(const char* name); // don't use
229  inline const std::vector<TraceTimer*>& children() const ;//don't use.
230 
231  inline void PruneTimersParentChildPercent(double percent);
232  inline void sampleMemUsage() ;
233 
234  inline void addFlops(long long int flops) {m_flops+=flops;}
235 
236 
237  const char* m_name;
238  mutable int m_rank;
239  int tid = 0;
240  int m_thread_id;
241  long long int m_flops;
242  long long int m_count;
243 //#pragma omp atomic
244 
245  static std::vector<TraceTimer*>* getRootTimerPtr()
246  {
247  static std::vector<TraceTimer*>* retval = new std::vector<TraceTimer*>();
248  static bool initialized = false;
249  if(!initialized)
250  {
251  std::vector<TraceTimer*>* current = getCurrentTimerPtr();
252  //this is the code from initialize
253  const char* rootName = "root";
254  TraceTimer* rootTimer = new TraceTimer(rootName, NULL, 0);
255  rootTimer->m_thread_id = 0;
256  char mutex = 0;
257 
258  retval->resize(1);
259  (*retval)[0] = rootTimer;
260 
261  (*current).resize(1);
262  (*current)[0]=rootTimer;
263 
264  (*retval)[0]->tid = 0;
265  rootTimer->start(&mutex);
266  rootTimer->zeroTime = TimerGetTimeStampWC();
267  rootTimer->zeroTicks = PR_ticks();
268  }
269  initialized = true;
270  return retval;
271  }
272 
273 
274  static std::vector<TraceTimer*>* getCurrentTimerPtr()
275  {
276  static std::vector<TraceTimer*>* retval = new std::vector<TraceTimer*>(1);
277  return retval;
278  }
279 
280 
281  //oh the evil crap we have to do to avoid static initialization
282  static void staticReport()
283  {
284  std::vector<TraceTimer*>* vecptr = getRootTimerPtr();
285  if(vecptr->size() > 0)
286  {
287  (*vecptr)[0]->report();
288  }
289  }
290 
291  //oh the evil crap we have to do to avoid static initialization
292  static void staticReset()
293  {
294  std::vector<TraceTimer*>* vecptr = getRootTimerPtr();
295  if(vecptr->size() > 0)
296  {
297  (*vecptr)[0]->reset();
298  }
299  }
300 
301  //oh the evil crap we have to do to avoid static initialization
302  static void staticPruneTimersParentChildPercent(double percent)
303  {
304  std::vector<TraceTimer*>* vecptr = getRootTimerPtr();
305  if(vecptr->size() > 0)
306  {
307  (*vecptr)[0]->PruneTimersParentChildPercent(percent);
308  }
309  }
310 
311  //oh the evil crap we have to do to avoid static initialization
312  static void staticSetTimerFileName(string a_filename)
313  {
314  std::vector<TraceTimer*>* vecptr = getRootTimerPtr();
315  if(vecptr->size() > 0)
316  {
317  (*vecptr)[0]->setTimerFileName(a_filename);
318  }
319  }
320 
321  //more evil crap
322  static int getTID()
323  {
324  int retval = -1;
325  std::vector<TraceTimer*>* vecptr = getRootTimerPtr();
326  if(vecptr->size() > 0)
327  {
328  retval = (*vecptr)[0]->tid;
329  }
330  return retval;
331  }
332 
333  //and all for the lack of a perfect reasonable language feature
334  static TraceTimer* staticGetTimer(const char* name)
335  {
336  TraceTimer* retval = NULL;
337  std::vector<TraceTimer*>* vecptr = getRootTimerPtr();
338  if(vecptr->size() > 0)
339  {
340  retval = (*vecptr)[0]->getTimer(name);
341  }
342  return retval;
343  }
344 
345  private:
346  string m_filename; //only meaningful at root
347 
348  TraceTimer(const char* a_name, TraceTimer* parent, int thread_id)
349  //:m_pruned(false), m_parent(parent), m_name(a_name), m_count(0),
350  // m_accumulated_WCtime(0),m_last_WCtime_stamp(0), m_thread_id(thread_id),
351  // m_flops(0)
352  {
353  m_pruned = false;
354  m_parent = parent;
355  m_name = a_name;
356  m_count = 0;
357  m_accumulated_WCtime = 0;
358  m_last_WCtime_stamp = 0;
359  m_thread_id = thread_id;
360  m_flops = 0;
361  }
362 
363 
364 
365  bool m_pruned;
366  TraceTimer* m_parent;
367  std::vector<TraceTimer*> m_children;
368 
369  unsigned long long int m_accumulated_WCtime;
370  unsigned long long int m_last_WCtime_stamp;
371 
372  double zeroTime = 0;
373  unsigned long long int zeroTicks = 0;
374 
375 
376 
377  void reportTree(FILE* out, const TraceTimer& node, int depth);
378  const TraceTimer* activeChild() const;
379 
380  int m_depth;
381  inline void macroTest();
382  inline void macroTest2();
383 
384  inline void currentize() const ;
385 
386  inline void reportFullTree(FILE* out, const TraceTimer& timer,
387  unsigned long long int totalTime, int depth, double secondspertick);
388  inline void reportOneTree(FILE* out, const TraceTimer& timer, double secondspertick);
389 
390 
391  inline void reset(TraceTimer& timer);
392  inline void PruneTimersParentChildPercent(double threshold, TraceTimer* parent);
393  inline void sumFlops(TraceTimer& timer);
394  };
395 
396 
398  {
399  public:
400  AutoStartLeaf(TraceTimer* a_timer):m_timer(a_timer) {if(a_timer)a_timer->leafStart();}
401  ~AutoStartLeaf(){if(m_timer)m_timer->leafStop();}
402  bool active();
403  private:
404  TraceTimer* m_timer;
405  };
406 
407  class AutoStart
408  {
409  public:
410  AutoStart(TraceTimer* a_timer, char* mutex, char* childMutex)
411  :m_mutex(mutex), m_childMutex(childMutex),m_timer(a_timer)
412  {if(a_timer)a_timer->start(mutex);}
413  AutoStart(TraceTimer* a_timer, char* mutex)
414  :m_mutex(mutex), m_childMutex((char*)(getOKPtr()) ),m_timer(a_timer)
415  {
416  if(a_timer)a_timer->start(mutex);
417  }
418  inline ~AutoStart();
419  bool active();
420  private:
421  static char* getOKPtr()
422  {
423  static bool init = false;
424  static char* retval = new char[1024];
425  if(!init)
426  {
427  sprintf(retval, "0");
428  }
429  init = true;
430  return retval;
431  }
432  char* m_mutex;
433  char* m_childMutex;
434  TraceTimer* m_timer;
435  static const char ok = 0;
436 
437  };
438 
439  inline
440  AutoStart::~AutoStart()
441  {
442 # ifndef NDEBUG
443  if(*m_childMutex == 1)
444  {
445  std::cerr<<" stop called in timer unexpectedly";
446  abort();
447  }
448 # endif
449  if(m_timer)m_timer->stop(m_mutex);
450  }
451 
452 
453  inline void TraceTimer::leafStart()
454  {
455  if(m_pruned) return;
456  ++m_count;
457  m_last_WCtime_stamp = PR_ticks();
458  }
459 
460  inline void TraceTimer::leafStop()
461  {
462  if(m_pruned) return;
463  m_accumulated_WCtime += PR_ticks() - m_last_WCtime_stamp;
464  m_last_WCtime_stamp=0;
465  }
466 #endif
467 
468 #ifdef PR_TURN_OFF_TIMERS
469 
470 #define PR_TIMER(name, tpointer)
471 #define PR_TIME(name)
472 #define PR_FLOPS(flops)
473 #define PR_TIMELEAF(name)
474 #define PR_TIMERS(name)
475 #define PR_START(tpointer)
476 #define PR_STOP(tpointer)
477 #define PR_TIMER_REPORT()
478 #define PR_TIMER_RESET()
479 #define PR_TIMER_PRUNE(threshold)
480 #define PR_TIMER_SETFILE(filename)
481 
482 #else
483 
484 #define PR_TIMER(name, tpointer) \
485  const char* TimerTag_##tpointer = name ; \
486  ::Proto::TraceTimer* tpointer = NULL ; \
487  if(::Proto::TraceTimer::getTID()==0) \
488  { \
489  tpointer = ::Proto::TraceTimer::staticGetTimer(TimerTag_##tpointer) ; \
490  }
491 
492 #define PR_TIME(name) \
493  const char* TimerTagA = name ; \
494  char PR_TimermutexA = 0; \
495  ::Proto::TraceTimer* PR_tpointer = NULL; \
496  if(::Proto::TraceTimer::getTID()==0) \
497  { \
498  PR_tpointer = ::Proto::TraceTimer::staticGetTimer(TimerTagA); \
499  } \
500  ::Proto::AutoStart autostart(PR_tpointer, &PR_TimermutexA)
501 
502 #define PR_FLOPS(flops) \
503  if(PR_tpointer)PR_tpointer->addFlops(flops);
504 
505 #define PR_TIMELEAF(name) \
506  const char* TimerTagA = name ; \
507  ::Proto::TraceTimer* PR_tpointer = NULL; \
508  if(::Proto::TraceTimer::getTID()==0) \
509  { \
510  PR_tpointer = ::Proto::TraceTimer::staticGetTimer(TimerTagA); \
511  } \
512  ::Proto::AutoStartLeaf autostart(PR_tpointer)
513 
514 #define PR_TIMERS(name) \
515  const char* TimerTagA = name ; \
516  char PR_TimermutexA = 0; \
517  char PR_Timermutex = 0; \
518  ::Proto::TraceTimer* PR_tpointer = NULL; \
519  if(::Proto::TraceTimer::getTID()==0) \
520  { \
521  PR_tpointer = ::Proto::TraceTimer::staticGetTimer(TimerTagA); \
522  } \
523  ::Proto::AutoStart autostart(PR_tpointer, &PR_TimermutexA, &PR_Timermutex)
524 
525 
526 #define PR_START(tpointer) \
527  if(::Proto::TraceTimer::getTID()==0) \
528  { \
529  tpointer->start(&PR_Timermutex); \
530 }
531 
532 #define PR_STOP(tpointer) \
533  if(::Proto::TraceTimer::getTID()==0) \
534  { \
535  tpointer->stop(&PR_Timermutex); \
536  }
537  //#define PR_STOPV(tpointer, val ) val = tpointer->stop(&PR_Timermutex)
538 
539 #define PR_TIMER_REPORT() ::Proto::TraceTimer::staticReport()
540 
541 #define PR_TIMER_RESET() ::Proto::TraceTimer::staticReset()
542 
543 #define PR_TIMER_PRUNE(threshold) ::Proto::TraceTimer::staticPruneTimersParentChildPercent(threshold)
544 
545 #define PR_TIMER_SETFILE(filename) ::Proto::TraceTimer::staticSetTimerFileName(filename);
546 #endif
547 }//namespace proto
548 
549 #include "implem/Proto_TimerImplem.H"
550 #endif // PR_TIMER_H
Definition: Proto_Timer.H:397
Definition: Proto_Timer.H:407
void setTimerFileName(string a_filename)
need to set the filename so it is not /dev/null
Definition: Proto_Timer.H:221
Definition: Proto_Box.H:11
Definition: Proto_Timer.H:178