COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/time_measure.h @ 1689:f1795dafe42c

Last change on this file since 1689:f1795dafe42c was 1689:f1795dafe42c, checked in by Alpar Juttner, 14 years ago
  • runningTimeTest(): a tool to measure running times more precisely.
  • TimeStamp? now uses double to count cpu-times
  • 'get's removed from the query functions of Times and TimeStamp?
File size: 8.4 KB
Line 
1/* -*- C++ -*-
2 * lemon/time_measure.h - Part of LEMON, a generic C++ optimization library
3 *
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
6 *
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
10 *
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
13 * purpose.
14 *
15 */
16
17#ifndef LEMON_TIME_MEASURE_H
18#define LEMON_TIME_MEASURE_H
19
20///\ingroup misc
21///\file
22///\brief Tools for measuring cpu usage
23
24#include <sys/time.h>
25#include <sys/times.h>
26#include <fstream>
27#include <iostream>
28#include <unistd.h>
29
30namespace lemon {
31
32  /// \addtogroup misc
33  /// @{
34
35  /// A class to store (cpu)time instances.
36
37  /// This class stores five time values.
38  /// - a real time
39  /// - a user cpu time
40  /// - a system cpu time
41  /// - a user cpu time of children
42  /// - a system cpu time of children
43  ///
44  /// TimeStamp's can be added to or substracted from each other and
45  /// they can be pushed to a stream.
46  ///
47  /// In most cases, perhaps \ref Timer class is what you want to use instead.
48  ///
49  ///\author Alpar Juttner
50
51  class TimeStamp
52  {
53    struct rtms
54    {
55      double tms_utime;
56      double tms_stime;
57      double tms_cutime;
58      double tms_cstime;
59      rtms() {}
60      rtms(tms ts) : tms_utime(ts.tms_utime), tms_stime(ts.tms_stime),
61                     tms_cutime(ts.tms_cutime), tms_cstime(ts.tms_cstime) {}
62    };
63    rtms ts;
64    double real_time;
65 
66    rtms &getTms() {return ts;}
67    const rtms &getTms() const {return ts;}
68
69  public:
70
71    ///Read the current time values of the process
72    void stamp()
73    {
74      timeval tv;
75      tms _ts;
76      times(&_ts);
77      gettimeofday(&tv, 0);real_time=tv.tv_sec+double(tv.tv_usec)/1e6;
78      ts=_ts;
79    }
80 
81    /// Constructor initializing with zero
82    TimeStamp()
83    { ts.tms_utime=ts.tms_stime=ts.tms_cutime=ts.tms_cstime=0; real_time=0;}
84    ///Constructor initializing with the current time values of the process
85    TimeStamp(void *) { stamp();}
86 
87    ///\e
88    TimeStamp &operator+=(const TimeStamp &b)
89    {
90      ts.tms_utime+=b.ts.tms_utime;
91      ts.tms_stime+=b.ts.tms_stime;
92      ts.tms_cutime+=b.ts.tms_cutime;
93      ts.tms_cstime+=b.ts.tms_cstime;
94      real_time+=b.real_time;
95      return *this;
96    }
97    ///\e
98    TimeStamp operator+(const TimeStamp &b) const
99    {
100      TimeStamp t(*this);
101      return t+=b;
102    }
103    ///\e
104    TimeStamp &operator-=(const TimeStamp &b)
105    {
106      ts.tms_utime-=b.ts.tms_utime;
107      ts.tms_stime-=b.ts.tms_stime;
108      ts.tms_cutime-=b.ts.tms_cutime;
109      ts.tms_cstime-=b.ts.tms_cstime;
110      real_time-=b.real_time;
111      return *this;
112    }
113    ///\e
114    TimeStamp operator-(const TimeStamp &b) const
115    {
116      TimeStamp t(*this);
117      return t-=b;
118    }
119    ///\e
120
121    ///\bug operator * and / gives rounded values!
122    TimeStamp &operator*=(double b)
123    {
124      ts.tms_utime*=b;
125      ts.tms_stime*=b;
126      ts.tms_cutime*=b;
127      ts.tms_cstime*=b;
128      real_time*=b;
129      return *this;
130    }
131    ///\e
132    TimeStamp operator*(double b) const
133    {
134      TimeStamp t(*this);
135      return t*=b;
136    }
137    friend TimeStamp operator*(double b,const TimeStamp &t);
138    ///\e
139    TimeStamp &operator/=(double b)
140    {
141      ts.tms_utime/=b;
142      ts.tms_stime/=b;
143      ts.tms_cutime/=b;
144      ts.tms_cstime/=b;
145      real_time/=b;
146      return *this;
147    }
148    ///\e
149    TimeStamp operator/(double b) const
150    {
151      TimeStamp t(*this);
152      return t/=b;
153    }
154    ///The time ellapsed since the last call of stamp()
155    TimeStamp ellapsed() const
156    {
157      TimeStamp t(NULL);
158      return t-*this;
159    }
160 
161    friend std::ostream& operator<<(std::ostream& os,const TimeStamp &t);
162 
163    ///Gives back the user time of the process
164    double userTime() const
165    {
166      return double(ts.tms_utime)/sysconf(_SC_CLK_TCK);
167    }
168    ///Gives back the system time of the process
169    double systemTime() const
170    {
171      return double(ts.tms_stime)/sysconf(_SC_CLK_TCK);
172    }
173    ///Gives back the user time of the process' children
174    double cUserTime() const
175    {
176      return double(ts.tms_cutime)/sysconf(_SC_CLK_TCK);
177    }
178    ///Gives back the user time of the process' children
179    double cSystemTime() const
180    {
181      return double(ts.tms_cstime)/sysconf(_SC_CLK_TCK);
182    }
183    ///Gives back the real time of the process
184    double realTime() const {return real_time;}
185  };
186
187  TimeStamp operator*(double b,const TimeStamp &t)
188  {
189    return t*b;
190  }
191 
192  ///Class measuring the cpu time and real time usage of the process
193
194  ///Class measuring the cpu time and real time usage of the process.
195  ///It is quite easy-to-use, here is a short example.
196  ///\code
197  ///#include<lemon/time_measure.h>
198  ///#include<iostream>
199  ///
200  ///int main()
201  ///{
202  ///
203  ///  ...
204  ///
205  ///  Timer T;
206  ///  doSomething();
207  ///  std::cout << T << '\n';
208  ///  T.reset();
209  ///  doSomethingElse();
210  ///  std::cout << T << '\n';
211  ///
212  ///  ...
213  ///
214  ///}
215  ///\endcode
216  ///
217  ///\todo This shouldn't be Unix (Linux) specific.
218  ///
219  ///\author Alpar Juttner
220  class Timer
221  {
222    TimeStamp start_time;
223
224    void _reset() {start_time.stamp();}
225 
226  public:
227    ///Constructor. It starts with zero time counters
228    Timer() {_reset();}
229
230    ///Computes the ellapsed time
231
232    ///This conversion computes the ellapsed time
233    ///since the construction of \c t or since
234    ///the last \c t.reset().
235    operator TimeStamp () const
236    {
237      TimeStamp t;
238      t.stamp();
239      return t-start_time;
240    }
241
242    ///Resets the time counters
243
244    ///Resets the time counters
245    ///
246    void reset()
247    {
248      _reset();
249    }
250
251
252    ///Gives back the ellapsed user time of the process
253    double userTime() const
254    {
255      return operator TimeStamp().userTime();
256    }
257    ///Gives back the ellapsed system time of the process
258    double systemTime() const
259    {
260      return operator TimeStamp().systemTime();
261    }
262    ///Gives back the ellapsed user time of the process' children
263    double cUserTime() const
264    {
265      return operator TimeStamp().cUserTime();
266    }
267    ///Gives back the ellapsed user time of the process' children
268    double cSystemTime() const
269    {
270      return operator TimeStamp().cSystemTime();
271    }
272    ///Gives back the ellapsed real time of the process
273    double realTime() const
274    {
275      return operator TimeStamp().realTime();
276    }
277
278  };
279
280  ///Prints the time counters
281
282  ///Prints the time counters in the following form:
283  ///
284  /// <tt>u: XX.XXs s: XX.XXs cu: XX.XXs cs: XX.XXs real: XX.XXs</tt>
285  ///
286  /// where the values are the
287  /// \li \c u: user cpu time,
288  /// \li \c s: system cpu time,
289  /// \li \c cu: user cpu time of children,
290  /// \li \c cs: system cpu time of children,
291  /// \li \c real: real time.
292  /// \relates TimeStamp
293  inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t)
294  {
295    long cls = sysconf(_SC_CLK_TCK);
296    os << "u: " << double(t.getTms().tms_utime)/cls <<
297      "s, s: " << double(t.getTms().tms_stime)/cls <<
298      "s, cu: " << double(t.getTms().tms_cutime)/cls <<
299      "s, cs: " << double(t.getTms().tms_cstime)/cls <<
300      "s, real: " << t.realTime() << "s";
301    return os;
302  }
303
304 
305  ///Tool to measure the running time more exactly.
306 
307  ///This function calls \c f several times and returns the average
308  ///running time. The number of the executions will be choosen in such a way
309  ///that the full running time will be roughly between \c min_time
310  ///and <tt>2*min_time</tt>.
311  ///\param f the function object to be measured.
312  ///\param min_time the minimum total running time.
313  ///\retval num if it is not \c NULL, then *num will contain the actual
314  ///        number of execution of \c f.
315  ///\retval full_time if it is not \c NULL, then *full_time
316  ///        will contain the actual
317  ///        total running time.
318  ///\return The average running time of \c f.
319 
320  template<class F>
321  TimeStamp runningTimeTest(F &f,double min_time=10,int *num = NULL,
322                        TimeStamp *full_time=NULL)
323  {
324    Timer t;
325    TimeStamp full;
326    int total=0;
327    for(int tn=1;tn < 1<<24; tn*=2) {
328      for(;total<tn;total++) f();
329      full=t;
330      if(full.realTime()>min_time) {
331        if(num) *num=total;
332        if(full_time) *full_time=full;
333      return full/total;
334      }
335    }
336    return TimeStamp();
337  }
338 
339  /// @} 
340
341
342} //namespace lemon
343
344#endif //LEMON_TIME_MEASURE_H
Note: See TracBrowser for help on using the repository browser.