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(const char* a_name) ;
00275 static void sampleMemUsage2() ;
00276 static void reportPeak(FILE* out);
00277
00278 static const char* currentTimer()
00279 {
00280 return s_currentTimer[0]->m_name;
00281 }
00282
00283 private:
00284 TraceTimer(const char* a_name, TraceTimer* parent, int thread_id);
00285 static std::vector<TraceTimer*> s_roots;
00286 static std::vector<TraceTimer*> s_currentTimer;
00287
00288 static long long int s_peak;
00289 static TraceTimer* s_peakTimer;
00290
00291 bool m_pruned;
00292 TraceTimer* m_parent;
00293 std::vector<TraceTimer*> m_children;
00294 const char* m_name;
00295 long long int m_count;
00296 unsigned long long int m_accumulated_WCtime;
00297 unsigned long long int m_last_WCtime_stamp;
00298 mutable int m_rank;
00299 int m_thread_id;
00300 static bool s_memorySampling;
00301 unsigned int m_memoryMin, m_memoryMax;
00302
00303 static bool s_tracing;
00304
00305
00306 static bool find(std::list<const TraceTimer*>& a_trace, const TraceTimer* a_target);
00307 void reportTree(FILE* out, const TraceTimer& node, int depth);
00308 const TraceTimer* activeChild() const;
00309
00310 void macroTest();
00311 void macroTest2();
00312
00313 void currentize() const ;
00314 int computeRank() const;
00315 static void reportFullTree(FILE* out, const TraceTimer& timer,
00316 unsigned long long int totalTime, int depth);
00317 static void reportOneTree(FILE* out, const TraceTimer& timer);
00318 static void updateMemory(TraceTimer& a_timer);
00319
00320
00321 static void subReport(FILE* out, const char* header, unsigned long long int totalTime);
00322 static void reset(TraceTimer& timer);
00323 static void PruneTimersParentChildPercent(double threshold, TraceTimer* parent);
00324
00325 };
00326
00327
00328 class AutoStartLeaf
00329 {
00330 public:
00331 AutoStartLeaf(TraceTimer* a_timer):m_timer(a_timer)
00332 {
00333 a_timer->leafStart();
00334 }
00335
00336 ~AutoStartLeaf()
00337 {
00338 m_timer->leafStop();
00339 }
00340
00341 bool active();
00342
00343 private:
00344 TraceTimer* m_timer;
00345 };
00346
00347 class AutoStart
00348 {
00349 public:
00350 AutoStart(TraceTimer* a_timer, char* mutex, char* childMutex)
00351 :m_mutex(mutex), m_childMutex(childMutex),m_timer(a_timer)
00352 {a_timer->start(mutex);}
00353 AutoStart(TraceTimer* a_timer, char* mutex)
00354 :m_mutex(mutex), m_childMutex(&AutoStart::ok),m_timer(a_timer)
00355 {a_timer->start(mutex);}
00356 inline ~AutoStart();
00357 bool active();
00358 private:
00359 char* m_mutex;
00360 char* m_childMutex;
00361 TraceTimer* m_timer;
00362 static char ok;
00363
00364 };
00365
00366 inline
00367 AutoStart::~AutoStart()
00368 {
00369 # ifndef NDEBUG
00370 if (*m_childMutex == 1)
00371 MayDay::Error("Child timer still running on function exit");
00372 # endif
00373 m_timer->stop(m_mutex);
00374 }
00375
00376 inline double TimerGetTimeStampWC()
00377 {
00378
00379
00380
00381 #ifndef CH_NTIMER
00382 struct timeval tv;
00383 struct timezone tz;
00384 gettimeofday(&tv, &tz);
00385 return((double)tv.tv_sec + 0.000001 * (double)tv.tv_usec);
00386 #else
00387 return 0;
00388 #endif
00389 }
00390
00391 inline void TraceTimer::leafStart()
00392 {
00393 if (m_pruned) return;
00394 ++m_count;
00395 m_last_WCtime_stamp = ch_ticks();
00396 }
00397
00398 inline void TraceTimer::leafStop()
00399 {
00400 if (m_pruned) return;
00401 m_accumulated_WCtime += ch_ticks() - m_last_WCtime_stamp;
00402 m_last_WCtime_stamp=0;
00403 }
00404
00405
00406
00407 #endif // CH_NTIMER
00408 #include "BaseNamespaceFooter.H"
00409
00410 #endif // CH_TIMER_H