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 #include <cstdio>
00015 #include "REAL.H"
00016 #include "MayDay.H"
00017 #include "Vector.H"
00018 #include "ClockTicks.H"
00019 #include "CH_Counters.H"
00020
00021
00022 #ifdef CH_MPI
00023 #include "mpi.h"
00024 #endif
00025
00026 #ifdef _OPENMP
00027 #include "CH_Thread.H"
00028 #endif
00029
00030
00031 #include <list>
00032 #include <string>
00033 #include "List.H"
00034
00035 #include <string>
00036 #include <iostream>
00037
00038 #include "BaseNamespaceHeader.H"
00039
00040 using namespace std;
00041
00042 #ifdef CH_NTIMER
00043
00044 #define CH_TIMERS_ON() false
00045 #define CH_TIMER(name, tpointer) (void)0
00046 #define CH_TIME(name) (void)0
00047 #define CH_TIMELEAF(name) (void)0
00048 #define CH_TIMERS(name) (void)0
00049 #define CH_START(tpointer) (void)0
00050 #define CH_STOP(tpointer) (void)0
00051
00052 #define CH_TIMER_REPORT() (void)0
00053 #define CH_TIMER_REPORTNAME(stream, name) (void)0
00054 #define CH_TIMER_RESET() (void)0
00055 #define CH_TIMER_PRUNE(threshold) (void)0
00056
00057 #else // CH_NTIMER
00058
00059 extern std::fstream LBFILE;
00060
00061 #define CH_TIMERS_ON() TraceTimer::timersOn()
00062
00063 #define CH_TIMER(name, tpointer) \
00064 const char* TimerTag_##tpointer = name ; \
00065 CH_XD::TraceTimer* tpointer = NULL ;\
00066 if(TIMERS_tid==0) \
00067 { \
00068 tpointer = CH_XD::TraceTimer::getTimer(TimerTag_##tpointer) ; \
00069 }
00070 #ifdef _OPENMP
00071 #define CH_TIME(name) \
00072 const char* TimerTagA = name ; \
00073 char CH_TimermutexA = 0; \
00074 CH_XD::TraceTimer* ch_tpointer = NULL; \
00075 int tid=omp_get_thread_num(); \
00076 if(tid == 0) \
00077 { \
00078 ch_tpointer = CH_XD::TraceTimer::getTimer(TimerTagA); \
00079 } \
00080 CH_XD::AutoStart autostart(ch_tpointer, &CH_TimermutexA)
00081 #else
00082 #define CH_TIME(name) \
00083 const char* TimerTagA = name ; \
00084 char CH_TimermutexA = 0; \
00085 CH_XD::TraceTimer* ch_tpointer = NULL; \
00086 ch_tpointer = CH_XD::TraceTimer::getTimer(TimerTagA); \
00087 CH_XD::AutoStart autostart(ch_tpointer, &CH_TimermutexA)
00088 #endif
00089
00090 #ifdef _OPENMP
00091 #define CH_TIMELEAF(name) \
00092 const char* TimerTagA = name ; \
00093 CH_XD::TraceTimer* ch_tpointer = NULL; \
00094 int tid = omp_get_thread_num(); if(tid==0) \
00095 { \
00096 ch_tpointer = CH_XD::TraceTimer::getTimer(TimerTagA); \
00097 } \
00098 CH_XD::AutoStartLeaf autostart(ch_tpointer)
00099 #else
00100 #define CH_TIMELEAF(name) \
00101 const char* TimerTagA = name ; \
00102 CH_XD::TraceTimer* ch_tpointer = NULL; \
00103 ch_tpointer = CH_XD::TraceTimer::getTimer(TimerTagA); \
00104 CH_XD::AutoStartLeaf autostart(ch_tpointer)
00105 #endif
00106
00107 #ifdef _OPENMP
00108 #define CH_TIMERS(name) \
00109 const char* TimerTagA = name ; \
00110 char CH_TimermutexA = 0; \
00111 char CH_Timermutex = 0; \
00112 CH_XD::TraceTimer* ch_tpointer = NULL; \
00113 int TIMERS_tid = omp_get_thread_num(); if(TIMERS_tid==0) \
00114 { \
00115 ch_tpointer = CH_XD::TraceTimer::getTimer(TimerTagA); \
00116 } \
00117 CH_XD::AutoStart autostart(ch_tpointer, &CH_TimermutexA, &CH_Timermutex)
00118
00119
00120 #define CH_START(tpointer) \
00121 if(TIMERS_tid==0) \
00122 { \
00123 tpointer->start(&CH_Timermutex); \
00124 }
00125
00126 #define CH_STOP(tpointer) \
00127 if(TIMERS_tid==0) \
00128 { \
00129 tpointer->stop(&CH_Timermutex); \
00130 }
00131
00132 #else
00133 #define CH_TIMERS(name) \
00134 const char* TimerTagA = name ; \
00135 char CH_TimermutexA = 0; \
00136 char CH_Timermutex = 0; \
00137 CH_XD::TraceTimer* ch_tpointer = NULL; \
00138 int TIMERS_tid=0; \
00139 { \
00140 ch_tpointer = CH_XD::TraceTimer::getTimer(TimerTagA); \
00141 } \
00142 CH_XD::AutoStart autostart(ch_tpointer, &CH_TimermutexA, &CH_Timermutex)
00143
00144
00145 #define CH_START(tpointer) \
00146 { \
00147 tpointer->start(&CH_Timermutex); \
00148 }
00149
00150 #define CH_STOP(tpointer) \
00151 { \
00152 tpointer->stop(&CH_Timermutex); \
00153 }
00154
00155 #endif
00156
00157
00158 #define CH_TIMER_REPORT() CH_XD::TraceTimer::report()
00159
00160 #define CH_TIMER_REPORTNAME(stream, name) CH_XD::TraceTimer::reportName(stream, name);
00161 #define CH_TIMER_RESET() CH_XD::TraceTimer::reset()
00162
00163 #define CH_TIMER_PRUNE(threshold) CH_XD::TraceTimer::PruneTimersParentChildPercent(threshold)
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 class TraceTimer
00307 {
00308 public:
00309 virtual ~TraceTimer();
00310 void start(char* mutex);
00311 unsigned long long int stop(char* mutex);
00312 static void report(bool a_closeAfter=false);
00313 static void reportName(std::ostream& out, const char* name);
00314 static void reset();
00315
00316 void leafStart();
00317 void leafStop();
00318
00319 unsigned long long int time() const
00320 {
00321 return m_accumulated_WCtime;
00322 }
00323
00324 int rank() const
00325 {
00326 return m_rank;
00327 }
00328 long long int count() const
00329 {
00330 return m_count;
00331 }
00332
00333 void prune();
00334 bool isPruned() const
00335 {
00336 return m_pruned;
00337 }
00338
00339 static int initializer();
00340 static TraceTimer* getTimer(const char* name);
00341 const std::vector<TraceTimer*>& children() const ;
00342
00343 static void PruneTimersParentChildPercent(double percent);
00344 static void sampleMemUsage(const char* a_name) ;
00345 static void sampleMemUsage2() ;
00346 static void reportPeak(FILE* out);
00347
00348 static const char* currentTimer()
00349 {
00350 return s_currentTimer[0]->m_name;
00351 }
00352
00353 static bool timersOn();
00354
00355 private:
00356 TraceTimer(const char* a_name, TraceTimer* parent, int thread_id);
00357 static std::vector<TraceTimer*> s_roots;
00358 static std::vector<TraceTimer*> s_currentTimer;
00359
00360 static long long int s_peak;
00361 static TraceTimer* s_peakTimer;
00362
00363 bool m_pruned;
00364 TraceTimer* m_parent;
00365 std::vector<TraceTimer*> m_children;
00366 const char* m_name;
00367 long long int m_count;
00368 unsigned long long int m_accumulated_WCtime;
00369 unsigned long long int m_last_WCtime_stamp;
00370 mutable int m_rank;
00371 int m_thread_id;
00372 static bool s_memorySampling;
00373 unsigned int m_memoryMin, m_memoryMax;
00374 unsigned long long int m_flopEnter, m_flops;
00375
00376 static bool s_tracing;
00377
00378 static bool find(std::list<const TraceTimer*>& a_trace, const TraceTimer* a_target);
00379 void reportTree(FILE* out, const TraceTimer& node, int depth);
00380 const TraceTimer* activeChild() const;
00381
00382 void macroTest();
00383 void macroTest2();
00384
00385 void currentize() const ;
00386 int computeRank() const;
00387 static void reportFullTree(FILE* out, const TraceTimer& timer,
00388 unsigned long long int totalTime, int depth, TraceTimer** stack_bottom);
00389 static void reportOneTree(FILE* out, const TraceTimer& timer);
00390 static void updateMemory(TraceTimer& a_timer);
00391
00392
00393 static void subReport(FILE* out, const char* header, unsigned long long int totalTime);
00394 static void reset(TraceTimer& timer);
00395 static void PruneTimersParentChildPercent(double threshold, TraceTimer* parent);
00396
00397 };
00398
00399 class AutoStartLeaf
00400 {
00401 public:
00402 AutoStartLeaf(TraceTimer* a_timer):m_timer(a_timer)
00403 {
00404 if(a_timer)a_timer->leafStart();
00405 }
00406
00407 ~AutoStartLeaf()
00408 {
00409 if(m_timer)m_timer->leafStop();
00410 }
00411
00412 bool active();
00413
00414 private:
00415 TraceTimer* m_timer;
00416 };
00417
00418 class AutoStart
00419 {
00420 public:
00421 AutoStart(TraceTimer* a_timer, char* mutex, char* childMutex)
00422 :m_mutex(mutex), m_childMutex(childMutex),m_timer(a_timer)
00423 {if(a_timer)a_timer->start(mutex);}
00424 AutoStart(TraceTimer* a_timer, char* mutex)
00425 :m_mutex(mutex), m_childMutex(&AutoStart::ok),m_timer(a_timer)
00426 {if(a_timer)a_timer->start(mutex);}
00427 ~AutoStart()
00428 { if(m_timer)m_timer->stop(m_mutex); }
00429
00430 bool active();
00431 private:
00432 char* m_mutex;
00433 char* m_childMutex;
00434 TraceTimer* m_timer;
00435 static char ok;
00436
00437 };
00438
00439
00440
00441
00442 inline void TraceTimer::leafStart()
00443 {
00444 if (m_pruned) return;
00445 m_flopEnter=ch_flops();
00446 ++m_count;
00447 m_last_WCtime_stamp = ch_ticks();
00448 }
00449
00450 inline void TraceTimer::leafStop()
00451 {
00452 if (m_pruned) return;
00453 m_accumulated_WCtime += ch_ticks() - m_last_WCtime_stamp;
00454 m_flops+=ch_flops()-m_flopEnter;
00455 m_last_WCtime_stamp=0;
00456 }
00457
00458
00459 #endif // CH_NTIMER
00460 #include "BaseNamespaceFooter.H"
00461
00462 #endif // CH_TIMER_H