00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef STXXL_IOSTATS_HEADER
00016 #define STXXL_IOSTATS_HEADER
00017
00018 #ifndef STXXL_IO_STATS
00019 #define STXXL_IO_STATS 1
00020 #endif
00021
00022
00023 #include <iostream>
00024
00025 #include <stxxl/bits/namespace.h>
00026 #include <stxxl/bits/deprecated.h>
00027 #include <stxxl/bits/common/mutex.h>
00028 #include <stxxl/bits/common/timer.h>
00029 #include <stxxl/bits/common/types.h>
00030 #include <stxxl/bits/common/utils.h>
00031 #include <stxxl/bits/unused.h>
00032 #include <stxxl/bits/singleton.h>
00033
00034
00035 __STXXL_BEGIN_NAMESPACE
00036
00040
00043 class stats : public singleton<stats>
00044 {
00045 friend class singleton<stats>;
00046
00047 unsigned reads, writes;
00048 int64 volume_read, volume_written;
00049 unsigned c_reads, c_writes;
00050 int64 c_volume_read, c_volume_written;
00051 double t_reads, t_writes;
00052 double p_reads, p_writes;
00053 double p_begin_read, p_begin_write;
00054 double p_ios;
00055 double p_begin_io;
00056 double t_waits, p_waits;
00057 double p_begin_wait;
00058 double t_wait_read, p_wait_read;
00059 double p_begin_wait_read;
00060 double t_wait_write, p_wait_write;
00061 double p_begin_wait_write;
00062 int acc_reads, acc_writes;
00063 int acc_ios;
00064 int acc_waits;
00065 int acc_wait_read, acc_wait_write;
00066 double last_reset;
00067 mutex read_mutex, write_mutex, io_mutex, wait_mutex;
00068
00069 stats();
00070
00071 public:
00072 enum wait_op_type {
00073 WAIT_OP_ANY,
00074 WAIT_OP_READ,
00075 WAIT_OP_WRITE
00076 };
00077
00078 class scoped_read_write_timer
00079 {
00080 typedef unsigned_type size_type;
00081
00082 bool is_write;
00083 #if STXXL_IO_STATS
00084 bool running;
00085 #endif
00086
00087 public:
00088 scoped_read_write_timer(size_type size, bool is_write = false)
00089 : is_write(is_write)
00090 #if STXXL_IO_STATS
00091 , running(false)
00092 #endif
00093 {
00094 start(size);
00095 }
00096
00097 ~scoped_read_write_timer()
00098 {
00099 stop();
00100 }
00101
00102 void start(size_type size)
00103 {
00104 #if STXXL_IO_STATS
00105 if (!running) {
00106 running = true;
00107 if (is_write)
00108 stats::get_instance()->write_started(size);
00109 else
00110 stats::get_instance()->read_started(size);
00111 }
00112 #else
00113 STXXL_UNUSED(size);
00114 #endif
00115 }
00116
00117 void stop()
00118 {
00119 #if STXXL_IO_STATS
00120 if (running) {
00121 if (is_write)
00122 stats::get_instance()->write_finished();
00123 else
00124 stats::get_instance()->read_finished();
00125 running = false;
00126 }
00127 #endif
00128 }
00129 };
00130
00131 class scoped_write_timer
00132 {
00133 typedef unsigned_type size_type;
00134
00135 #if STXXL_IO_STATS
00136 bool running;
00137 #endif
00138
00139 public:
00140 scoped_write_timer(size_type size)
00141 #if STXXL_IO_STATS
00142 : running(false)
00143 #endif
00144 {
00145 start(size);
00146 }
00147
00148 ~scoped_write_timer()
00149 {
00150 stop();
00151 }
00152
00153 void start(size_type size)
00154 {
00155 #if STXXL_IO_STATS
00156 if (!running) {
00157 running = true;
00158 stats::get_instance()->write_started(size);
00159 }
00160 #else
00161 STXXL_UNUSED(size);
00162 #endif
00163 }
00164
00165 void stop()
00166 {
00167 #if STXXL_IO_STATS
00168 if (running) {
00169 stats::get_instance()->write_finished();
00170 running = false;
00171 }
00172 #endif
00173 }
00174 };
00175
00176 class scoped_read_timer
00177 {
00178 typedef unsigned_type size_type;
00179
00180 #if STXXL_IO_STATS
00181 bool running;
00182 #endif
00183
00184 public:
00185 scoped_read_timer(size_type size)
00186 #if STXXL_IO_STATS
00187 : running(false)
00188 #endif
00189 {
00190 start(size);
00191 }
00192
00193 ~scoped_read_timer()
00194 {
00195 stop();
00196 }
00197
00198 void start(size_type size)
00199 {
00200 #if STXXL_IO_STATS
00201 if (!running) {
00202 running = true;
00203 stats::get_instance()->read_started(size);
00204 }
00205 #else
00206 STXXL_UNUSED(size);
00207 #endif
00208 }
00209
00210 void stop()
00211 {
00212 #if STXXL_IO_STATS
00213 if (running) {
00214 stats::get_instance()->read_finished();
00215 running = false;
00216 }
00217 #endif
00218 }
00219 };
00220
00221 class scoped_wait_timer
00222 {
00223 #ifndef STXXL_DO_NOT_COUNT_WAIT_TIME
00224 bool running;
00225 wait_op_type wait_op;
00226 #endif
00227
00228 public:
00229 scoped_wait_timer(wait_op_type wait_op, bool measure_time = true)
00230 #ifndef STXXL_DO_NOT_COUNT_WAIT_TIME
00231 : running(false), wait_op(wait_op)
00232 #endif
00233 {
00234 if (measure_time)
00235 start();
00236 }
00237
00238 ~scoped_wait_timer()
00239 {
00240 stop();
00241 }
00242
00243 void start()
00244 {
00245 #ifndef STXXL_DO_NOT_COUNT_WAIT_TIME
00246 if (!running) {
00247 running = true;
00248 stats::get_instance()->wait_started(wait_op);
00249 }
00250 #endif
00251 }
00252
00253 void stop()
00254 {
00255 #ifndef STXXL_DO_NOT_COUNT_WAIT_TIME
00256 if (running) {
00257 stats::get_instance()->wait_finished(wait_op);
00258 running = false;
00259 }
00260 #endif
00261 }
00262 };
00263
00264 public:
00267 unsigned get_reads() const
00268 {
00269 return reads;
00270 }
00271
00274 unsigned get_writes() const
00275 {
00276 return writes;
00277 }
00278
00281 int64 get_read_volume() const
00282 {
00283 return volume_read;
00284 }
00285
00288 int64 get_written_volume() const
00289 {
00290 return volume_written;
00291 }
00292
00295 unsigned get_cached_reads() const
00296 {
00297 return c_reads;
00298 }
00299
00302 unsigned get_cached_writes() const
00303 {
00304 return c_writes;
00305 }
00306
00309 int64 get_cached_read_volume() const
00310 {
00311 return c_volume_read;
00312 }
00313
00316 int64 get_cached_written_volume() const
00317 {
00318 return c_volume_written;
00319 }
00320
00323 double get_read_time() const
00324 {
00325 return t_reads;
00326 }
00327
00330 double get_write_time() const
00331 {
00332 return t_writes;
00333 }
00334
00337 double get_pread_time() const
00338 {
00339 return p_reads;
00340 }
00341
00344 double get_pwrite_time() const
00345 {
00346 return p_writes;
00347 }
00348
00351 double get_pio_time() const
00352 {
00353 return p_ios;
00354 }
00355
00361 double get_io_wait_time() const
00362 {
00363 return t_waits;
00364 }
00365
00366 double get_wait_read_time() const
00367 {
00368 return t_wait_read;
00369 }
00370
00371 double get_wait_write_time() const
00372 {
00373 return t_wait_write;
00374 }
00375
00378 double get_last_reset_time() const
00379 {
00380 return last_reset;
00381 }
00382
00383 #ifndef STXXL_IO_STATS_RESET_FORBIDDEN
00384
00385 _STXXL_DEPRECATED(void reset());
00386 #endif
00387
00389 _STXXL_DEPRECATED(void _reset_io_wait_time());
00390
00391
00392 void write_started(unsigned_type size_, double now = 0.0);
00393 void write_canceled(unsigned_type size_);
00394 void write_finished();
00395 void write_cached(unsigned_type size_);
00396 void read_started(unsigned_type size_, double now = 0.0);
00397 void read_canceled(unsigned_type size_);
00398 void read_finished();
00399 void read_cached(unsigned_type size_);
00400 void wait_started(wait_op_type wait_op);
00401 void wait_finished(wait_op_type wait_op);
00402 };
00403
00404 #if !STXXL_IO_STATS
00405 inline void stats::write_started(unsigned_type size_, double now)
00406 {
00407 STXXL_UNUSED(size_);
00408 STXXL_UNUSED(now);
00409 }
00410 inline void stats::write_cached(unsigned_type size_)
00411 {
00412 STXXL_UNUSED(size_);
00413 }
00414 inline void stats::write_finished() { }
00415 inline void stats::read_started(unsigned_type size_, double now)
00416 {
00417 STXXL_UNUSED(size_);
00418 STXXL_UNUSED(now);
00419 }
00420 inline void stats::read_cached(unsigned_type size_)
00421 {
00422 STXXL_UNUSED(size_);
00423 }
00424 inline void stats::read_finished() { }
00425 #endif
00426 #ifdef STXXL_DO_NOT_COUNT_WAIT_TIME
00427 inline void stats::wait_started(wait_op_type) { }
00428 inline void stats::wait_finished(wait_op_type) { }
00429 #endif
00430
00431
00432 class stats_data
00433 {
00434 unsigned reads, writes;
00435 int64 volume_read, volume_written;
00436 unsigned c_reads, c_writes;
00437 int64 c_volume_read, c_volume_written;
00438 double t_reads, t_writes;
00439 double p_reads, p_writes;
00440 double p_ios;
00441 double t_wait;
00442 double t_wait_read, t_wait_write;
00443 double elapsed;
00444
00445 public:
00446 stats_data() :
00447 reads(0),
00448 writes(0),
00449 volume_read(0),
00450 volume_written(0),
00451 c_reads(0),
00452 c_writes(0),
00453 c_volume_read(0),
00454 c_volume_written(0),
00455 t_reads(0.0),
00456 t_writes(0.0),
00457 p_reads(0.0),
00458 p_writes(0.0),
00459 p_ios(0.0),
00460 t_wait(0.0),
00461 t_wait_read(0.0),
00462 t_wait_write(0.0),
00463 elapsed(0.0)
00464 { }
00465
00466 stats_data(const stats & s) :
00467 reads(s.get_reads()),
00468 writes(s.get_writes()),
00469 volume_read(s.get_read_volume()),
00470 volume_written(s.get_written_volume()),
00471 c_reads(s.get_cached_reads()),
00472 c_writes(s.get_cached_writes()),
00473 c_volume_read(s.get_cached_read_volume()),
00474 c_volume_written(s.get_cached_written_volume()),
00475 t_reads(s.get_read_time()),
00476 t_writes(s.get_write_time()),
00477 p_reads(s.get_pread_time()),
00478 p_writes(s.get_pwrite_time()),
00479 p_ios(s.get_pio_time()),
00480 t_wait(s.get_io_wait_time()),
00481 t_wait_read(s.get_wait_read_time()),
00482 t_wait_write(s.get_wait_write_time()),
00483 elapsed(timestamp() - s.get_last_reset_time())
00484 { }
00485
00486 stats_data operator + (const stats_data & a) const
00487 {
00488 stats_data s;
00489 s.reads = reads + a.reads;
00490 s.writes = writes + a.writes;
00491 s.volume_read = volume_read + a.volume_read;
00492 s.volume_written = volume_written + a.volume_written;
00493 s.c_reads = c_reads + a.c_reads;
00494 s.c_writes = c_writes + a.c_writes;
00495 s.c_volume_read = c_volume_read + a.c_volume_read;
00496 s.c_volume_written = c_volume_written + a.c_volume_written;
00497 s.t_reads = t_reads + a.t_reads;
00498 s.t_writes = t_writes + a.t_writes;
00499 s.p_reads = p_reads + a.p_reads;
00500 s.p_writes = p_writes + a.p_writes;
00501 s.p_ios = p_ios + a.p_ios;
00502 s.t_wait = t_wait + a.t_wait;
00503 s.t_wait_read = t_wait_read + a.t_wait_read;
00504 s.t_wait_write = t_wait_write + a.t_wait_write;
00505 s.elapsed = elapsed + a.elapsed;
00506 return s;
00507 }
00508
00509 stats_data operator - (const stats_data & a) const
00510 {
00511 stats_data s;
00512 s.reads = reads - a.reads;
00513 s.writes = writes - a.writes;
00514 s.volume_read = volume_read - a.volume_read;
00515 s.volume_written = volume_written - a.volume_written;
00516 s.c_reads = c_reads - a.c_reads;
00517 s.c_writes = c_writes - a.c_writes;
00518 s.c_volume_read = c_volume_read - a.c_volume_read;
00519 s.c_volume_written = c_volume_written - a.c_volume_written;
00520 s.t_reads = t_reads - a.t_reads;
00521 s.t_writes = t_writes - a.t_writes;
00522 s.p_reads = p_reads - a.p_reads;
00523 s.p_writes = p_writes - a.p_writes;
00524 s.p_ios = p_ios - a.p_ios;
00525 s.t_wait = t_wait - a.t_wait;
00526 s.t_wait_read = t_wait_read - a.t_wait_read;
00527 s.t_wait_write = t_wait_write - a.t_wait_write;
00528 s.elapsed = elapsed - a.elapsed;
00529 return s;
00530 }
00531
00532 unsigned get_reads() const
00533 {
00534 return reads;
00535 }
00536
00537 unsigned get_writes() const
00538 {
00539 return writes;
00540 }
00541
00542 int64 get_read_volume() const
00543 {
00544 return volume_read;
00545 }
00546
00547 int64 get_written_volume() const
00548 {
00549 return volume_written;
00550 }
00551
00552 unsigned get_cached_reads() const
00553 {
00554 return c_reads;
00555 }
00556
00557 unsigned get_cached_writes() const
00558 {
00559 return c_writes;
00560 }
00561
00562 int64 get_cached_read_volume() const
00563 {
00564 return c_volume_read;
00565 }
00566
00567 int64 get_cached_written_volume() const
00568 {
00569 return c_volume_written;
00570 }
00571
00572 double get_read_time() const
00573 {
00574 return t_reads;
00575 }
00576
00577 double get_write_time() const
00578 {
00579 return t_writes;
00580 }
00581
00582 double get_pread_time() const
00583 {
00584 return p_reads;
00585 }
00586
00587 double get_pwrite_time() const
00588 {
00589 return p_writes;
00590 }
00591
00592 double get_pio_time() const
00593 {
00594 return p_ios;
00595 }
00596
00597 double get_elapsed_time() const
00598 {
00599 return elapsed;
00600 }
00601
00602 double get_io_wait_time() const
00603 {
00604 return t_wait;
00605 }
00606
00607 double get_wait_read_time() const
00608 {
00609 return t_wait_read;
00610 }
00611
00612 double get_wait_write_time() const
00613 {
00614 return t_wait_write;
00615 }
00616 };
00617
00618 std::ostream & operator << (std::ostream & o, const stats_data & s);
00619
00620 inline std::ostream & operator << (std::ostream & o, const stats & s)
00621 {
00622 o << stxxl::stats_data(s);
00623 return o;
00624 }
00625
00626 std::string format_with_SI_IEC_unit_multiplier(uint64 number, const char * unit = "", int multiplier = 1000);
00627
00628 inline std::string add_IEC_binary_multiplier(uint64 number, const char * unit = "")
00629 {
00630 return format_with_SI_IEC_unit_multiplier(number, unit, 1024);
00631 }
00632
00633 inline std::string add_SI_multiplier(uint64 number, const char * unit = "")
00634 {
00635 return format_with_SI_IEC_unit_multiplier(number, unit, 1000);
00636 }
00637
00639
00640 __STXXL_END_NAMESPACE
00641
00642 #endif // !STXXL_IOSTATS_HEADER
00643