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