Stxxl  1.3.2
iostats.h
1 /***************************************************************************
2  * include/stxxl/bits/io/iostats.h
3  *
4  * Part of the STXXL. See http://stxxl.sourceforge.net
5  *
6  * Copyright (C) 2002-2004 Roman Dementiev <[email protected]>
7  * Copyright (C) 2008-2010 Andreas Beckmann <[email protected]>
8  * Copyright (C) 2009, 2010 Johannes Singler <[email protected]>
9  *
10  * Distributed under the Boost Software License, Version 1.0.
11  * (See accompanying file LICENSE_1_0.txt or copy at
12  * http://www.boost.org/LICENSE_1_0.txt)
13  **************************************************************************/
14 
15 #ifndef STXXL_IOSTATS_HEADER
16 #define STXXL_IOSTATS_HEADER
17 
18 #ifndef STXXL_IO_STATS
19  #define STXXL_IO_STATS 1
20 #endif
21 
22 
23 #include <iostream>
24 
25 #include <stxxl/bits/namespace.h>
26 #include <stxxl/bits/deprecated.h>
27 #include <stxxl/bits/common/mutex.h>
28 #include <stxxl/bits/common/timer.h>
29 #include <stxxl/bits/common/types.h>
30 #include <stxxl/bits/common/utils.h>
31 #include <stxxl/bits/unused.h>
32 #include <stxxl/bits/singleton.h>
33 
34 
35 __STXXL_BEGIN_NAMESPACE
36 
40 
43 class stats : public singleton<stats>
44 {
45  friend class singleton<stats>;
46 
47  unsigned reads, writes; // number of operations
48  int64 volume_read, volume_written; // number of bytes read/written
49  unsigned c_reads, c_writes; // number of cached operations
50  int64 c_volume_read, c_volume_written; // number of bytes read/written from/to cache
51  double t_reads, t_writes; // seconds spent in operations
52  double p_reads, p_writes; // seconds spent in parallel operations
53  double p_begin_read, p_begin_write; // start time of parallel operation
54  double p_ios; // seconds spent in all parallel I/O operations (read and write)
55  double p_begin_io;
56  double t_waits, p_waits; // seconds spent waiting for completion of I/O operations
57  double p_begin_wait;
58  double t_wait_read, p_wait_read;
59  double p_begin_wait_read;
60  double t_wait_write, p_wait_write;
61  double p_begin_wait_write;
62  int acc_reads, acc_writes; // number of requests, participating in parallel operation
63  int acc_ios;
64  int acc_waits;
65  int acc_wait_read, acc_wait_write;
66  double last_reset;
67  mutex read_mutex, write_mutex, io_mutex, wait_mutex;
68 
69  stats();
70 
71 public:
72  enum wait_op_type {
73  WAIT_OP_ANY,
74  WAIT_OP_READ,
75  WAIT_OP_WRITE
76  };
77 
78  class scoped_read_write_timer
79  {
80  typedef unsigned_type size_type;
81 
82  bool is_write;
83 #if STXXL_IO_STATS
84  bool running;
85 #endif
86 
87  public:
88  scoped_read_write_timer(size_type size, bool is_write = false)
89  : is_write(is_write)
90 #if STXXL_IO_STATS
91  , running(false)
92 #endif
93  {
94  start(size);
95  }
96 
97  ~scoped_read_write_timer()
98  {
99  stop();
100  }
101 
102  void start(size_type size)
103  {
104 #if STXXL_IO_STATS
105  if (!running) {
106  running = true;
107  if (is_write)
108  stats::get_instance()->write_started(size);
109  else
110  stats::get_instance()->read_started(size);
111  }
112 #else
113  STXXL_UNUSED(size);
114 #endif
115  }
116 
117  void stop()
118  {
119 #if STXXL_IO_STATS
120  if (running) {
121  if (is_write)
122  stats::get_instance()->write_finished();
123  else
124  stats::get_instance()->read_finished();
125  running = false;
126  }
127 #endif
128  }
129  };
130 
131  class scoped_write_timer
132  {
133  typedef unsigned_type size_type;
134 
135 #if STXXL_IO_STATS
136  bool running;
137 #endif
138 
139  public:
140  scoped_write_timer(size_type size)
141 #if STXXL_IO_STATS
142  : running(false)
143 #endif
144  {
145  start(size);
146  }
147 
148  ~scoped_write_timer()
149  {
150  stop();
151  }
152 
153  void start(size_type size)
154  {
155 #if STXXL_IO_STATS
156  if (!running) {
157  running = true;
158  stats::get_instance()->write_started(size);
159  }
160 #else
161  STXXL_UNUSED(size);
162 #endif
163  }
164 
165  void stop()
166  {
167 #if STXXL_IO_STATS
168  if (running) {
169  stats::get_instance()->write_finished();
170  running = false;
171  }
172 #endif
173  }
174  };
175 
176  class scoped_read_timer
177  {
178  typedef unsigned_type size_type;
179 
180 #if STXXL_IO_STATS
181  bool running;
182 #endif
183 
184  public:
185  scoped_read_timer(size_type size)
186 #if STXXL_IO_STATS
187  : running(false)
188 #endif
189  {
190  start(size);
191  }
192 
193  ~scoped_read_timer()
194  {
195  stop();
196  }
197 
198  void start(size_type size)
199  {
200 #if STXXL_IO_STATS
201  if (!running) {
202  running = true;
203  stats::get_instance()->read_started(size);
204  }
205 #else
206  STXXL_UNUSED(size);
207 #endif
208  }
209 
210  void stop()
211  {
212 #if STXXL_IO_STATS
213  if (running) {
214  stats::get_instance()->read_finished();
215  running = false;
216  }
217 #endif
218  }
219  };
220 
221  class scoped_wait_timer
222  {
223 #ifndef STXXL_DO_NOT_COUNT_WAIT_TIME
224  bool running;
225  wait_op_type wait_op;
226 #endif
227 
228  public:
229  scoped_wait_timer(wait_op_type wait_op, bool measure_time = true)
230 #ifndef STXXL_DO_NOT_COUNT_WAIT_TIME
231  : running(false), wait_op(wait_op)
232 #endif
233  {
234  if (measure_time)
235  start();
236  }
237 
238  ~scoped_wait_timer()
239  {
240  stop();
241  }
242 
243  void start()
244  {
245 #ifndef STXXL_DO_NOT_COUNT_WAIT_TIME
246  if (!running) {
247  running = true;
248  stats::get_instance()->wait_started(wait_op);
249  }
250 #endif
251  }
252 
253  void stop()
254  {
255 #ifndef STXXL_DO_NOT_COUNT_WAIT_TIME
256  if (running) {
257  stats::get_instance()->wait_finished(wait_op);
258  running = false;
259  }
260 #endif
261  }
262  };
263 
264 public:
267  unsigned get_reads() const
268  {
269  return reads;
270  }
271 
274  unsigned get_writes() const
275  {
276  return writes;
277  }
278 
281  int64 get_read_volume() const
282  {
283  return volume_read;
284  }
285 
288  int64 get_written_volume() const
289  {
290  return volume_written;
291  }
292 
295  unsigned get_cached_reads() const
296  {
297  return c_reads;
298  }
299 
302  unsigned get_cached_writes() const
303  {
304  return c_writes;
305  }
306 
310  {
311  return c_volume_read;
312  }
313 
317  {
318  return c_volume_written;
319  }
320 
323  double get_read_time() const
324  {
325  return t_reads;
326  }
327 
330  double get_write_time() const
331  {
332  return t_writes;
333  }
334 
337  double get_pread_time() const
338  {
339  return p_reads;
340  }
341 
344  double get_pwrite_time() const
345  {
346  return p_writes;
347  }
348 
351  double get_pio_time() const
352  {
353  return p_ios;
354  }
355 
361  double get_io_wait_time() const
362  {
363  return t_waits;
364  }
365 
366  double get_wait_read_time() const
367  {
368  return t_wait_read;
369  }
370 
371  double get_wait_write_time() const
372  {
373  return t_wait_write;
374  }
375 
378  double get_last_reset_time() const
379  {
380  return last_reset;
381  }
382 
383 #ifndef STXXL_IO_STATS_RESET_FORBIDDEN
384  _STXXL_DEPRECATED(void reset());
386 #endif
387 
389  _STXXL_DEPRECATED(void _reset_io_wait_time());
390 
391  // for library use
392  void write_started(unsigned_type size_, double now = 0.0);
393  void write_canceled(unsigned_type size_);
394  void write_finished();
395  void write_cached(unsigned_type size_);
396  void read_started(unsigned_type size_, double now = 0.0);
397  void read_canceled(unsigned_type size_);
398  void read_finished();
399  void read_cached(unsigned_type size_);
400  void wait_started(wait_op_type wait_op);
401  void wait_finished(wait_op_type wait_op);
402 };
403 
404 #if !STXXL_IO_STATS
405 inline void stats::write_started(unsigned_type size_, double now)
406 {
407  STXXL_UNUSED(size_);
408  STXXL_UNUSED(now);
409 }
410 inline void stats::write_cached(unsigned_type size_)
411 {
412  STXXL_UNUSED(size_);
413 }
414 inline void stats::write_finished() { }
415 inline void stats::read_started(unsigned_type size_, double now)
416 {
417  STXXL_UNUSED(size_);
418  STXXL_UNUSED(now);
419 }
420 inline void stats::read_cached(unsigned_type size_)
421 {
422  STXXL_UNUSED(size_);
423 }
424 inline void stats::read_finished() { }
425 #endif
426 #ifdef STXXL_DO_NOT_COUNT_WAIT_TIME
427 inline void stats::wait_started(wait_op_type) { }
428 inline void stats::wait_finished(wait_op_type) { }
429 #endif
430 
431 
432 class stats_data
433 {
434  unsigned reads, writes; // number of operations
435  int64 volume_read, volume_written; // number of bytes read/written
436  unsigned c_reads, c_writes; // number of cached operations
437  int64 c_volume_read, c_volume_written; // number of bytes read/written from/to cache
438  double t_reads, t_writes; // seconds spent in operations
439  double p_reads, p_writes; // seconds spent in parallel operations
440  double p_ios; // seconds spent in all parallel I/O operations (read and write)
441  double t_wait; // seconds spent waiting for completion of I/O operations
442  double t_wait_read, t_wait_write; //
443  double elapsed;
444 
445 public:
446  stats_data() :
447  reads(0),
448  writes(0),
449  volume_read(0),
450  volume_written(0),
451  c_reads(0),
452  c_writes(0),
453  c_volume_read(0),
454  c_volume_written(0),
455  t_reads(0.0),
456  t_writes(0.0),
457  p_reads(0.0),
458  p_writes(0.0),
459  p_ios(0.0),
460  t_wait(0.0),
461  t_wait_read(0.0),
462  t_wait_write(0.0),
463  elapsed(0.0)
464  { }
465 
466  stats_data(const stats & s) :
467  reads(s.get_reads()),
468  writes(s.get_writes()),
469  volume_read(s.get_read_volume()),
470  volume_written(s.get_written_volume()),
471  c_reads(s.get_cached_reads()),
472  c_writes(s.get_cached_writes()),
473  c_volume_read(s.get_cached_read_volume()),
474  c_volume_written(s.get_cached_written_volume()),
475  t_reads(s.get_read_time()),
476  t_writes(s.get_write_time()),
477  p_reads(s.get_pread_time()),
478  p_writes(s.get_pwrite_time()),
479  p_ios(s.get_pio_time()),
480  t_wait(s.get_io_wait_time()),
481  t_wait_read(s.get_wait_read_time()),
482  t_wait_write(s.get_wait_write_time()),
483  elapsed(timestamp() - s.get_last_reset_time())
484  { }
485 
486  stats_data operator + (const stats_data & a) const
487  {
488  stats_data s;
489  s.reads = reads + a.reads;
490  s.writes = writes + a.writes;
491  s.volume_read = volume_read + a.volume_read;
492  s.volume_written = volume_written + a.volume_written;
493  s.c_reads = c_reads + a.c_reads;
494  s.c_writes = c_writes + a.c_writes;
495  s.c_volume_read = c_volume_read + a.c_volume_read;
496  s.c_volume_written = c_volume_written + a.c_volume_written;
497  s.t_reads = t_reads + a.t_reads;
498  s.t_writes = t_writes + a.t_writes;
499  s.p_reads = p_reads + a.p_reads;
500  s.p_writes = p_writes + a.p_writes;
501  s.p_ios = p_ios + a.p_ios;
502  s.t_wait = t_wait + a.t_wait;
503  s.t_wait_read = t_wait_read + a.t_wait_read;
504  s.t_wait_write = t_wait_write + a.t_wait_write;
505  s.elapsed = elapsed + a.elapsed;
506  return s;
507  }
508 
509  stats_data operator - (const stats_data & a) const
510  {
511  stats_data s;
512  s.reads = reads - a.reads;
513  s.writes = writes - a.writes;
514  s.volume_read = volume_read - a.volume_read;
515  s.volume_written = volume_written - a.volume_written;
516  s.c_reads = c_reads - a.c_reads;
517  s.c_writes = c_writes - a.c_writes;
518  s.c_volume_read = c_volume_read - a.c_volume_read;
519  s.c_volume_written = c_volume_written - a.c_volume_written;
520  s.t_reads = t_reads - a.t_reads;
521  s.t_writes = t_writes - a.t_writes;
522  s.p_reads = p_reads - a.p_reads;
523  s.p_writes = p_writes - a.p_writes;
524  s.p_ios = p_ios - a.p_ios;
525  s.t_wait = t_wait - a.t_wait;
526  s.t_wait_read = t_wait_read - a.t_wait_read;
527  s.t_wait_write = t_wait_write - a.t_wait_write;
528  s.elapsed = elapsed - a.elapsed;
529  return s;
530  }
531 
532  unsigned get_reads() const
533  {
534  return reads;
535  }
536 
537  unsigned get_writes() const
538  {
539  return writes;
540  }
541 
542  int64 get_read_volume() const
543  {
544  return volume_read;
545  }
546 
547  int64 get_written_volume() const
548  {
549  return volume_written;
550  }
551 
552  unsigned get_cached_reads() const
553  {
554  return c_reads;
555  }
556 
557  unsigned get_cached_writes() const
558  {
559  return c_writes;
560  }
561 
562  int64 get_cached_read_volume() const
563  {
564  return c_volume_read;
565  }
566 
567  int64 get_cached_written_volume() const
568  {
569  return c_volume_written;
570  }
571 
572  double get_read_time() const
573  {
574  return t_reads;
575  }
576 
577  double get_write_time() const
578  {
579  return t_writes;
580  }
581 
582  double get_pread_time() const
583  {
584  return p_reads;
585  }
586 
587  double get_pwrite_time() const
588  {
589  return p_writes;
590  }
591 
592  double get_pio_time() const
593  {
594  return p_ios;
595  }
596 
597  double get_elapsed_time() const
598  {
599  return elapsed;
600  }
601 
602  double get_io_wait_time() const
603  {
604  return t_wait;
605  }
606 
607  double get_wait_read_time() const
608  {
609  return t_wait_read;
610  }
611 
612  double get_wait_write_time() const
613  {
614  return t_wait_write;
615  }
616 };
617 
618 std::ostream & operator << (std::ostream & o, const stats_data & s);
619 
620 inline std::ostream & operator << (std::ostream & o, const stats & s)
621 {
622  o << stxxl::stats_data(s);
623  return o;
624 }
625 
626 std::string format_with_SI_IEC_unit_multiplier(uint64 number, const char * unit = "", int multiplier = 1000);
627 
628 inline std::string add_IEC_binary_multiplier(uint64 number, const char * unit = "")
629 {
630  return format_with_SI_IEC_unit_multiplier(number, unit, 1024);
631 }
632 
633 inline std::string add_SI_multiplier(uint64 number, const char * unit = "")
634 {
635  return format_with_SI_IEC_unit_multiplier(number, unit, 1000);
636 }
637 
639 
640 __STXXL_END_NAMESPACE
641 
642 #endif // !STXXL_IOSTATS_HEADER
643 // vim: et:ts=4:sw=4
_STXXL_DEPRECATED(void reset())
Resets I/O time counters (including I/O wait counter)
double get_pread_time() const
Period of time when at least one I/O thread was executing a read.
Definition: iostats.h:337
double get_write_time() const
Time that would be spent in write syscalls if all parallel writes were serialized.
Definition: iostats.h:330
int64 get_written_volume() const
Returns number of bytes written to the disks.
Definition: iostats.h:288
double get_last_reset_time() const
Return time of the last reset.
Definition: iostats.h:378
int64 get_read_volume() const
Returns number of bytes read from disks.
Definition: iostats.h:281
double get_read_time() const
Time that would be spent in read syscalls if all parallel reads were serialized.
Definition: iostats.h:323
double get_io_wait_time() const
I/O wait time counter.
Definition: iostats.h:361
unsigned get_writes() const
Returns total number of writes.
Definition: iostats.h:274
int64 get_cached_written_volume() const
Returns number of bytes written to the cache.
Definition: iostats.h:316
double get_pio_time() const
Period of time when at least one I/O thread was executing a read or a write.
Definition: iostats.h:351
int64 get_cached_read_volume() const
Returns number of bytes read from cache.
Definition: iostats.h:309
Collects various I/O statistics.
Definition: iostats.h:43
double get_pwrite_time() const
Period of time when at least one I/O thread was executing a write.
Definition: iostats.h:344
unsigned get_cached_reads() const
Returns total number of reads served from cache.
Definition: iostats.h:295
unsigned get_cached_writes() const
Returns total number of cached writes.
Definition: iostats.h:302
unsigned get_reads() const
Returns total number of reads.
Definition: iostats.h:267