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
00020 #ifdef CH_MPI
00021 #include "mpi.h"
00022 #endif
00023
00024
00025 #include <list>
00026 #include <string>
00027 #include "List.H"
00028
00029 #include <string>
00030 #include <iostream>
00031 #include <sys/time.h>
00032
00033 #include "BaseNamespaceHeader.H"
00034
00035 using namespace std;
00036
00037
00038
00039 #ifdef CH_NTIMER
00040
00041 #define CH_TIMER(name, tpointer) (void)0
00042 #define CH_TIME(name) (void)0
00043 #define CH_TIMELEAF(name) (void)0
00044 #define CH_TIMERS(name) (void)0
00045 #define CH_START(tpointer) (void)0
00046 #define CH_STOP(tpointer) (void)0
00047 #define CH_STOPV(tpointer, val) (void)0
00048 #define CH_TIMER_REPORT() (void)0
00049 #define CH_TIMER_RESET() (void)0
00050 #define CH_TIMER_PRUNE(threshold) (void)0
00051
00052 #else // CH_NTIMER
00053
00054
00055 #define CH_TIMER(name, tpointer) \
00056 const char* TimerTag_##tpointer = name ; \
00057 CH_XD::TraceTimer* tpointer = CH_XD::TraceTimer::getTimer(TimerTag_##tpointer)
00058
00059 #define CH_TIME(name) \
00060 const char* TimerTagA = name ; \
00061 char CH_TimermutexA = 0; \
00062 CH_XD::TraceTimer* ch_tpointer = CH_XD::TraceTimer::getTimer(TimerTagA); \
00063 CH_XD::AutoStart autostart(ch_tpointer, &CH_TimermutexA)
00064
00065 #define CH_TIMELEAF(name) \
00066 const char* TimerTagA = name ; \
00067 CH_XD::TraceTimer* ch_tpointer = CH_XD::TraceTimer::getTimer(TimerTagA); \
00068 CH_XD::AutoStartLeaf autostart(ch_tpointer)
00069
00070 #define CH_TIMERS(name) \
00071 const char* TimerTagA = name ; \
00072 char CH_TimermutexA = 0; \
00073 char CH_Timermutex = 0; \
00074 CH_XD::TraceTimer* ch_tpointer = CH_XD::TraceTimer::getTimer(TimerTagA); \
00075 CH_XD::AutoStart autostart(ch_tpointer, &CH_TimermutexA, &CH_Timermutex)
00076
00077
00078 #define CH_START(tpointer) tpointer->start(&CH_Timermutex)
00079
00080 #define CH_STOP(tpointer) tpointer->stop(&CH_Timermutex)
00081 #define CH_STOPV(tpointer, val ) val = tpointer->stop(&CH_Timermutex)
00082
00083 #define CH_TIMER_REPORT() CH_XD::TraceTimer::report()
00084
00085 #define CH_TIMER_RESET() CH_XD::TraceTimer::reset()
00086
00087 #define CH_TIMER_PRUNE(threshold) CH_XD::TraceTimer::PruneTimersParentChildPercent(threshold)
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
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 class TraceTimer
00237 {
00238 public:
00239 virtual ~TraceTimer();
00240 void start(char* mutex);
00241 unsigned long long int stop(char* mutex);
00242 static void report(bool a_closeAfter=false);
00243 static void reset();
00244
00245
00246 void leafStart();
00247 void leafStop();
00248
00249 unsigned long long int time() const
00250 {
00251 return m_accumulated_WCtime;
00252 }
00253
00254 int rank() const
00255 {
00256 return m_rank;
00257 }
00258 long long int count() const
00259 {
00260 return m_count;
00261 }
00262
00263 void prune();
00264 bool isPruned() const
00265 {
00266 return m_pruned;
00267 }
00268
00269 static int initializer();
00270 static TraceTimer* getTimer(const char* name);
00271 const std::vector<TraceTimer*>& children() const ;
00272
00273 static void PruneTimersParentChildPercent(double percent);
00274 static void sampleMemUsage() ;
00275
00276 static const char* currentTimer()
00277 {
00278 return s_currentTimer[0]->m_name;
00279 }
00280
00281 private:
00282 TraceTimer(const char* a_name, TraceTimer* parent, int thread_id);
00283 static std::vector<TraceTimer*> s_roots;
00284 static std::vector<TraceTimer*> s_currentTimer;
00285 static bool s_traceMemory;
00286 static long long int s_peak;
00287 static TraceTimer* s_peakTimer;
00288
00289 bool m_pruned;
00290 TraceTimer* m_parent;
00291 std::vector<TraceTimer*> m_children;
00292 const char* m_name;
00293 long long int m_count;
00294 unsigned long long int m_accumulated_WCtime;
00295 unsigned long long int m_last_WCtime_stamp;
00296 mutable int m_rank;
00297 int m_thread_id;
00298 long long int m_memory;
00299 long long int m_last_Memory_Stamp;
00300 long long int m_peak;
00301
00302 void reportTree(FILE* out, const TraceTimer& node, int depth);
00303 const TraceTimer* activeChild() const;
00304
00305 void macroTest();
00306 void macroTest2();
00307
00308 void currentize() const ;
00309 int computeRank() const;
00310 static void reportFullTree(FILE* out, const TraceTimer& timer,
00311 unsigned long long int totalTime, int depth);
00312 static void reportOneTree(FILE* out, const TraceTimer& timer);
00313 static void reportMemoryOneTree(FILE* out, const TraceTimer& timer);
00314 static void subReport(FILE* out, const char* header, unsigned long long int totalTime);
00315 static void reset(TraceTimer& timer);
00316 static void PruneTimersParentChildPercent(double threshold, TraceTimer* parent);
00317
00318 };
00319
00320
00321 class AutoStartLeaf
00322 {
00323 public:
00324 AutoStartLeaf(TraceTimer* a_timer):m_timer(a_timer)
00325 {
00326 a_timer->leafStart();
00327 }
00328
00329 ~AutoStartLeaf()
00330 {
00331 m_timer->leafStop();
00332 }
00333
00334 bool active();
00335
00336 private:
00337 TraceTimer* m_timer;
00338 };
00339
00340 class AutoStart
00341 {
00342 public:
00343 AutoStart(TraceTimer* a_timer, char* mutex, char* childMutex)
00344 :m_mutex(mutex), m_childMutex(childMutex),m_timer(a_timer)
00345 {a_timer->start(mutex);}
00346 AutoStart(TraceTimer* a_timer, char* mutex)
00347 :m_mutex(mutex), m_childMutex(&AutoStart::ok),m_timer(a_timer)
00348 {a_timer->start(mutex);}
00349 inline ~AutoStart();
00350 bool active();
00351 private:
00352 char* m_mutex;
00353 char* m_childMutex;
00354 TraceTimer* m_timer;
00355 static char ok;
00356
00357 };
00358
00359 inline
00360 AutoStart::~AutoStart()
00361 {
00362 # ifndef NDEBUG
00363 if (*m_childMutex == 1)
00364 MayDay::Error("Child timer still running on function exit");
00365 # endif
00366 m_timer->stop(m_mutex);
00367 }
00368
00369 inline double TimerGetTimeStampWC()
00370 {
00371
00372
00373
00374 #ifndef CH_NTIMER
00375 struct timeval tv;
00376 struct timezone tz;
00377 gettimeofday(&tv, &tz);
00378 return((double)tv.tv_sec + 0.000001 * (double)tv.tv_usec);
00379 #else
00380 return 0;
00381 #endif
00382 }
00383
00384 inline void TraceTimer::leafStart()
00385 {
00386 if (m_pruned) return;
00387 ++m_count;
00388 m_last_WCtime_stamp = ch_ticks();
00389 }
00390
00391 inline void TraceTimer::leafStop()
00392 {
00393 if (m_pruned) return;
00394 m_accumulated_WCtime += ch_ticks() - m_last_WCtime_stamp;
00395 m_last_WCtime_stamp=0;
00396 }
00397
00398
00399
00400 #endif // CH_NTIMER
00401 #include "BaseNamespaceFooter.H"
00402
00403 #endif // CH_TIMER_H