NGSolve  4.9
ngstd/profiler.hpp
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   {
00069     enum { SIZE = 1000 };
00070 
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     // int total_timer;
00085     static string filename;
00086   public: 
00088     NgProfiler();
00090     ~NgProfiler();
00091 
00092     static void SetFileName (const string & afilename) { filename = afilename; }
00093 
00095     NGS_DLL_HEADER static int CreateTimer (const string & name);
00096 
00097 
00098 #ifndef NOPROFILE
00099 
00100 
00101 #ifdef USE_TIMEOFDAY
00102     static void StartTimer (int nr) 
00103     { 
00104       timeval time;
00105       gettimeofday (&time, 0);
00106       // starttimes[nr] = time.tv_sec + 1e-6 * time.tv_usec;
00107 #pragma omp atomic
00108       tottimes[nr] -= time.tv_sec + 1e-6 * time.tv_usec;
00109       counts[nr]++; 
00110       VT_USER_START (const_cast<char*> (names[nr].c_str())); 
00111     }
00112 
00113     static void StopTimer (int nr) 
00114     { 
00115       timeval time;
00116       gettimeofday (&time, 0);
00117       // tottimes[nr] += time.tv_sec + 1e-6 * time.tv_usec - starttimes[nr];
00118 #pragma omp atomic
00119       tottimes[nr] += time.tv_sec + 1e-6 * time.tv_usec;
00120       VT_USER_END (const_cast<char*> (names[nr].c_str())); 
00121     }
00122   
00123 #else
00124   
00126     static void StartTimer (int nr) 
00127     {
00128       starttimes[nr] = clock(); counts[nr]++; 
00129       VT_USER_START (const_cast<char*> (names[nr].c_str())); 
00130     }
00131 
00133     static void StopTimer (int nr) 
00134     { 
00135       tottimes[nr] += clock()-starttimes[nr]; 
00136       VT_USER_END (const_cast<char*> (names[nr].c_str())); 
00137     }
00138 
00139 #endif
00140 
00141 
00143     static void AddFlops (int nr, double aflops) { flops[nr] += aflops; }
00144     static void AddLoads (int nr, double aloads) { loads[nr] += aloads; }
00145     static void AddStores (int nr, double astores) { stores[nr] += astores; }
00146 #else
00147 
00148     static void StartTimer (int nr) { ; }
00149     static void StopTimer (int nr) { ; }
00150     static void AddFlops (int nr, double aflops) { ; };
00151     static void AddLoads (int nr, double aflops) { ; };
00152     static void AddStores (int nr, double aflops) { ; };
00153 #endif
00154 
00155     static double GetTime (int nr)
00156     {
00157 #ifdef USE_TIMEOFDAY
00158       return tottimes[nr];
00159 #else
00160       return tottimes[nr]/CLOCKS_PER_SEC;
00161 #endif
00162     }
00163 
00164     static long int GetCounts (int nr)
00165     {
00166       return counts[nr];
00167     }
00168 
00170     static void SetName (int nr, const string & name) { names[nr] = name; }
00172     NGS_DLL_HEADER static void Print (FILE * ost);
00173     //static void Print (ostream & ost);
00174 
00179     class RegionTimer
00180     {
00181       int nr;
00182     public:
00184       RegionTimer (int anr) : nr(anr) { StartTimer (nr); }
00186       ~RegionTimer () { StopTimer (nr); }
00187     };
00188   };
00189 
00190 
00191 
00192   
00193 #ifndef VTRACE
00194   class Timer
00195   {
00196     int timernr;
00197   public:
00198     Timer (const string & name, int priority = 1)
00199     {
00200       timernr = NgProfiler::CreateTimer (name);
00201     }
00202     void Start () 
00203     {
00204       NgProfiler::StartTimer (timernr);
00205     }
00206     void Stop () 
00207     {
00208       NgProfiler::StopTimer (timernr);
00209     }
00210     void AddFlops (double aflops)
00211     {
00212       NgProfiler::AddFlops (timernr, aflops);
00213     }
00214 
00215     double GetTime () { return NgProfiler::GetTime(timernr); }
00216     long int GetCounts () { return NgProfiler::GetCounts(timernr); }
00217 
00218     operator int () { return timernr; }
00219   };
00220   
00221   
00226   class RegionTimer
00227   {
00228     Timer & timer;
00229   public:
00231     RegionTimer (Timer & atimer) : timer(atimer) { timer.Start(); }
00233     ~RegionTimer () { timer.Stop(); }
00234   };
00235 #else
00236 
00237 
00238   
00239 #ifdef PARALLEL
00240   class Timer
00241   {
00242     static Timer * stack_top;
00243 
00244     int timer_id;
00245     Timer * prev;
00246     int priority;
00247   public:
00248     Timer (const string & name, int apriority = 1)
00249     {
00250       priority = apriority;
00251       timer_id = VT_USER_DEF(name.c_str());
00252     }
00253     void Start () 
00254     {
00255       if (priority == 1)
00256         {
00257           prev = stack_top;
00258           stack_top = this;
00259           if (prev)
00260             VT_USER_END_ID (prev -> timer_id);
00261           VT_USER_START_ID(timer_id);
00262         }
00263     }
00264     void Stop () 
00265     {
00266       if (priority == 1)
00267         {
00268           VT_USER_END_ID(timer_id);
00269           if (prev != NULL)
00270             VT_USER_START_ID(prev -> timer_id);
00271           stack_top = prev;
00272         }
00273     }
00274 
00275     void AddFlops (double aflops)  { ; }
00276     double GetTime () { return 0; }
00277     long int GetCounts () { return 0; }
00278   };
00279 #else
00280 
00281   class Timer
00282   {
00283     int timer_id;
00284 
00285   public:
00286     Timer (const string & name, int priority = 1)
00287     {
00288       timer_id = VT_USER_DEF(name.c_str());
00289     }
00290     void Start () 
00291     {
00292       VT_USER_START_ID(timer_id);
00293     }
00294     void Stop () 
00295     {
00296       VT_USER_END_ID(timer_id);
00297     }
00298 
00299     void AddFlops (double aflops)  { ; }
00300     double GetTime () { return 0; }
00301     long int GetCounts () { return 0; }
00302   };
00303 
00304 #endif
00305 
00306 
00307 
00308   
00313   class RegionTimer
00314   {
00315     Timer & timer;
00316   public:
00318     RegionTimer (Timer & atimer) : timer(atimer) { timer.Start(); }
00320     ~RegionTimer () { timer.Stop(); }
00321   };
00322 #endif
00323 
00324 }
00325 
00326 
00327 #endif