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