http://stxxl.sourceforge.net
<dementiev@mpi-sb.mpg.de>
<beckmann@cs.uni-frankfurt.de>
<singler@kit.edu>
http://www.boost.org/LICENSE_1_0.txt
#ifndef STXXL_IOSTATS_HEADER
#define STXXL_IOSTATS_HEADER
#ifndef STXXL_IO_STATS
#define STXXL_IO_STATS 1
#endif
#include <iostream>
#include <stxxl/bits/namespace.h>
#include <stxxl/bits/deprecated.h>
#include <stxxl/bits/common/mutex.h>
#include <stxxl/bits/common/timer.h>
#include <stxxl/bits/common/types.h>
#include <stxxl/bits/common/utils.h>
#include <stxxl/bits/unused.h>
#include <stxxl/bits/singleton.h>
__STXXL_BEGIN_NAMESPACE
class stats : public singleton<stats>
{
friend class singleton<stats>;
unsigned reads, writes;
int64 volume_read, volume_written;
unsigned c_reads, c_writes;
int64 c_volume_read, c_volume_written;
double t_reads, t_writes;
double p_reads, p_writes;
double p_begin_read, p_begin_write;
double p_ios;
double p_begin_io;
double t_waits, p_waits;
double p_begin_wait;
double t_wait_read, p_wait_read;
double p_begin_wait_read;
double t_wait_write, p_wait_write;
double p_begin_wait_write;
int acc_reads, acc_writes;
int acc_ios;
int acc_waits;
int acc_wait_read, acc_wait_write;
double last_reset;
mutex read_mutex, write_mutex, io_mutex, wait_mutex;
stats();
public:
enum wait_op_type {
WAIT_OP_ANY,
WAIT_OP_READ,
WAIT_OP_WRITE
};
class scoped_read_write_timer
{
typedef unsigned_type size_type;
bool is_write;
#if STXXL_IO_STATS
bool running;
#endif
public:
scoped_read_write_timer(size_type size, bool is_write = false)
: is_write(is_write)
#if STXXL_IO_STATS
, running(false)
#endif
{
start(size);
}
~scoped_read_write_timer()
{
stop();
}
void start(size_type size)
{
#if STXXL_IO_STATS
if (!running) {
running = true;
if (is_write)
stats::get_instance()->write_started(size);
else
stats::get_instance()->read_started(size);
}
#else
STXXL_UNUSED(size);
#endif
}
void stop()
{
#if STXXL_IO_STATS
if (running) {
if (is_write)
stats::get_instance()->write_finished();
else
stats::get_instance()->read_finished();
running = false;
}
#endif
}
};
class scoped_write_timer
{
typedef unsigned_type size_type;
#if STXXL_IO_STATS
bool running;
#endif
public:
scoped_write_timer(size_type size)
#if STXXL_IO_STATS
: running(false)
#endif
{
start(size);
}
~scoped_write_timer()
{
stop();
}
void start(size_type size)
{
#if STXXL_IO_STATS
if (!running) {
running = true;
stats::get_instance()->write_started(size);
}
#else
STXXL_UNUSED(size);
#endif
}
void stop()
{
#if STXXL_IO_STATS
if (running) {
stats::get_instance()->write_finished();
running = false;
}
#endif
}
};
class scoped_read_timer
{
typedef unsigned_type size_type;
#if STXXL_IO_STATS
bool running;
#endif
public:
scoped_read_timer(size_type size)
#if STXXL_IO_STATS
: running(false)
#endif
{
start(size);
}
~scoped_read_timer()
{
stop();
}
void start(size_type size)
{
#if STXXL_IO_STATS
if (!running) {
running = true;
stats::get_instance()->read_started(size);
}
#else
STXXL_UNUSED(size);
#endif
}
void stop()
{
#if STXXL_IO_STATS
if (running) {
stats::get_instance()->read_finished();
running = false;
}
#endif
}
};
class scoped_wait_timer
{
#ifndef STXXL_DO_NOT_COUNT_WAIT_TIME
bool running;
wait_op_type wait_op;
#endif
public:
scoped_wait_timer(wait_op_type wait_op, bool measure_time = true)
#ifndef STXXL_DO_NOT_COUNT_WAIT_TIME
: running(false), wait_op(wait_op)
#endif
{
if (measure_time)
start();
}
~scoped_wait_timer()
{
stop();
}
void start()
{
#ifndef STXXL_DO_NOT_COUNT_WAIT_TIME
if (!running) {
running = true;
stats::get_instance()->wait_started(wait_op);
}
#endif
}
void stop()
{
#ifndef STXXL_DO_NOT_COUNT_WAIT_TIME
if (running) {
stats::get_instance()->wait_finished(wait_op);
running = false;
}
#endif
}
};
public:
unsigned get_reads() const
{
return reads;
}
unsigned get_writes() const
{
return writes;
}
int64 get_read_volume() const
{
return volume_read;
}
int64 get_written_volume() const
{
return volume_written;
}
unsigned get_cached_reads() const
{
return c_reads;
}
unsigned get_cached_writes() const
{
return c_writes;
}
int64 get_cached_read_volume() const
{
return c_volume_read;
}
int64 get_cached_written_volume() const
{
return c_volume_written;
}
double get_read_time() const
{
return t_reads;
}
double get_write_time() const
{
return t_writes;
}
double get_pread_time() const
{
return p_reads;
}
double get_pwrite_time() const
{
return p_writes;
}
double get_pio_time() const
{
return p_ios;
}
double get_io_wait_time() const
{
return t_waits;
}
double get_wait_read_time() const
{
return t_wait_read;
}
double get_wait_write_time() const
{
return t_wait_write;
}
double get_last_reset_time() const
{
return last_reset;
}
#ifndef STXXL_IO_STATS_RESET_FORBIDDEN
_STXXL_DEPRECATED(void reset());
#endif
_STXXL_DEPRECATED(void _reset_io_wait_time());
void write_started(unsigned_type size_, double now = 0.0);
void write_canceled(unsigned_type size_);
void write_finished();
void write_cached(unsigned_type size_);
void read_started(unsigned_type size_, double now = 0.0);
void read_canceled(unsigned_type size_);
void read_finished();
void read_cached(unsigned_type size_);
void wait_started(wait_op_type wait_op);
void wait_finished(wait_op_type wait_op);
};
#if !STXXL_IO_STATS
inline void stats::write_started(unsigned_type size_, double now)
{
STXXL_UNUSED(size_);
STXXL_UNUSED(now);
}
inline void stats::write_cached(unsigned_type size_)
{
STXXL_UNUSED(size_);
}
inline void stats::write_finished() { }
inline void stats::read_started(unsigned_type size_, double now)
{
STXXL_UNUSED(size_);
STXXL_UNUSED(now);
}
inline void stats::read_cached(unsigned_type size_)
{
STXXL_UNUSED(size_);
}
inline void stats::read_finished() { }
#endif
#ifdef STXXL_DO_NOT_COUNT_WAIT_TIME
inline void stats::wait_started(wait_op_type) { }
inline void stats::wait_finished(wait_op_type) { }
#endif
class stats_data
{
unsigned reads, writes;
int64 volume_read, volume_written;
unsigned c_reads, c_writes;
int64 c_volume_read, c_volume_written;
double t_reads, t_writes;
double p_reads, p_writes;
double p_ios;
double t_wait;
double t_wait_read, t_wait_write;
double elapsed;
public:
stats_data() :
reads(0),
writes(0),
volume_read(0),
volume_written(0),
c_reads(0),
c_writes(0),
c_volume_read(0),
c_volume_written(0),
t_reads(0.0),
t_writes(0.0),
p_reads(0.0),
p_writes(0.0),
p_ios(0.0),
t_wait(0.0),
t_wait_read(0.0),
t_wait_write(0.0),
elapsed(0.0)
{ }
stats_data(const stats & s) :
reads(s.get_reads()),
writes(s.get_writes()),
volume_read(s.get_read_volume()),
volume_written(s.get_written_volume()),
c_reads(s.get_cached_reads()),
c_writes(s.get_cached_writes()),
c_volume_read(s.get_cached_read_volume()),
c_volume_written(s.get_cached_written_volume()),
t_reads(s.get_read_time()),
t_writes(s.get_write_time()),
p_reads(s.get_pread_time()),
p_writes(s.get_pwrite_time()),
p_ios(s.get_pio_time()),
t_wait(s.get_io_wait_time()),
t_wait_read(s.get_wait_read_time()),
t_wait_write(s.get_wait_write_time()),
elapsed(timestamp() - s.get_last_reset_time())
{ }
stats_data operator + (const stats_data & a) const
{
stats_data s;
s.reads = reads + a.reads;
s.writes = writes + a.writes;
s.volume_read = volume_read + a.volume_read;
s.volume_written = volume_written + a.volume_written;
s.c_reads = c_reads + a.c_reads;
s.c_writes = c_writes + a.c_writes;
s.c_volume_read = c_volume_read + a.c_volume_read;
s.c_volume_written = c_volume_written + a.c_volume_written;
s.t_reads = t_reads + a.t_reads;
s.t_writes = t_writes + a.t_writes;
s.p_reads = p_reads + a.p_reads;
s.p_writes = p_writes + a.p_writes;
s.p_ios = p_ios + a.p_ios;
s.t_wait = t_wait + a.t_wait;
s.t_wait_read = t_wait_read + a.t_wait_read;
s.t_wait_write = t_wait_write + a.t_wait_write;
s.elapsed = elapsed + a.elapsed;
return s;
}
stats_data operator - (const stats_data & a) const
{
stats_data s;
s.reads = reads - a.reads;
s.writes = writes - a.writes;
s.volume_read = volume_read - a.volume_read;
s.volume_written = volume_written - a.volume_written;
s.c_reads = c_reads - a.c_reads;
s.c_writes = c_writes - a.c_writes;
s.c_volume_read = c_volume_read - a.c_volume_read;
s.c_volume_written = c_volume_written - a.c_volume_written;
s.t_reads = t_reads - a.t_reads;
s.t_writes = t_writes - a.t_writes;
s.p_reads = p_reads - a.p_reads;
s.p_writes = p_writes - a.p_writes;
s.p_ios = p_ios - a.p_ios;
s.t_wait = t_wait - a.t_wait;
s.t_wait_read = t_wait_read - a.t_wait_read;
s.t_wait_write = t_wait_write - a.t_wait_write;
s.elapsed = elapsed - a.elapsed;
return s;
}
unsigned get_reads() const
{
return reads;
}
unsigned get_writes() const
{
return writes;
}
int64 get_read_volume() const
{
return volume_read;
}
int64 get_written_volume() const
{
return volume_written;
}
unsigned get_cached_reads() const
{
return c_reads;
}
unsigned get_cached_writes() const
{
return c_writes;
}
int64 get_cached_read_volume() const
{
return c_volume_read;
}
int64 get_cached_written_volume() const
{
return c_volume_written;
}
double get_read_time() const
{
return t_reads;
}
double get_write_time() const
{
return t_writes;
}
double get_pread_time() const
{
return p_reads;
}
double get_pwrite_time() const
{
return p_writes;
}
double get_pio_time() const
{
return p_ios;
}
double get_elapsed_time() const
{
return elapsed;
}
double get_io_wait_time() const
{
return t_wait;
}
double get_wait_read_time() const
{
return t_wait_read;
}
double get_wait_write_time() const
{
return t_wait_write;
}
};
std::ostream & operator << (std::ostream & o, const stats_data & s);
inline std::ostream & operator << (std::ostream & o, const stats & s)
{
o << stxxl::stats_data(s);
return o;
}
std::string format_with_SI_IEC_unit_multiplier(uint64 number, const char * unit = "", int multiplier = 1000);
inline std::string add_IEC_binary_multiplier(uint64 number, const char * unit = "")
{
return format_with_SI_IEC_unit_multiplier(number, unit, 1024);
}
inline std::string add_SI_multiplier(uint64 number, const char * unit = "")
{
return format_with_SI_IEC_unit_multiplier(number, unit, 1000);
}
__STXXL_END_NAMESPACE
#endif