NGSolve  5.3
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   {
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