Stxxl 1.2.1
|
00001 /*************************************************************************** 00002 * include/stxxl/bits/io/iostats.h 00003 * 00004 * Part of the STXXL. See http://stxxl.sourceforge.net 00005 * 00006 * Copyright (C) 2002-2004 Roman Dementiev <dementiev@mpi-sb.mpg.de> 00007 * Copyright (C) 2008 Andreas Beckmann <beckmann@mpi-inf.mpg.de> 00008 * 00009 * Distributed under the Boost Software License, Version 1.0. 00010 * (See accompanying file LICENSE_1_0.txt or copy at 00011 * http://www.boost.org/LICENSE_1_0.txt) 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/types.h> 00027 #include <stxxl/bits/common/utils.h> 00028 #include <stxxl/bits/singleton.h> 00029 00030 00031 __STXXL_BEGIN_NAMESPACE 00032 00036 00039 class stats : public singleton<stats> 00040 { 00041 friend class singleton<stats>; 00042 00043 unsigned reads, writes; // number of operations 00044 int64 volume_read, volume_written; // number of bytes read/written 00045 double t_reads, t_writes; // seconds spent in operations 00046 double p_reads, p_writes; // seconds spent in parallel operations 00047 double p_begin_read, p_begin_write; // start time of parallel operation 00048 double p_ios; // seconds spent in all parallel I/O operations (read and write) 00049 double p_begin_io; 00050 double t_waits, p_waits; // seconds spent waiting for completion of I/O operations 00051 double p_begin_wait; 00052 int acc_reads, acc_writes; // number of requests, participating in parallel operation 00053 int acc_ios; 00054 int acc_waits; 00055 double last_reset; 00056 mutex read_mutex, write_mutex, io_mutex, wait_mutex; 00057 00058 stats(); 00059 00060 public: 00061 class scoped_write_timer 00062 { 00063 typedef unsigned_type size_type; 00064 00065 #if STXXL_IO_STATS 00066 bool running; 00067 #endif 00068 00069 public: 00070 scoped_write_timer(size_type size) 00071 #if STXXL_IO_STATS 00072 : running(false) 00073 #endif 00074 { 00075 start(size); 00076 } 00077 00078 ~scoped_write_timer() 00079 { 00080 stop(); 00081 } 00082 00083 void start(size_type size) 00084 { 00085 #if STXXL_IO_STATS 00086 if (!running) { 00087 running = true; 00088 stats::get_instance()->write_started(size); 00089 } 00090 #else 00091 UNUSED(size); 00092 #endif 00093 } 00094 00095 void stop() 00096 { 00097 #if STXXL_IO_STATS 00098 if (running) { 00099 stats::get_instance()->write_finished(); 00100 running = false; 00101 } 00102 #endif 00103 } 00104 }; 00105 00106 class scoped_read_timer 00107 { 00108 typedef unsigned_type size_type; 00109 00110 #if STXXL_IO_STATS 00111 bool running; 00112 #endif 00113 00114 public: 00115 scoped_read_timer(size_type size) 00116 #if STXXL_IO_STATS 00117 : running(false) 00118 #endif 00119 { 00120 start(size); 00121 } 00122 00123 ~scoped_read_timer() 00124 { 00125 stop(); 00126 } 00127 00128 void start(size_type size) 00129 { 00130 #if STXXL_IO_STATS 00131 if (!running) { 00132 running = true; 00133 stats::get_instance()->read_started(size); 00134 } 00135 #else 00136 UNUSED(size); 00137 #endif 00138 } 00139 00140 void stop() 00141 { 00142 #if STXXL_IO_STATS 00143 if (running) { 00144 stats::get_instance()->read_finished(); 00145 running = false; 00146 } 00147 #endif 00148 } 00149 }; 00150 00151 class scoped_wait_timer 00152 { 00153 #ifdef COUNT_WAIT_TIME 00154 bool running; 00155 #endif 00156 00157 public: 00158 scoped_wait_timer() 00159 #ifdef COUNT_WAIT_TIME 00160 : running(false) 00161 #endif 00162 { 00163 start(); 00164 } 00165 00166 ~scoped_wait_timer() 00167 { 00168 stop(); 00169 } 00170 00171 void start() 00172 { 00173 #ifdef COUNT_WAIT_TIME 00174 if (!running) { 00175 running = true; 00176 stats::get_instance()->wait_started(); 00177 } 00178 #endif 00179 } 00180 00181 void stop() 00182 { 00183 #ifdef COUNT_WAIT_TIME 00184 if (running) { 00185 stats::get_instance()->wait_finished(); 00186 running = false; 00187 } 00188 #endif 00189 } 00190 }; 00191 00192 public: 00195 unsigned get_reads() const 00196 { 00197 return reads; 00198 } 00199 00202 unsigned get_writes() const 00203 { 00204 return writes; 00205 } 00206 00209 int64 get_read_volume() const 00210 { 00211 return volume_read; 00212 } 00213 00216 int64 get_written_volume() const 00217 { 00218 return volume_written; 00219 } 00220 00223 double get_read_time() const 00224 { 00225 return t_reads; 00226 } 00227 00230 double get_write_time() const 00231 { 00232 return t_writes; 00233 } 00234 00237 double get_pread_time() const 00238 { 00239 return p_reads; 00240 } 00241 00244 double get_pwrite_time() const 00245 { 00246 return p_writes; 00247 } 00248 00251 double get_pio_time() const 00252 { 00253 return p_ios; 00254 } 00255 00261 double get_io_wait_time() const 00262 { 00263 return t_waits; 00264 } 00265 00268 double get_last_reset_time() const 00269 { 00270 return last_reset; 00271 } 00272 00274 void reset(); 00275 00277 __STXXL_DEPRECATED(void _reset_io_wait_time()); 00278 00279 // for library use 00280 void write_started(unsigned size_); 00281 void write_finished(); 00282 void read_started(unsigned size_); 00283 void read_finished(); 00284 void wait_started(); 00285 void wait_finished(); 00286 }; 00287 00288 #if !STXXL_IO_STATS 00289 inline void stats::write_started(unsigned size_) 00290 { 00291 UNUSED(size_); 00292 } 00293 inline void stats::write_finished() { } 00294 inline void stats::read_started(unsigned size_) 00295 { 00296 UNUSED(size_); 00297 } 00298 inline void stats::read_finished() { } 00299 #endif 00300 #ifndef COUNT_WAIT_TIME 00301 inline void stats::wait_started() { } 00302 inline void stats::wait_finished() { } 00303 #endif 00304 00305 00306 class stats_data 00307 { 00308 unsigned reads, writes; // number of operations 00309 int64 volume_read, volume_written; // number of bytes read/written 00310 double t_reads, t_writes; // seconds spent in operations 00311 double p_reads, p_writes; // seconds spent in parallel operations 00312 double p_ios; // seconds spent in all parallel I/O operations (read and write) 00313 double t_wait; // seconds spent waiting for completion of I/O operations 00314 double elapsed; 00315 00316 public: 00317 stats_data() : 00318 reads(0), 00319 writes(0), 00320 volume_read(0), 00321 volume_written(0), 00322 t_reads(0.0), 00323 t_writes(0.0), 00324 p_reads(0.0), 00325 p_writes(0.0), 00326 p_ios(0.0), 00327 t_wait(0.0), 00328 elapsed(0.0) 00329 { } 00330 00331 stats_data(const stats & s) : 00332 reads(s.get_reads()), 00333 writes(s.get_writes()), 00334 volume_read(s.get_read_volume()), 00335 volume_written(s.get_written_volume()), 00336 t_reads(s.get_read_time()), 00337 t_writes(s.get_write_time()), 00338 p_reads(s.get_pread_time()), 00339 p_writes(s.get_pwrite_time()), 00340 p_ios(s.get_pio_time()), 00341 t_wait(s.get_io_wait_time()), 00342 elapsed(timestamp() - s.get_last_reset_time()) 00343 { } 00344 00345 stats_data operator + (const stats_data & a) const 00346 { 00347 stats_data s; 00348 s.reads = reads + a.reads; 00349 s.writes = writes + a.writes; 00350 s.volume_read = volume_read + a.volume_read; 00351 s.volume_written = volume_written + a.volume_written; 00352 s.t_reads = t_reads + a.t_reads; 00353 s.t_writes = t_writes + a.t_writes; 00354 s.p_reads = p_reads + a.p_reads; 00355 s.p_writes = p_writes + a.p_writes; 00356 s.p_ios = p_ios + a.p_ios; 00357 s.t_wait = t_wait + a.t_wait; 00358 s.elapsed = elapsed + a.elapsed; 00359 return s; 00360 } 00361 00362 stats_data operator - (const stats_data & a) const 00363 { 00364 stats_data s; 00365 s.reads = reads - a.reads; 00366 s.writes = writes - a.writes; 00367 s.volume_read = volume_read - a.volume_read; 00368 s.volume_written = volume_written - a.volume_written; 00369 s.t_reads = t_reads - a.t_reads; 00370 s.t_writes = t_writes - a.t_writes; 00371 s.p_reads = p_reads - a.p_reads; 00372 s.p_writes = p_writes - a.p_writes; 00373 s.p_ios = p_ios - a.p_ios; 00374 s.t_wait = t_wait - a.t_wait; 00375 s.elapsed = elapsed - a.elapsed; 00376 return s; 00377 } 00378 00379 unsigned get_reads() const 00380 { 00381 return reads; 00382 } 00383 00384 unsigned get_writes() const 00385 { 00386 return writes; 00387 } 00388 00389 int64 get_read_volume() const 00390 { 00391 return volume_read; 00392 } 00393 00394 int64 get_written_volume() const 00395 { 00396 return volume_written; 00397 } 00398 00399 double get_read_time() const 00400 { 00401 return t_reads; 00402 } 00403 00404 double get_write_time() const 00405 { 00406 return t_writes; 00407 } 00408 00409 double get_pread_time() const 00410 { 00411 return p_reads; 00412 } 00413 00414 double get_pwrite_time() const 00415 { 00416 return p_writes; 00417 } 00418 00419 double get_pio_time() const 00420 { 00421 return p_ios; 00422 } 00423 00424 double get_elapsed_time() const 00425 { 00426 return elapsed; 00427 } 00428 00429 double get_io_wait_time() const 00430 { 00431 return t_wait; 00432 } 00433 }; 00434 00435 std::ostream & operator << (std::ostream & o, const stats_data & s); 00436 00437 inline std::ostream & operator << (std::ostream & o, const stats & s) 00438 { 00439 o << stxxl::stats_data(s); 00440 return o; 00441 } 00442 00444 00445 __STXXL_END_NAMESPACE 00446 00447 #endif // !STXXL_IOSTATS_HEADER 00448 // vim: et:ts=4:sw=4