gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Add missing include to time_measure.h
0 1 0
default
1 file changed with 1 insertions and 0 deletions:
↑ Collapse diff ↑
Ignore white space 1024 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_TIME_MEASURE_H
20 20
#define LEMON_TIME_MEASURE_H
21 21

	
22 22
///\ingroup timecount
23 23
///\file
24 24
///\brief Tools for measuring cpu usage
25 25

	
26 26
#ifdef WIN32
27 27
#define WIN32_LEAN_AND_MEAN
28 28
#define NOMINMAX
29 29
#include <windows.h>
30 30
#include <cmath>
31 31
#else
32
#include <unistd.h>
32 33
#include <sys/times.h>
33 34
#include <sys/time.h>
34 35
#endif
35 36

	
36 37
#include <string>
37 38
#include <fstream>
38 39
#include <iostream>
39 40

	
40 41
namespace lemon {
41 42

	
42 43
  /// \addtogroup timecount
43 44
  /// @{
44 45

	
45 46
  /// A class to store (cpu)time instances.
46 47

	
47 48
  /// This class stores five time values.
48 49
  /// - a real time
49 50
  /// - a user cpu time
50 51
  /// - a system cpu time
51 52
  /// - a user cpu time of children
52 53
  /// - a system cpu time of children
53 54
  ///
54 55
  /// TimeStamp's can be added to or substracted from each other and
55 56
  /// they can be pushed to a stream.
56 57
  ///
57 58
  /// In most cases, perhaps the \ref Timer or the \ref TimeReport
58 59
  /// class is what you want to use instead.
59 60

	
60 61
  class TimeStamp
61 62
  {
62 63
    double utime;
63 64
    double stime;
64 65
    double cutime;
65 66
    double cstime;
66 67
    double rtime;
67 68

	
68 69
    void _reset() {
69 70
      utime = stime = cutime = cstime = rtime = 0;
70 71
    }
71 72

	
72 73
  public:
73 74

	
74 75
    ///Read the current time values of the process
75 76
    void stamp()
76 77
    {
77 78
#ifndef WIN32
78 79
      timeval tv;
79 80
      gettimeofday(&tv, 0);
80 81
      rtime=tv.tv_sec+double(tv.tv_usec)/1e6;
81 82

	
82 83
      tms ts;
83 84
      double tck=sysconf(_SC_CLK_TCK);
84 85
      times(&ts);
85 86
      utime=ts.tms_utime/tck;
86 87
      stime=ts.tms_stime/tck;
87 88
      cutime=ts.tms_cutime/tck;
88 89
      cstime=ts.tms_cstime/tck;
89 90
#else
90 91
      static const double ch = 4294967296.0e-7;
91 92
      static const double cl = 1.0e-7;
92 93

	
93 94
      FILETIME system;
94 95
      GetSystemTimeAsFileTime(&system);
95 96
      rtime = ch * system.dwHighDateTime + cl * system.dwLowDateTime;
96 97

	
97 98
      FILETIME create, exit, kernel, user;
98 99
      if (GetProcessTimes(GetCurrentProcess(),&create, &exit, &kernel, &user)) {
99 100
        utime = ch * user.dwHighDateTime + cl * user.dwLowDateTime;
100 101
        stime = ch * kernel.dwHighDateTime + cl * kernel.dwLowDateTime;
101 102
        cutime = 0;
102 103
        cstime = 0;
103 104
      } else {
104 105
        rtime = 0;
105 106
        utime = 0;
106 107
        stime = 0;
107 108
        cutime = 0;
108 109
        cstime = 0;
109 110
      }
110 111
#endif
111 112
    }
112 113

	
113 114
    /// Constructor initializing with zero
114 115
    TimeStamp()
115 116
    { _reset(); }
116 117
    ///Constructor initializing with the current time values of the process
117 118
    TimeStamp(void *) { stamp();}
118 119

	
119 120
    ///Set every time value to zero
120 121
    TimeStamp &reset() {_reset();return *this;}
121 122

	
122 123
    ///\e
123 124
    TimeStamp &operator+=(const TimeStamp &b)
124 125
    {
125 126
      utime+=b.utime;
126 127
      stime+=b.stime;
127 128
      cutime+=b.cutime;
128 129
      cstime+=b.cstime;
129 130
      rtime+=b.rtime;
130 131
      return *this;
131 132
    }
132 133
    ///\e
133 134
    TimeStamp operator+(const TimeStamp &b) const
134 135
    {
135 136
      TimeStamp t(*this);
136 137
      return t+=b;
137 138
    }
138 139
    ///\e
139 140
    TimeStamp &operator-=(const TimeStamp &b)
140 141
    {
141 142
      utime-=b.utime;
142 143
      stime-=b.stime;
143 144
      cutime-=b.cutime;
144 145
      cstime-=b.cstime;
145 146
      rtime-=b.rtime;
146 147
      return *this;
147 148
    }
148 149
    ///\e
149 150
    TimeStamp operator-(const TimeStamp &b) const
150 151
    {
151 152
      TimeStamp t(*this);
152 153
      return t-=b;
153 154
    }
154 155
    ///\e
155 156
    TimeStamp &operator*=(double b)
156 157
    {
157 158
      utime*=b;
158 159
      stime*=b;
159 160
      cutime*=b;
160 161
      cstime*=b;
161 162
      rtime*=b;
162 163
      return *this;
163 164
    }
164 165
    ///\e
165 166
    TimeStamp operator*(double b) const
166 167
    {
167 168
      TimeStamp t(*this);
168 169
      return t*=b;
169 170
    }
170 171
    friend TimeStamp operator*(double b,const TimeStamp &t);
171 172
    ///\e
172 173
    TimeStamp &operator/=(double b)
173 174
    {
174 175
      utime/=b;
175 176
      stime/=b;
176 177
      cutime/=b;
177 178
      cstime/=b;
178 179
      rtime/=b;
179 180
      return *this;
180 181
    }
181 182
    ///\e
182 183
    TimeStamp operator/(double b) const
183 184
    {
184 185
      TimeStamp t(*this);
185 186
      return t/=b;
186 187
    }
187 188
    ///The time ellapsed since the last call of stamp()
188 189
    TimeStamp ellapsed() const
189 190
    {
190 191
      TimeStamp t(NULL);
191 192
      return t-*this;
192 193
    }
193 194

	
194 195
    friend std::ostream& operator<<(std::ostream& os,const TimeStamp &t);
195 196

	
196 197
    ///Gives back the user time of the process
197 198
    double userTime() const
198 199
    {
199 200
      return utime;
200 201
    }
201 202
    ///Gives back the system time of the process
202 203
    double systemTime() const
203 204
    {
204 205
      return stime;
205 206
    }
206 207
    ///Gives back the user time of the process' children
207 208

	
208 209
    ///\note On <tt>WIN32</tt> platform this value is not calculated.
209 210
    ///
210 211
    double cUserTime() const
211 212
    {
212 213
      return cutime;
213 214
    }
214 215
    ///Gives back the user time of the process' children
215 216

	
216 217
    ///\note On <tt>WIN32</tt> platform this value is not calculated.
217 218
    ///
218 219
    double cSystemTime() const
219 220
    {
220 221
      return cstime;
221 222
    }
222 223
    ///Gives back the real time
223 224
    double realTime() const {return rtime;}
224 225
  };
225 226

	
226 227
  TimeStamp operator*(double b,const TimeStamp &t)
227 228
  {
228 229
    return t*b;
229 230
  }
230 231

	
231 232
  ///Prints the time counters
232 233

	
233 234
  ///Prints the time counters in the following form:
234 235
  ///
235 236
  /// <tt>u: XX.XXs s: XX.XXs cu: XX.XXs cs: XX.XXs real: XX.XXs</tt>
236 237
  ///
237 238
  /// where the values are the
238 239
  /// \li \c u: user cpu time,
239 240
  /// \li \c s: system cpu time,
240 241
  /// \li \c cu: user cpu time of children,
241 242
  /// \li \c cs: system cpu time of children,
242 243
  /// \li \c real: real time.
243 244
  /// \relates TimeStamp
244 245
  /// \note On <tt>WIN32</tt> platform the cummulative values are not
245 246
  /// calculated.
246 247
  inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t)
247 248
  {
248 249
    os << "u: " << t.userTime() <<
249 250
      "s, s: " << t.systemTime() <<
250 251
      "s, cu: " << t.cUserTime() <<
251 252
      "s, cs: " << t.cSystemTime() <<
252 253
      "s, real: " << t.realTime() << "s";
253 254
    return os;
254 255
  }
255 256

	
256 257
  ///Class for measuring the cpu time and real time usage of the process
257 258

	
258 259
  ///Class for measuring the cpu time and real time usage of the process.
259 260
  ///It is quite easy-to-use, here is a short example.
260 261
  ///\code
261 262
  /// #include<lemon/time_measure.h>
262 263
  /// #include<iostream>
263 264
  ///
264 265
  /// int main()
265 266
  /// {
266 267
  ///
267 268
  ///   ...
268 269
  ///
269 270
  ///   Timer t;
270 271
  ///   doSomething();
271 272
  ///   std::cout << t << '\n';
272 273
  ///   t.restart();
273 274
  ///   doSomethingElse();
274 275
  ///   std::cout << t << '\n';
275 276
  ///
276 277
  ///   ...
277 278
  ///
278 279
  /// }
279 280
  ///\endcode
280 281
  ///
281 282
  ///The \ref Timer can also be \ref stop() "stopped" and
282 283
  ///\ref start() "started" again, so it is possible to compute collected
283 284
  ///running times.
284 285
  ///
285 286
  ///\warning Depending on the operation system and its actual configuration
286 287
  ///the time counters have a certain (10ms on a typical Linux system)
287 288
  ///granularity.
288 289
  ///Therefore this tool is not appropriate to measure very short times.
289 290
  ///Also, if you start and stop the timer very frequently, it could lead to
290 291
  ///distorted results.
291 292
  ///
292 293
  ///\note If you want to measure the running time of the execution of a certain
293 294
  ///function, consider the usage of \ref TimeReport instead.
294 295
  ///
295 296
  ///\sa TimeReport
296 297
  class Timer
297 298
  {
298 299
    int _running; //Timer is running iff _running>0; (_running>=0 always holds)
299 300
    TimeStamp start_time; //This is the relativ start-time if the timer
300 301
                          //is _running, the collected _running time otherwise.
301 302

	
302 303
    void _reset() {if(_running) start_time.stamp(); else start_time.reset();}
303 304

	
304 305
  public:
305 306
    ///Constructor.
306 307

	
307 308
    ///\param run indicates whether or not the timer starts immediately.
308 309
    ///
309 310
    Timer(bool run=true) :_running(run) {_reset();}
310 311

	
311 312
    ///\name Control the state of the timer
312 313
    ///Basically a Timer can be either running or stopped,
313 314
    ///but it provides a bit finer control on the execution.
314 315
    ///The \ref lemon::Timer "Timer" also counts the number of
315 316
    ///\ref lemon::Timer::start() "start()" executions, and it stops
316 317
    ///only after the same amount (or more) \ref lemon::Timer::stop()
317 318
    ///"stop()"s. This can be useful e.g. to compute the running time
318 319
    ///of recursive functions.
319 320

	
320 321
    ///@{
321 322

	
322 323
    ///Reset and stop the time counters
323 324

	
324 325
    ///This function resets and stops the time counters
325 326
    ///\sa restart()
326 327
    void reset()
327 328
    {
328 329
      _running=0;
329 330
      _reset();
330 331
    }
331 332

	
332 333
    ///Start the time counters
333 334

	
334 335
    ///This function starts the time counters.
335 336
    ///
336 337
    ///If the timer is started more than ones, it will remain running
337 338
    ///until the same amount of \ref stop() is called.
338 339
    ///\sa stop()
339 340
    void start()
340 341
    {
341 342
      if(_running) _running++;
342 343
      else {
343 344
        _running=1;
344 345
        TimeStamp t;
345 346
        t.stamp();
346 347
        start_time=t-start_time;
347 348
      }
348 349
    }
349 350

	
350 351

	
351 352
    ///Stop the time counters
352 353

	
353 354
    ///This function stops the time counters. If start() was executed more than
354 355
    ///once, then the same number of stop() execution is necessary the really
355 356
    ///stop the timer.
356 357
    ///
357 358
    ///\sa halt()
358 359
    ///\sa start()
359 360
    ///\sa restart()
360 361
    ///\sa reset()
361 362

	
362 363
    void stop()
363 364
    {
364 365
      if(_running && !--_running) {
365 366
        TimeStamp t;
366 367
        t.stamp();
367 368
        start_time=t-start_time;
368 369
      }
369 370
    }
370 371

	
371 372
    ///Halt (i.e stop immediately) the time counters
372 373

	
373 374
    ///This function stops immediately the time counters, i.e. <tt>t.halt()</tt>
374 375
    ///is a faster
375 376
    ///equivalent of the following.
376 377
    ///\code
377 378
    ///  while(t.running()) t.stop()
378 379
    ///\endcode
379 380
    ///
380 381
    ///
381 382
    ///\sa stop()
382 383
    ///\sa restart()
383 384
    ///\sa reset()
384 385

	
385 386
    void halt()
386 387
    {
387 388
      if(_running) {
388 389
        _running=0;
389 390
        TimeStamp t;
390 391
        t.stamp();
391 392
        start_time=t-start_time;
392 393
      }
393 394
    }
394 395

	
395 396
    ///Returns the running state of the timer
396 397

	
397 398
    ///This function returns the number of stop() exections that is
398 399
    ///necessary to really stop the timer.
399 400
    ///For example the timer
400 401
    ///is running if and only if the return value is \c true
401 402
    ///(i.e. greater than
402 403
    ///zero).
403 404
    int running()  { return _running; }
404 405

	
405 406

	
406 407
    ///Restart the time counters
407 408

	
408 409
    ///This function is a shorthand for
409 410
    ///a reset() and a start() calls.
410 411
    ///
411 412
    void restart()
412 413
    {
413 414
      reset();
414 415
      start();
415 416
    }
416 417

	
417 418
    ///@}
418 419

	
419 420
    ///\name Query Functions for the ellapsed time
420 421

	
421 422
    ///@{
422 423

	
423 424
    ///Gives back the ellapsed user time of the process
424 425
    double userTime() const
425 426
    {
426 427
      return operator TimeStamp().userTime();
427 428
    }
428 429
    ///Gives back the ellapsed system time of the process
429 430
    double systemTime() const
430 431
    {
431 432
      return operator TimeStamp().systemTime();
432 433
    }
433 434
    ///Gives back the ellapsed user time of the process' children
434 435

	
435 436
    ///\note On <tt>WIN32</tt> platform this value is not calculated.
436 437
    ///
437 438
    double cUserTime() const
438 439
    {
439 440
      return operator TimeStamp().cUserTime();
440 441
    }
441 442
    ///Gives back the ellapsed user time of the process' children
442 443

	
443 444
    ///\note On <tt>WIN32</tt> platform this value is not calculated.
444 445
    ///
445 446
    double cSystemTime() const
446 447
    {
447 448
      return operator TimeStamp().cSystemTime();
448 449
    }
449 450
    ///Gives back the ellapsed real time
450 451
    double realTime() const
451 452
    {
452 453
      return operator TimeStamp().realTime();
453 454
    }
454 455
    ///Computes the ellapsed time
455 456

	
456 457
    ///This conversion computes the ellapsed time, therefore you can print
457 458
    ///the ellapsed time like this.
458 459
    ///\code
459 460
    ///  Timer t;
460 461
    ///  doSomething();
461 462
    ///  std::cout << t << '\n';
462 463
    ///\endcode
463 464
    operator TimeStamp () const
464 465
    {
465 466
      TimeStamp t;
466 467
      t.stamp();
467 468
      return _running?t-start_time:start_time;
468 469
    }
469 470

	
470 471

	
471 472
    ///@}
472 473
  };
473 474

	
474 475
  ///Same as Timer but prints a report on destruction.
475 476

	
476 477
  ///Same as \ref Timer but prints a report on destruction.
477 478
  ///This example shows its usage.
478 479
  ///\code
479 480
  ///  void myAlg(ListGraph &g,int n)
480 481
  ///  {
481 482
  ///    TimeReport tr("Running time of myAlg: ");
482 483
  ///    ... //Here comes the algorithm
483 484
  ///  }
484 485
  ///\endcode
485 486
  ///
486 487
  ///\sa Timer
487 488
  ///\sa NoTimeReport
488 489
  class TimeReport : public Timer
489 490
  {
490 491
    std::string _title;
491 492
    std::ostream &_os;
492 493
  public:
493 494
    ///Constructor
494 495

	
495 496
    ///Constructor.
496 497
    ///\param title This text will be printed before the ellapsed time.
497 498
    ///\param os The stream to print the report to.
498 499
    ///\param run Sets whether the timer should start immediately.
499 500
    TimeReport(std::string title,std::ostream &os=std::cerr,bool run=true)
500 501
      : Timer(run), _title(title), _os(os){}
501 502
    ///Destructor that prints the ellapsed time
502 503
    ~TimeReport()
503 504
    {
504 505
      _os << _title << *this << std::endl;
505 506
    }
506 507
  };
507 508

	
508 509
  ///'Do nothing' version of TimeReport
509 510

	
510 511
  ///\sa TimeReport
511 512
  ///
512 513
  class NoTimeReport
513 514
  {
514 515
  public:
515 516
    ///\e
516 517
    NoTimeReport(std::string,std::ostream &,bool) {}
517 518
    ///\e
518 519
    NoTimeReport(std::string,std::ostream &) {}
519 520
    ///\e
520 521
    NoTimeReport(std::string) {}
521 522
    ///\e Do nothing.
522 523
    ~NoTimeReport() {}
523 524

	
524 525
    operator TimeStamp () const { return TimeStamp(); }
525 526
    void reset() {}
526 527
    void start() {}
527 528
    void stop() {}
528 529
    void halt() {}
529 530
    int running() { return 0; }
530 531
    void restart() {}
531 532
    double userTime() const { return 0; }
532 533
    double systemTime() const { return 0; }
533 534
    double cUserTime() const { return 0; }
534 535
    double cSystemTime() const { return 0; }
535 536
    double realTime() const { return 0; }
536 537
  };
537 538

	
538 539
  ///Tool to measure the running time more exactly.
539 540

	
540 541
  ///This function calls \c f several times and returns the average
541 542
  ///running time. The number of the executions will be choosen in such a way
542 543
  ///that the full real running time will be roughly between \c min_time
543 544
  ///and <tt>2*min_time</tt>.
0 comments (0 inline)