NGSolve
5.3
|
00001 #ifndef FILE_PROFILER 00002 #define FILE_PROFILER 00003 00004 /**************************************************************************/ 00005 /* File: profiler.hpp */ 00006 /* Author: Joachim Schoeberl */ 00007 /* Date: 5. Jan. 2005 */ 00008 /**************************************************************************/ 00009 00010 00011 // Philippose - 27 January 2010 00012 // Windows does not provide a "sys/time.h" include, 00013 // and neither does it define the function "gettimeofday" 00014 // anywhere..... This is a workaround... 00015 #ifdef _WIN32 00016 #include <sys/timeb.h> 00017 #include <sys/types.h> 00018 #include <winsock.h> 00019 00020 00021 inline void gettimeofday(struct timeval* t,void* timezone) 00022 { struct _timeb timebuffer; 00023 _ftime( &timebuffer ); 00024 t->tv_sec=timebuffer.time; 00025 t->tv_usec=1000*timebuffer.millitm; 00026 } 00027 00028 inline double WallTime () 00029 { 00030 struct _timeb timebuffer; 00031 _ftime( &timebuffer ); 00032 return timebuffer.time+1e-3*timebuffer.millitm; 00033 } 00034 00035 00036 #else 00037 00038 #include <sys/time.h> 00039 00040 inline double WallTime () 00041 { 00042 timeval time; 00043 gettimeofday (&time, 0); 00044 return time.tv_sec + 1e-6 * time.tv_usec; 00045 } 00046 00047 #endif 00048 00049 #ifdef VTRACE 00050 #include "vt_user.h" 00051 #else 00052 #define VT_USER_START(n) 00053 #define VT_USER_END(n) 00054 #define VT_TRACER(n) 00055 #define VT_ON() 00056 #define VT_OFF() 00057 #endif 00058 00059 namespace ngstd 00060 { 00061 00062 00066 class NgProfiler 00067 { 00068 public: 00070 enum { SIZE = 1000000 }; 00071 // static long int tottimes[SIZE]; 00072 // static long int starttimes[SIZE]; 00073 00074 NGS_DLL_HEADER static double tottimes[SIZE]; 00075 NGS_DLL_HEADER static double starttimes[SIZE]; 00076 00077 NGS_DLL_HEADER static long int counts[SIZE]; 00078 NGS_DLL_HEADER static double flops[SIZE]; 00079 NGS_DLL_HEADER static double loads[SIZE]; 00080 NGS_DLL_HEADER static double stores[SIZE]; 00081 NGS_DLL_HEADER static string names[SIZE]; 00082 NGS_DLL_HEADER static int usedcounter[SIZE]; 00083 00084 private: 00085 00086 // int total_timer; 00087 static string filename; 00088 public: 00090 NgProfiler(); 00092 ~NgProfiler(); 00093 00094 static void SetFileName (const string & afilename) { filename = afilename; } 00095 00097 NGS_DLL_HEADER static int CreateTimer (const string & name); 00098 00099 00100 #ifndef NOPROFILE 00101 00102 00103 #ifdef USE_TIMEOFDAY 00104 static void StartTimer (int nr) 00105 { 00106 timeval time; 00107 gettimeofday (&time, 0); 00108 // starttimes[nr] = time.tv_sec + 1e-6 * time.tv_usec; 00109 #pragma omp atomic 00110 tottimes[nr] -= time.tv_sec + 1e-6 * time.tv_usec; 00111 #pragma omp atomic 00112 counts[nr]++; 00113 VT_USER_START (const_cast<char*> (names[nr].c_str())); 00114 } 00115 00116 static void StopTimer (int nr) 00117 { 00118 timeval time; 00119 gettimeofday (&time, 0); 00120 // tottimes[nr] += time.tv_sec + 1e-6 * time.tv_usec - starttimes[nr]; 00121 #pragma omp atomic 00122 tottimes[nr] += time.tv_sec + 1e-6 * time.tv_usec; 00123 VT_USER_END (const_cast<char*> (names[nr].c_str())); 00124 } 00125 00126 #else 00127 00129 static void StartTimer (int nr) 00130 { 00131 starttimes[nr] = clock(); counts[nr]++; 00132 VT_USER_START (const_cast<char*> (names[nr].c_str())); 00133 } 00134 00136 static void StopTimer (int nr) 00137 { 00138 tottimes[nr] += clock()-starttimes[nr]; 00139 VT_USER_END (const_cast<char*> (names[nr].c_str())); 00140 } 00141 00142 #endif 00143 00144 00146 static void AddFlops (int nr, double aflops) { flops[nr] += aflops; } 00147 static void AddLoads (int nr, double aloads) { loads[nr] += aloads; } 00148 static void AddStores (int nr, double astores) { stores[nr] += astores; } 00149 #else 00150 00151 static void StartTimer (int nr) { ; } 00152 static void StopTimer (int nr) { ; } 00153 static void AddFlops (int nr, double aflops) { ; }; 00154 static void AddLoads (int nr, double aflops) { ; }; 00155 static void AddStores (int nr, double aflops) { ; }; 00156 #endif 00157 00158 static int GetNr (const string & name) 00159 { 00160 for (int i = SIZE-1; i >= 0; i--) 00161 if (names[i] == name) 00162 return i; 00163 return -1; 00164 } 00165 00166 static double GetTime (int nr) 00167 { 00168 #ifdef USE_TIMEOFDAY 00169 return tottimes[nr]; 00170 #else 00171 return tottimes[nr]/CLOCKS_PER_SEC; 00172 #endif 00173 } 00174 00175 static double GetTime (const string & name) 00176 { 00177 for (int i = SIZE-1; i >= 0; i--) 00178 if (names[i] == name) 00179 return GetTime (i); 00180 return 0; 00181 } 00182 00183 00184 static long int GetCounts (int nr) 00185 { 00186 return counts[nr]; 00187 } 00188 00189 static long int GetFlops (int nr) 00190 { 00191 return flops[nr]; 00192 } 00193 00195 static void SetName (int nr, const string & name) { names[nr] = name; } 00197 NGS_DLL_HEADER static void Print (FILE * ost); 00198 //static void Print (ostream & ost); 00199 00204 class RegionTimer 00205 { 00206 int nr; 00207 public: 00209 RegionTimer (int anr) : nr(anr) { StartTimer (nr); } 00211 ~RegionTimer () { StopTimer (nr); } 00212 }; 00213 }; 00214 00215 00216 00217 00218 #ifndef VTRACE 00219 class Timer 00220 { 00221 int timernr; 00222 int priority; 00223 public: 00224 Timer (const string & name, int apriority = 1) 00225 : priority(apriority) 00226 { 00227 timernr = NgProfiler::CreateTimer (name); 00228 } 00229 void SetName (const string & name) 00230 { 00231 NgProfiler::SetName (timernr, name); 00232 } 00233 void Start () 00234 { 00235 if (priority <= 1) 00236 NgProfiler::StartTimer (timernr); 00237 } 00238 void Stop () 00239 { 00240 if (priority <= 1) 00241 NgProfiler::StopTimer (timernr); 00242 } 00243 void AddFlops (double aflops) 00244 { 00245 if (priority <= 1) 00246 NgProfiler::AddFlops (timernr, aflops); 00247 } 00248 00249 double GetTime () { return NgProfiler::GetTime(timernr); } 00250 long int GetCounts () { return NgProfiler::GetCounts(timernr); } 00251 double GetMFlops () 00252 { return NgProfiler::GetFlops(timernr) 00253 / NgProfiler::GetTime(timernr) * 1e-6; } 00254 operator int () { return timernr; } 00255 }; 00256 00257 00262 class RegionTimer 00263 { 00264 Timer & timer; 00265 public: 00267 RegionTimer (Timer & atimer) : timer(atimer) { timer.Start(); } 00269 ~RegionTimer () { timer.Stop(); } 00270 }; 00271 #else 00272 00273 00274 00275 #ifdef PARALLEL 00276 class Timer 00277 { 00278 static Timer * stack_top; 00279 00280 int timer_id; 00281 Timer * prev; 00282 int priority; 00283 string name; 00284 public: 00285 Timer (const string & aname, int apriority = 1) 00286 : name(aname) 00287 { 00288 priority = apriority; 00289 // timer_id = VT_USER_DEF(name.c_str()); 00290 timer_id = VT_USER_DEF(name.c_str(), NULL, NULL, -1); 00291 } 00292 void Start () 00293 { 00294 if (priority == 1) 00295 { 00296 prev = stack_top; 00297 stack_top = this; 00298 if (prev) 00299 // VT_USER_END_ID (prev -> timer_id); 00300 // VT_USER_END2 (prev -> timer_id); 00301 VT_USER_END (prev -> name.c_str()); 00302 // VT_USER_START_ID(timer_id); 00303 // VT_USER_START2 (timer_id); 00304 VT_USER_START (name.c_str()); 00305 } 00306 } 00307 void Stop () 00308 { 00309 if (priority == 1) 00310 { 00311 // VT_USER_END_ID(timer_id); 00312 // VT_USER_END2(timer_id); 00313 VT_USER_END(name.c_str()); 00314 if (prev != NULL) 00315 // VT_USER_START_ID(prev -> timer_id); 00316 // VT_USER_START2(prev -> timer_id); 00317 VT_USER_START(prev -> name.c_str()); 00318 stack_top = prev; 00319 } 00320 } 00321 void SetName (const string & /* st */) { ; } 00322 void AddFlops (double aflops) { ; } 00323 double GetTime () { return 0; } 00324 long int GetCounts () { return 0; } 00325 operator int () { return timer_id; } 00326 }; 00327 #else 00328 00329 class Timer 00330 { 00331 int timer_id; 00332 00333 public: 00334 Timer (const string & name, int priority = 1) 00335 { 00336 timer_id = VT_USER_DEF(name.c_str()); 00337 } 00338 void Start () 00339 { 00340 VT_USER_START_ID(timer_id); 00341 } 00342 void Stop () 00343 { 00344 VT_USER_END_ID(timer_id); 00345 } 00346 00347 void SetName (const string & st) { ; } 00348 void AddFlops (double aflops) { ; } 00349 double GetTime () { return 0; } 00350 long int GetCounts () { return 0; } 00351 }; 00352 00353 #endif 00354 00355 00356 00357 00362 class RegionTimer 00363 { 00364 Timer & timer; 00365 public: 00367 RegionTimer (Timer & atimer) : timer(atimer) { timer.Start(); } 00369 ~RegionTimer () { timer.Stop(); } 00370 }; 00371 #endif 00372 00373 } 00374 00375 00376 #endif