src/include/time_measure.h
changeset 539 fb261e3a9a0f
parent 491 4804c967543d
equal deleted inserted replaced
5:810cac44137c -1:000000000000
     1 // -*- c++ -*-
       
     2 #ifndef HUGO_TIME_MEASURE_H
       
     3 #define HUGO_TIME_MEASURE_H
       
     4 
       
     5 ///\ingroup misc
       
     6 ///\file
       
     7 ///\brief Tools for measuring cpu usage
       
     8 
       
     9 #include <sys/time.h>
       
    10 #include <sys/times.h>
       
    11 #include <fstream>
       
    12 #include <iostream>
       
    13 #include <unistd.h>
       
    14 
       
    15 namespace hugo {
       
    16 
       
    17   /// \addtogroup misc
       
    18   /// @{
       
    19 
       
    20   /// A class to store (cpu)time instances.
       
    21 
       
    22   /// This class stores five time values.
       
    23   /// - a real time
       
    24   /// - a user cpu time
       
    25   /// - a system cpu time
       
    26   /// - a user cpu time of children
       
    27   /// - a system cpu time of children
       
    28   ///
       
    29   /// TimeStamp's can be added to or substracted from each other and
       
    30   /// they can be pushed to a stream.
       
    31   ///
       
    32   /// In most cases, perhaps \ref Timer class is what you want to use instead.
       
    33   ///
       
    34   ///\author Alpar Juttner
       
    35 
       
    36   class TimeStamp
       
    37   {
       
    38     tms ts;
       
    39     double real_time;
       
    40   
       
    41   public:
       
    42 
       
    43     tms &getTms() {return ts;}
       
    44     const tms &getTms() const {return ts;}
       
    45     ///Read the current time values of the process
       
    46     void stamp()
       
    47     {
       
    48       timeval tv;
       
    49       times(&ts);
       
    50       gettimeofday(&tv, 0);real_time=tv.tv_sec+double(tv.tv_usec)/1e6;
       
    51     }
       
    52   
       
    53     /// Constructor initializing with zero
       
    54     TimeStamp()
       
    55     { ts.tms_utime=ts.tms_stime=ts.tms_cutime=ts.tms_cstime=0; real_time=0;}
       
    56     ///Constructor initializing with the current time values of the process
       
    57     TimeStamp(void *) { stamp();}
       
    58   
       
    59     ///
       
    60     TimeStamp &operator+=(const TimeStamp &b)
       
    61     {
       
    62       ts.tms_utime+=b.ts.tms_utime;
       
    63       ts.tms_stime+=b.ts.tms_stime;
       
    64       ts.tms_cutime+=b.ts.tms_cutime;
       
    65       ts.tms_cstime+=b.ts.tms_cstime;
       
    66       real_time+=b.real_time;
       
    67       return *this;
       
    68     }
       
    69     ///
       
    70     TimeStamp operator+(const TimeStamp &b) const
       
    71     {
       
    72       TimeStamp t(*this);
       
    73       return t+=b;
       
    74     }
       
    75     ///
       
    76     TimeStamp &operator-=(const TimeStamp &b)
       
    77     {
       
    78       ts.tms_utime-=b.ts.tms_utime;
       
    79       ts.tms_stime-=b.ts.tms_stime;
       
    80       ts.tms_cutime-=b.ts.tms_cutime;
       
    81       ts.tms_cstime-=b.ts.tms_cstime;
       
    82       real_time-=b.real_time;
       
    83       return *this;
       
    84     }
       
    85     ///
       
    86     TimeStamp operator-(const TimeStamp &b) const
       
    87     {
       
    88       TimeStamp t(*this);
       
    89       return t-=b;
       
    90     }
       
    91 
       
    92     ///The time ellapsed since the last call of stamp()
       
    93     TimeStamp ellapsed() const
       
    94     {
       
    95       TimeStamp t(NULL);
       
    96       return t-*this;
       
    97     }
       
    98   
       
    99     friend std::ostream& operator<<(std::ostream& os,const TimeStamp &t);
       
   100   
       
   101     ///Gives back the user time of the process
       
   102     double getUserTime() const
       
   103     {
       
   104       return double(ts.tms_utime)/sysconf(_SC_CLK_TCK);
       
   105     }
       
   106     ///Gives back the system time of the process
       
   107     double getSystemTime() const
       
   108     {
       
   109       return double(ts.tms_stime)/sysconf(_SC_CLK_TCK);
       
   110     }
       
   111     ///Gives back the user time of the process' children
       
   112     double getCUserTime() const
       
   113     {
       
   114       return double(ts.tms_cutime)/sysconf(_SC_CLK_TCK);
       
   115     }
       
   116     ///Gives back the user time of the process' children
       
   117     double getCSystemTime() const
       
   118     {
       
   119       return double(ts.tms_cstime)/sysconf(_SC_CLK_TCK);
       
   120     }
       
   121     ///Gives back the real time of the process
       
   122     double getRealTime() const {return real_time;}
       
   123   };
       
   124 
       
   125   ///Class measuring the cpu time and real time usage of the process
       
   126 
       
   127   ///Class measuring the cpu time and real time usage of the process.
       
   128   ///It is quite easy-to-use, here is a short example.
       
   129   ///\code
       
   130   ///int main()
       
   131   ///{
       
   132   ///
       
   133   ///  ...
       
   134   ///
       
   135   ///  Timer T();
       
   136   ///  doSomething();
       
   137   ///  cout << T;
       
   138   ///  T.reset();
       
   139   ///  doSomethingElse();
       
   140   ///  cout << T;
       
   141   ///
       
   142   ///  ...
       
   143   ///
       
   144   ///}
       
   145   ///\endcode
       
   146   ///
       
   147   ///\todo This shouldn't be Unix (Linux) specific.
       
   148   ///
       
   149   ///\author Alpar Juttner
       
   150   class Timer
       
   151   {
       
   152     TimeStamp start_time;
       
   153 
       
   154     void _reset() {start_time.stamp();}
       
   155   
       
   156   public: 
       
   157     ///Constructor. It starts with zero time counters
       
   158     Timer() {_reset();}
       
   159 
       
   160     ///Computes the ellapsed time
       
   161 
       
   162     ///This conversion computes the ellapsed time
       
   163     ///since the construction of \c t or since
       
   164     ///the last \c t.reset().
       
   165     operator TimeStamp ()
       
   166     {
       
   167       TimeStamp t;
       
   168       t.stamp();
       
   169       return t-start_time;
       
   170     }
       
   171 
       
   172     ///Resets the time counters
       
   173     TimeStamp reset()
       
   174     {
       
   175       TimeStamp t(start_time);
       
   176       _reset();
       
   177       return start_time-t;
       
   178     }
       
   179   };
       
   180 
       
   181   ///Prints the time counters
       
   182 
       
   183   ///Prints the time counters in the following form:
       
   184   ///
       
   185   /// <tt>u: XX.XXs s: XX.XXs cu: XX.XXs cs: XX.XXs real: XX.XXs</tt>
       
   186   ///
       
   187   /// where the values are the
       
   188   /// \li \c u: user cpu time,
       
   189   /// \li \c s: system cpu time,
       
   190   /// \li \c cu: user cpu time of children,
       
   191   /// \li \c cs: system cpu time of children,
       
   192   /// \li \c real: real time.
       
   193   inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t)
       
   194   {
       
   195     long cls = sysconf(_SC_CLK_TCK);
       
   196     os << "u: " << double(t.getTms().tms_utime)/cls <<
       
   197       "s, s: " << double(t.getTms().tms_stime)/cls <<
       
   198       "s, cu: " << double(t.getTms().tms_cutime)/cls <<
       
   199       "s, cs: " << double(t.getTms().tms_cstime)/cls <<
       
   200       "s, real: " << t.getRealTime() << "s";
       
   201     return os;
       
   202   }
       
   203 
       
   204   /// @}  
       
   205 
       
   206 } //namespace hugo
       
   207 
       
   208 #endif //HUGO_TIME_MEASURE_H