00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011 #ifndef _CH_TIMER_H_
00012 #define _CH_TIMER_H_
00013
00014 #ifdef CH_AIX
00015 #define FOUR_COUNTERS
00016 #endif
00017
00018 #include <cstdio>
00019 #include "REAL.H"
00020 #include "MayDay.H"
00021 #include "Vector.H"
00022 #include "ClockTicks.H"
00023 #ifdef CH_MPI
00024 #include "mpi.h"
00025 #endif
00026
00027
00028 #ifndef CH_NTIMER
00029
00030 extern "C" {
00031
00032 #include <unistd.h>
00033 #include <sys/time.h>
00034
00035
00036
00037
00038 #ifdef PAPI
00039 #include <papi.h>
00040 #endif
00041 }
00042
00043
00044 #ifndef TIMER_COUNTER
00045 #define TIMER_COUNTER 0
00046 #endif
00047
00048 #include <list>
00049 #include <string>
00050 #include "List.H"
00051
00052 #include <string>
00053 #include <iostream>
00054 #include "BaseNamespaceHeader.H"
00055
00056 using namespace std;
00057
00058
00073 class OldTimer {
00074
00075 public:
00076
00077
00078
00080 OldTimer();
00082 OldTimer(const string& a_name, const int a_tableID);
00083 OldTimer(const string& a_name, OldTimer&, const int a_tableID);
00084 OldTimer(const string& a_name, OldTimer&);
00085 OldTimer(const string& a_name, OldTimer&, const int a_tableID, bool);
00086
00087 ~OldTimer();
00088
00089 void setup();
00090 void start();
00091 void stop();
00092 void stop(Real& wc1);
00093 void clear();
00094
00095 inline double getTimeStampWC();
00096 double wc_time() { return m_accumulated_WCtime; }
00097 double mflops();
00098 void writeTotalPct(const string& a_extra = "");
00099
00100 #ifdef PAPI
00101 long long int papi_counter0() { return m_accumulated_counter0; }
00102 long long int papi_counter1() { return m_accumulated_counter1; }
00103 double total_papi_counter0() { return m_totalPapiCounter0; }
00104 double total_papi_counter1() { return m_totalPapiCounter1; }
00105 #ifdef FOUR_COUNTERS
00106 long long int papi_counter2() { return m_accumulated_counter2; }
00107 long long int papi_counter3() { return m_accumulated_counter3; }
00108 double total_papi_counter2() { return m_totalPapiCounter2; }
00109 double total_papi_counter3() { return m_totalPapiCounter3; }
00110 #endif
00111 #endif
00112
00113 string Name() { return m_name; }
00114 long long int Count() { return m_count; }
00115 int tableID() { return m_tableID; }
00116
00117 static list<OldTimer*> *TimerList;
00118
00119 static void TimerSummary(const int bert, const int ernie) {
00120 TimerSummary();
00121 }
00122
00123 static void TimerInit(const int rank);
00124 static void TimerSummary(void);
00125 static void TimerSummaryWithTITAfiles(void);
00126
00127 private:
00128
00129
00130 static void TimerSummary_(const int itita);
00131 static void writeParentTables(FILE *out, const double TimerCost);
00132 static void writeDiagnosticTables(FILE *out, const double TimerCost);
00133
00134
00135 int m_tableID;
00136
00137 double m_accumulated_WCtime, m_last_WCtime_stamp;
00138
00139
00140 #ifndef CH_MPI
00141 struct timeval tv;
00142 struct timezone tz;
00143 #endif
00144
00145 int m_ID;
00146 string m_name;
00147 bool m_diagnostic;
00148 OldTimer& m_Parent;
00149
00150
00151 bool m_evenCountAcrossRanks;
00152 double m_avgWC, m_minWC, m_maxWC, m_avgCount;
00153
00154 #ifdef PAPI
00155 long long int m_accumulated_counter0;
00156 long long int m_accumulated_counter1;
00157 long long int m_previous_counter0;
00158 long long int m_previous_counter1;
00159 double m_totalPapiCounter0;
00160 double m_totalPapiCounter1;
00161 #ifdef FOUR_COUNTERS
00162 long long int m_values[4];
00163 long long int m_accumulated_counter2;
00164 long long int m_accumulated_counter3;
00165 long long int m_previous_counter2;
00166 long long int m_previous_counter3;
00167 double m_totalPapiCounter2;
00168 double m_totalPapiCounter3;
00169 #else
00170 long long int m_values[2];
00171 #endif
00172 #endif
00173
00174 long long int m_count;
00175 long long int m_totalCount;
00176 };
00177
00178 #else // CH_NTIMER
00179
00180
00181 using namespace std;
00182
00183 class OldTimer {
00184
00185 public:
00186
00187 OldTimer(){}
00188 OldTimer(const string&, const int){}
00189 OldTimer(const string&, OldTimer&, const int){}
00190 OldTimer(const string&, OldTimer&){}
00191 OldTimer(const string&, OldTimer&, const int, bool){}
00192
00193 ~OldTimer(){}
00194
00195 void setup(){}
00196 void start(){}
00197 void stop(){}
00198 void stop(Real& wc1){}
00199 void clear(){}
00200
00201 inline double getTimeStampWC(){return 0.0;}
00202 double wc_time() {return 0.0;}
00203 double mflops();
00204 void writeTotalPct(const string& a_extra = "");
00205
00206 #ifdef PAPI
00207 long long int papi_counter0() {return 0;}
00208 long long int papi_counter1() {return 0;}
00209 double total_papi_counter0() {return 0.0;}
00210 double total_papi_counter1() {return 0.0;}
00211 #ifdef FOUR_COUNTERS
00212 long long int papi_counter2() {return 0;}
00213 long long int papi_counter3() {return 0;}
00214 double total_papi_counter2() {return 0.0;}
00215 double total_papi_counter3() {return 0.0;}
00216 #endif
00217 #endif
00218
00219 string Name() { return NULL; }
00220 long long int Count() { return 0; }
00221 int tableID() { return 0; }
00222
00223 static void TimerSummary(const int bert, const int ernie) {
00224 TimerSummary();
00225 }
00226
00227 static void TimerInit(const int rank){}
00228 static void TimerSummary(void){}
00229 static void TimerSummaryWithTITAfiles(void){};
00230
00231 private:
00232
00233
00234 static void TimerSummary_(const int itita){}
00235 static void writeParentTables(FILE *out, const double TimerCost){}
00236 static void writeDiagnosticTables(FILE *out, const double TimerCost){}
00237 };
00238
00239 #endif // CH_NTIMER
00240
00241 #ifdef CH_NTIMER
00242
00243 #define CH_TIMER(name, tpointer) (void)0
00244 #define CH_TIME(name) (void)0
00245 #define CH_TIMELEAF(name) (void)0
00246 #define CH_TIMERS(name) (void)0
00247 #define CH_START(tpointer) (void)0
00248 #define CH_STOP(tpointer) (void)0
00249 #define CH_STOPV(tpointer, val) (void)0
00250 #define CH_TIMER_REPORT() (void)0
00251 #define CH_TIMER_RESET() (void)0
00252 #define CH_TIMER_PRUNE(threshold) (void)0
00253
00254 #else // CH_NTIMER
00255
00256
00257 #define CH_TIMER(name, tpointer) \
00258 const char* TimerTag_##tpointer = name ; \
00259 CH_XD::TraceTimer* tpointer = CH_XD::TraceTimer::getTimer(TimerTag_##tpointer)
00260
00261 #define CH_TIME(name) \
00262 const char* TimerTagA = name ; \
00263 char CH_TimermutexA = 0; \
00264 CH_XD::TraceTimer* ch_tpointer = CH_XD::TraceTimer::getTimer(TimerTagA); \
00265 CH_XD::AutoStart autostart(ch_tpointer, &CH_TimermutexA)
00266
00267 #define CH_TIMELEAF(name) \
00268 const char* TimerTagA = name ; \
00269 CH_XD::TraceTimer* ch_tpointer = CH_XD::TraceTimer::getTimer(TimerTagA); \
00270 CH_XD::AutoStartLeaf autostart(ch_tpointer)
00271
00272 #define CH_TIMERS(name) \
00273 const char* TimerTagA = name ; \
00274 char CH_TimermutexA = 0; \
00275 char CH_Timermutex = 0; \
00276 CH_XD::TraceTimer* ch_tpointer = CH_XD::TraceTimer::getTimer(TimerTagA); \
00277 CH_XD::AutoStart autostart(ch_tpointer, &CH_TimermutexA, &CH_Timermutex)
00278
00279
00280 #define CH_START(tpointer) tpointer->start(&CH_Timermutex)
00281
00282 #define CH_STOP(tpointer) tpointer->stop(&CH_Timermutex)
00283 #define CH_STOPV(tpointer, val ) val = tpointer->stop(&CH_Timermutex)
00284
00285 #define CH_TIMER_REPORT() CH_XD::TraceTimer::report()
00286
00287 #define CH_TIMER_RESET() CH_XD::TraceTimer::reset()
00288
00289 #define CH_TIMER_PRUNE(threshold) CH_XD::TraceTimer::PruneTimersParentChildPercent(threshold)
00290
00291 #endif // CH_NTIMER
00292
00293
00434 class TraceTimer
00435 {
00436 public:
00437 virtual ~TraceTimer();
00438 void start(char* mutex);
00439 unsigned long long int stop(char* mutex);
00440 static void report(bool a_closeAfter=false);
00441 static void reset();
00442
00443
00444 void leafStart();
00445 void leafStop();
00446
00447 unsigned long long int time() const
00448 {
00449 return m_accumulated_WCtime;
00450 }
00451
00452 int rank() const
00453 {
00454 return m_rank;
00455 }
00456 long long int count() const
00457 {
00458 return m_count;
00459 }
00460
00461 void prune();
00462 bool isPruned() const {return m_pruned;}
00463
00464 static int initializer();
00465 static TraceTimer* getTimer(const char* name);
00466 const std::vector<TraceTimer*>& children() const ;
00467
00468 static void PruneTimersParentChildPercent(double percent);
00469 static void sampleMemUsage() ;
00470
00471 static const char* currentTimer()
00472 {
00473 return s_currentTimer[0]->m_name;
00474 }
00475
00476 private:
00477 TraceTimer(const char* a_name, TraceTimer* parent, int thread_id);
00478 static std::vector<TraceTimer*> s_roots;
00479 static std::vector<TraceTimer*> s_currentTimer;
00480 static bool s_traceMemory;
00481 static long long int s_peak;
00482 static TraceTimer* s_peakTimer;
00483
00484 bool m_pruned;
00485 TraceTimer* m_parent;
00486 std::vector<TraceTimer*> m_children;
00487 const char* m_name;
00488 long long int m_count;
00489 unsigned long long int m_accumulated_WCtime;
00490 unsigned long long int m_last_WCtime_stamp;
00491 mutable int m_rank;
00492 int m_thread_id;
00493 long long int m_memory;
00494 long long int m_last_Memory_Stamp;
00495 long long int m_peak;
00496
00497 void reportTree(FILE* out, const TraceTimer& node, int depth);
00498 const TraceTimer* activeChild() const;
00499
00500 void macroTest();
00501 void macroTest2();
00502
00503 void currentize() const ;
00504 int computeRank() const;
00505 static void reportFullTree(FILE* out, const TraceTimer& timer,
00506 unsigned long long int totalTime, int depth);
00507 static void reportOneTree(FILE* out, const TraceTimer& timer);
00508 static void reportMemoryOneTree(FILE* out, const TraceTimer& timer);
00509 static void subReport(FILE* out, const char* header, unsigned long long int totalTime);
00510 static void reset(TraceTimer& timer);
00511 static void PruneTimersParentChildPercent(double threshold, TraceTimer* parent);
00512
00513 };
00514
00515
00516 class AutoStartLeaf
00517 {
00518 public:
00519 AutoStartLeaf(TraceTimer* a_timer):m_timer(a_timer) {a_timer->leafStart();}
00520 ~AutoStartLeaf(){m_timer->leafStop();}
00521 bool active();
00522 private:
00523 TraceTimer* m_timer;
00524 };
00525
00526 class AutoStart
00527 {
00528 public:
00529 AutoStart(TraceTimer* a_timer, char* mutex, char* childMutex)
00530 :m_mutex(mutex), m_childMutex(childMutex),m_timer(a_timer)
00531 {a_timer->start(mutex);}
00532 AutoStart(TraceTimer* a_timer, char* mutex)
00533 :m_mutex(mutex), m_childMutex(&AutoStart::ok),m_timer(a_timer)
00534 {a_timer->start(mutex);}
00535 inline ~AutoStart();
00536 bool active();
00537 private:
00538 char* m_mutex;
00539 char* m_childMutex;
00540 TraceTimer* m_timer;
00541 static char ok;
00542
00543 };
00544
00545 inline
00546 AutoStart::~AutoStart()
00547 {
00548 # ifndef NDEBUG
00549 if(*m_childMutex == 1)
00550 MayDay::Error("Child timer still running on function exit");
00551 # endif
00552 m_timer->stop(m_mutex);
00553 }
00554
00555 inline double TimerGetTimeStampWC(){
00556
00557
00558
00559
00560 #ifndef CH_NTIMER
00561 struct timeval tv;
00562 struct timezone tz;
00563 gettimeofday(&tv, &tz);
00564 return((double)tv.tv_sec + 0.000001 * (double)tv.tv_usec);
00565 #else
00566 return 0;
00567 #endif
00568 }
00569
00570 inline void TraceTimer::leafStart()
00571 {
00572 if(m_pruned) return;
00573 ++m_count;
00574 m_last_WCtime_stamp = ch_ticks();
00575 }
00576
00577 inline void TraceTimer::leafStop()
00578 {
00579 if(m_pruned) return;
00580 m_accumulated_WCtime += ch_ticks() - m_last_WCtime_stamp;
00581 m_last_WCtime_stamp=0;
00582 }
00583
00584
00585
00586 #ifndef CH_NTIMER
00587 #include "BaseNamespaceFooter.H"
00588 #endif
00589 #endif // CH_TIMER_H