summaryrefslogtreecommitdiff
path: root/base/statistics.cc
diff options
context:
space:
mode:
authorNathan Binkert <binkertn@umich.edu>2003-12-09 13:05:43 -0500
committerNathan Binkert <binkertn@umich.edu>2003-12-09 13:05:43 -0500
commit368de4109f9decca72faac1a6eb0909da712f43f (patch)
treeb7d842968d27019f6e304834662833676f8f2354 /base/statistics.cc
parentf8b78a81b952ed1953276290b48cbd053b084fcf (diff)
downloadgem5-368de4109f9decca72faac1a6eb0909da712f43f.tar.xz
Sweeping change in the stats package....again...
base/statistics.cc: - Merge the m5 display and simplescalar compatible display functions. - Use functors for the stats printing instead of functions. This gets rid of the very long argument lists and improves clarity. - Fix a bug in binning that caused an invalid allocation to occur. base/statistics.hh: - Instead of using a compile time variable to choose whether to print in ss compat mode, we use a runtime variable. This is how we'll choose python output. - There are no more virtual functions in the statistics themselves. All virtual functions have been moved into a secondary helper class. Every stat has an associated helper class that knows how to access certain variables in that stat. There is a hash_map from the stat to it's helper class data. This was done because the helper data is only used during setup, stats reset, and printing. All of which happen rarely, and you want to avoid any performance hit that you can. - To provide the name(), desc(), etc functions to classes so that the user can set various parameters to the stats class, a single class containing all of those functions was created. An odd trick was done to actually make this class derive from the stat class because a base class with no data actually does end up taking up space. - The detail namespace was removed for now. I'll put it back when the package is not in so much flux. - Standard deviation, and mean were added to all distribution stats. - There are several bugfixes and changes that aren't mentioned test/Makefile: Don't test sim_stats foo. test/stattest.cc: Don't test sim_stats foo. Fix bin usage so that it corresponds to the current usage. --HG-- extra : convert_revision : ce8d9a8d485a84d55799f253d851e83650684170
Diffstat (limited to 'base/statistics.cc')
-rw-r--r--base/statistics.cc1164
1 files changed, 616 insertions, 548 deletions
diff --git a/base/statistics.cc b/base/statistics.cc
index 737f8f73b..afe613455 100644
--- a/base/statistics.cc
+++ b/base/statistics.cc
@@ -63,108 +63,45 @@ using namespace std;
// This is a hack to get this parameter from the old stats package.
namespace Statistics {
bool PrintDescriptions = true;
+DisplayMode default_mode = mode_simplescalar;
-namespace Detail {
-/**
- * Struct to contain a name and description of statistic subfield.
- */
-struct SubData
-{
- /** Subfield name. */
- string name;
- /** Subfield desc. */
- string desc;
-};
-
-/**
- * Struct to contain print data of a Stat.
- */
-struct StatData
-{
- /**
- * Create this struct.
- */
- StatData();
- /**
- * Destructor.
- */
- ~StatData();
-
- /** True if the stat has been initialized. */
- bool init;
- /** True if the stat should be printed. */
- bool print;
- /** The name of the stat. */
- string name;
- /** Names and descriptions of subfields. */
- vector<SubData> *subdata;
- /** The description of the stat. */
- string desc;
- /** The display precision. */
- int precision;
- /** The formatting flags. */
- FormatFlags flags;
- /** A pointer to a prerequisite Stat. */
- const Stat *prereq;
-};
-
-StatData::StatData()
- : init(false), print(false), subdata(NULL), precision(-1), flags(none),
- prereq(NULL)
-{
-}
-
-StatData::~StatData()
-{
- if (subdata)
- delete subdata;
-}
-
-class Database
+namespace Database
{
- private:
- Database(const Database &) {}
-
- private:
- typedef list<Stat *> list_t;
- typedef map<const Stat *, StatData *> map_t;
-
- list<MainBin *> bins;
- map<const MainBin *, std::string > bin_names;
- list_t binnedStats;
+ class Data
+ {
+ private:
+ typedef list<StatData *> list_t;
+ typedef map<void *, StatData *> map_t;
- list_t allStats;
- list_t printStats;
- map_t statMap;
+ list<MainBin *> bins;
+ map<const MainBin *, string > bin_names;
+ list_t binnedStats;
- public:
- Database();
- ~Database();
+ list_t allStats;
+ list_t printStats;
+ map_t statMap;
- void dump(ostream &stream);
+ public:
+ void dump(ostream &stream);
- StatData *find(const Stat *stat);
- void check();
- void reset();
- void regStat(Stat *stat);
- StatData *print(Stat *stat);
- void regBin(MainBin *bin, std::string name);
-};
+ StatData *find(void *stat);
+ void mapStat(void *stat, StatData *data);
-Database::Database()
-{}
+ void check();
+ void reset();
+ void regBin(MainBin *bin, string name);
+ void regPrint(void *stat);
+ };
-Database::~Database()
-{}
void
-Database::dump(ostream &stream)
+Data::dump(ostream &stream)
{
#ifndef FS_MEASURE
list_t::iterator i = printStats.begin();
list_t::iterator end = printStats.end();
while (i != end) {
- Stat *stat = *i;
+ StatData *stat = *i;
if (stat->binned())
binnedStats.push_back(stat);
++i;
@@ -178,7 +115,7 @@ Database::dump(ostream &stream)
ccprintf(stream, "PRINTING BINNED STATS\n");
while (j != bins_end) {
(*j)->activate();
- map<const MainBin *, std::string>::const_iterator iter;
+ map<const MainBin *, string>::const_iterator iter;
iter = bin_names.find(*j);
if (iter == bin_names.end())
panic("a binned stat not found in names map!");
@@ -192,7 +129,7 @@ Database::dump(ostream &stream)
list_t::iterator end = binnedStats.end();
#endif
while (i != end) {
- Stat *stat = *i;
+ StatData *stat = *i;
if (stat->dodisplay())
stat->display(stream);
++i;
@@ -213,8 +150,8 @@ Database::dump(ostream &stream)
list_t::iterator k = printStats.begin();
list_t::iterator endprint = printStats.end();
while (k != endprint) {
- Stat *stat = *k;
- if (stat->dodisplay() && !stat->binned())
+ StatData *stat = *k;
+ if (stat->dodisplay() /*&& !stat->binned()*/)
stat->display(stream);
++k;
}
@@ -222,7 +159,7 @@ Database::dump(ostream &stream)
}
StatData *
-Database::find(const Stat *stat)
+Data::find(void *stat)
{
map_t::const_iterator i = statMap.find(stat);
@@ -233,41 +170,26 @@ Database::find(const Stat *stat)
}
void
-Database::check()
+Data::check()
{
list_t::iterator i = allStats.begin();
list_t::iterator end = allStats.end();
while (i != end) {
- Stat *stat = *i;
- StatData *data = find(stat);
- if (!data || !data->init) {
-#ifdef STAT_DEBUG
- cprintf("this is stat number %d\n",(*i)->number);
-#endif
- panic("Not all stats have been initialized");
- }
-
- if (data->print) {
- if (data->name.empty())
- panic("all printable stats must be named");
-
- list_t::iterator j = printStats.insert(printStats.end(), *i);
- inplace_merge(printStats.begin(), j,
- printStats.end(), Stat::less);
- }
-
+ StatData *stat = *i;
+ assert(stat);
+ stat->check();
++i;
}
}
void
-Database::reset()
+Data::reset()
{
list_t::iterator i = allStats.begin();
list_t::iterator end = allStats.end();
while (i != end) {
- Stat *stat = *i;
+ StatData *stat = *i;
stat->reset();
++i;
}
@@ -282,7 +204,7 @@ Database::reset()
i = allStats.begin();
while (i != end) {
- Stat *stat = *i;
+ StatData *stat = *i;
stat->reset();
++i;
}
@@ -294,21 +216,20 @@ Database::reset()
}
void
-Database::regStat(Stat *stat)
+Data::mapStat(void *stat, StatData *data)
{
if (statMap.find(stat) != statMap.end())
panic("shouldn't register stat twice!");
- allStats.push_back(stat);
+ allStats.push_back(data);
- StatData *data = new StatData;
bool success = (statMap.insert(make_pair(stat, data))).second;
assert(statMap.find(stat) != statMap.end());
assert(success && "this should never fail");
}
void
-Database::regBin(MainBin *bin, std::string name)
+Data::regBin(MainBin *bin, string name)
{
if (bin_names.find(bin) != bin_names.end())
panic("shouldn't register bin twice");
@@ -322,235 +243,121 @@ Database::regBin(MainBin *bin, std::string name)
cprintf("registering %s\n", name);
}
-bool
-Stat::less(Stat *stat1, Stat *stat2)
-{
- const string &name1 = stat1->myname();
- const string &name2 = stat2->myname();
-
- vector<string> v1;
- vector<string> v2;
-
- tokenize(v1, name1, '.');
- tokenize(v2, name2, '.');
-
- int last = min(v1.size(), v2.size()) - 1;
- for (int i = 0; i < last; ++i)
- if (v1[i] != v2[i])
- return v1[i] < v2[i];
-
- // Special compare for last element.
- if (v1[last] == v2[last])
- return v1.size() < v2.size();
- else
- return v1[last] < v2[last];
-
- return false;
-}
-
-StatData *
-Database::print(Stat *stat)
+void
+Data::regPrint(void *stat)
{
StatData *data = find(stat);
- assert(data);
- data->print = true;
+ if (!data->print) {
+ data->print = true;
+
+ list_t::iterator j = printStats.insert(printStats.end(), data);
+ inplace_merge(printStats.begin(), j,
+ printStats.end(), StatData::less);
+ }
- return data;
}
-Database &
+Data &
StatDB()
{
- static Database db;
+ static Data db;
return db;
}
-Stat::Stat(bool reg)
-{
-#if 0
- // This assert can help you find that pesky stat.
- assert(this != (void *)0xbffff5c0);
-#endif
-
- if (reg)
- StatDB().regStat(this);
-
-#ifdef STAT_DEBUG
- number = ++total_stats;
- cprintf("I'm stat number %d\n",number);
-#endif
}
-void
-Stat::setInit()
-{ mydata()->init = true; }
-
StatData *
-Stat::mydata()
+DataAccess::find() const
{
- StatData *data = StatDB().find(this);
- assert(data);
-
- return data;
-}
-
-const StatData *
-Stat::mydata() const
-{
- StatData *data = StatDB().find(this);
- assert(data);
-
- return data;
+ return Database::StatDB().find(const_cast<void *>((const void *)this));
}
-const SubData *
-Stat::mysubdata(int index) const
+void
+DataAccess::map(StatData *data)
{
- assert(index >= 0);
- if (index >= size())
- return NULL;
-
- const StatData *data = this->mydata();
- if (!data->subdata || data->subdata->size() <= index)
- return NULL;
-
- return &(*data->subdata)[index];
+ Database::StatDB().mapStat(this, data);
}
-SubData *
-Stat::mysubdata_create(int index)
+StatData *
+DataAccess::statData()
{
- int size = this->size();
- assert(index >= 0 && (size == 0 || size > 0 && index < size));
-
- StatData *data = this->mydata();
- if (!data->subdata) {
- if (!data->subdata) {
- if (size == 0)
- size = index + 1;
-
- data->subdata = new vector<SubData>(size);
- }
- } else if (data->subdata->size() <= index)
- data->subdata->resize(index + 1);
-
- SubData *sd = &(*data->subdata)[index];
- assert(sd);
-
- return sd;
+ StatData *ptr = find();
+ assert(ptr);
+ return ptr;
}
-string
-Stat::myname() const
-{ return mydata()->name; }
-
-string
-Stat::mysubname(int index) const
+const StatData *
+DataAccess::statData() const
{
- const SubData *sd = mysubdata(index);
- return sd ? sd->name : "";
+ const StatData *ptr = find();
+ assert(ptr);
+ return ptr;
}
-string
-Stat::mydesc() const
-{ return mydata()->desc; }
-
-string
-Stat::mysubdesc(int index) const
+void
+DataAccess::setInit()
{
- const SubData *sd = mysubdata(index);
- return sd ? sd->desc : "";
+ statData()->init = true;
}
-int
-Stat::myprecision() const
-{ return mydata()->precision; }
-
-FormatFlags
-Stat::myflags() const
-{ return mydata()->flags; }
-
-bool
-Stat::dodisplay() const
-{ return !mydata()->prereq || !mydata()->prereq->zero(); }
-
-StatData *
-Stat::print()
+void
+DataAccess::setPrint()
{
- StatData *data = StatDB().print(this);
- assert(data && data->init);
-
- return data;
+ Database::StatDB().regPrint(this);
}
-Stat &
-Stat::name(const string &name)
+StatData::~StatData()
{
- print()->name = name;
- return *this;
}
-Stat &
-Stat::desc(const string &desc)
+bool
+StatData::less(StatData *stat1, StatData *stat2)
{
- print()->desc = desc;
- return *this;
-}
+ const string &name1 = stat1->name;
+ const string &name2 = stat2->name;
-Stat &
-Stat::precision(int precision)
-{
- print()->precision = precision;
- return *this;
-}
+ vector<string> v1;
+ vector<string> v2;
-Stat &
-Stat::flags(FormatFlags flags)
-{
- if (flags & __reserved)
- panic("Cannot set reserved flags!\n");
+ tokenize(v1, name1, '.');
+ tokenize(v2, name2, '.');
- print()->flags |= flags;
- return *this;
-}
+ int last = min(v1.size(), v2.size()) - 1;
+ for (int i = 0; i < last; ++i)
+ if (v1[i] != v2[i])
+ return v1[i] < v2[i];
-Stat &
-Stat::prereq(const Stat &prereq)
-{
- print()->prereq = &prereq;
- return *this;
-}
+ // Special compare for last element.
+ if (v1[last] == v2[last])
+ return v1.size() < v2.size();
+ else
+ return v1[last] < v2[last];
-Stat &
-Stat::subname(int index, const string &name)
-{
- print();
- mysubdata_create(index)->name = name;
- return *this;
-}
-Stat &
-Stat::subdesc(int index, const string &desc)
-{
- print();
- mysubdata_create(index)->desc = desc;
- return *this;
+ return false;
}
bool
-ScalarStat::zero() const
+StatData::check() const
{
- return val() == 0.0;
-}
+ if (!init) {
+#ifdef STAT_DEBUG
+ cprintf("this is stat number %d\n",(*i)->number);
+#endif
+ panic("Not all stats have been initialized");
+ return false;
+ }
-bool
-VectorStat::zero() const
-{
- return val()[0] == 0.0;
+ if (print && name.empty()) {
+ panic("all printable stats must be named");
+ return false;
+ }
+
+ return true;
}
string
-ValueToString(result_t value, int precision)
+ValueToString(result_t value, DisplayMode mode, int precision)
{
stringstream val;
@@ -564,20 +371,33 @@ ValueToString(result_t value, int precision)
val.setf(ios::fixed);
val << value;
} else {
-#ifndef STAT_DISPLAY_COMPAT
- val << "no value";
-#else
- val << "<err: div-0>";
-#endif
+ val << (mode == mode_m5 ? "no value" : "<err: div-0>");
}
return val.str();
}
+struct ScalarPrint
+{
+ result_t value;
+ string name;
+ string desc;
+ int precision;
+ DisplayMode mode;
+ FormatFlags flags;
+ result_t pdf;
+ result_t cdf;
+
+ ScalarPrint()
+ : value(0.0), precision(0), mode(default_mode), flags(0),
+ pdf(NAN), cdf(NAN)
+ {}
+
+ void operator()(ostream &stream) const;
+};
+
void
-PrintOne(ostream &stream, result_t value,
- const string &name, const string &desc, int precision,
- FormatFlags flags, result_t pdf = NAN, result_t cdf = NAN)
+ScalarPrint::operator()(ostream &stream) const
{
if (flags & nozero && value == 0.0 ||
flags & nonan && isnan(value))
@@ -591,16 +411,13 @@ PrintOne(ostream &stream, result_t value,
if (!isnan(cdf))
ccprintf(cdfstr, "%.2f%%", cdf * 100.0);
-#ifdef STAT_DISPLAY_COMPAT
- if (flags & __substat) {
+ if (mode == mode_simplescalar && flags & __substat) {
ccprintf(stream, "%32s %12s %10s %10s", name,
- ValueToString(value, precision),
+ ValueToString(value, mode, precision),
pdfstr, cdfstr);
- } else
-#endif
- {
+ } else {
ccprintf(stream, "%-40s %12s %10s %10s", name,
- ValueToString(value, precision), pdfstr, cdfstr);
+ ValueToString(value, mode, precision), pdfstr, cdfstr);
}
if (PrintDescriptions) {
@@ -610,312 +427,563 @@ PrintOne(ostream &stream, result_t value,
stream << endl;
}
-void
-ScalarStat::display(ostream &stream) const
+struct VectorPrint
{
- PrintOne(stream, val(), myname(), mydesc(), myprecision(), myflags());
-}
-
-void
-VectorStat::display(ostream &stream) const
-{
- bool have_subname = false;
- bool have_subdesc = false;
- int size = this->size();
- for (int i = 0; i < size; ++i) {
- if (!mysubname(i).empty())
- have_subname = true;
- if (!mysubdesc(i).empty())
- have_subdesc = true;
- }
-
- vector<string> *subnames = 0;
- vector<string> *subdescs = 0;
- if (have_subname) {
- subnames = new vector<string>(size);
- for (int i = 0; i < size; ++i)
- (*subnames)[i] = mysubname(i);
- }
- if (have_subdesc) {
- subdescs = new vector<string>(size);
- for (int i = 0; i < size; ++i)
- (*subdescs)[i] = mysubdesc(i);
- }
+ string name;
+ string desc;
+ vector<string> subnames;
+ vector<string> subdescs;
+ int precision;
+ DisplayMode mode;
+ FormatFlags flags;
+ rvec_t vec;
+ result_t total;
- VectorDisplay(stream, myname(), subnames, mydesc(), subdescs,
- myprecision(), myflags(), val(), total());
-}
+ VectorPrint()
+ : subnames(0), subdescs(0), precision(-1), mode(default_mode),
+ flags(0), total(NAN)
+ {}
-#ifndef STAT_DISPLAY_COMPAT
-#define NAMESEP "::"
-#else
-#define NAMESEP "_"
-#endif
+ void operator()(ostream &stream) const;
+};
-#ifndef STAT_DISPLAY_COMPAT
void
-VectorDisplay(std::ostream &stream,
- const std::string &myname,
- const std::vector<std::string> *mysubnames,
- const std::string &mydesc,
- const std::vector<std::string> *mysubdescs,
- int myprecision, FormatFlags myflags,
- const rvec_t &vec, result_t mytotal)
+VectorPrint::operator()(std::ostream &stream) const
{
int _size = vec.size();
result_t _total = 0.0;
- result_t _pdf, _cdf = 0.0;
- if (myflags & (pdf | cdf)) {
+ if (flags & (pdf | cdf)) {
for (int i = 0; i < _size; ++i) {
_total += vec[i];
}
}
+ string base = name + ((mode == mode_simplescalar) ? "_" : "::");
+
+ ScalarPrint print;
+ print.name = name;
+ print.desc = desc;
+ print.precision = precision;
+ print.flags = flags;
+
+ bool havesub = !subnames.empty();
+
if (_size == 1) {
- PrintOne(stream, vec[0], myname, mydesc, myprecision, myflags);
- } else {
+ print.value = vec[0];
+ print(stream);
+ } else if (mode == mode_m5) {
for (int i = 0; i < _size; ++i) {
- string subname;
- if (mysubnames) {
- subname = (*mysubnames)[i];
- if (subname.empty())
- continue;
- } else {
- subname = to_string(i);
- }
+ if (havesub && (i >= subnames.size() || subnames[i].empty()))
+ continue;
- string name = myname + NAMESEP + subname;
- if (!(myflags & pdf))
- PrintOne(stream, vec[i], name, mydesc, myprecision, myflags);
- else {
- _pdf = vec[i] / _total;
- _cdf += _pdf;
- PrintOne(stream, vec[i], name, mydesc, myprecision, myflags,
- _pdf, _cdf);
- }
- }
+ print.name = base + (havesub ? subnames[i] : to_string(i));
+ print.desc = subdescs.empty() ? desc : subdescs[i];
+ print.value = vec[i];
- if (myflags & total)
- PrintOne(stream, mytotal, myname + NAMESEP + "total",
- mydesc, myprecision, myflags);
- }
-}
-#else
-void
-VectorDisplay(std::ostream &stream,
- const std::string &myname,
- const std::vector<std::string> *mysubnames,
- const std::string &mydesc,
- const std::vector<std::string> *mysubdescs,
- int myprecision, FormatFlags myflags,
- const rvec_t &vec, result_t mytotal)
-{
- int _size = vec.size();
- result_t _total = 0.0;
- result_t _pdf, _cdf = 0.0;
+ if (_total && (flags & pdf)) {
+ print.pdf = vec[i] / _total;
+ print.cdf += print.pdf;
+ }
- if (myflags & (pdf | cdf)) {
- for (int i = 0; i < _size; ++i) {
- _total += vec[i];
+ print(stream);
}
- }
- if (_size == 1) {
- PrintOne(stream, vec[0], myname, mydesc, myprecision, myflags);
+ if (flags & ::Statistics::total) {
+ print.name = base + "total";
+ print.desc = desc;
+ print.value = total;
+ print(stream);
+ }
} else {
- if (myflags & total)
- PrintOne(stream, mytotal, myname, mydesc, myprecision, myflags);
+ if (flags & ::Statistics::total) {
+ print.value = total;
+ print(stream);
+ }
- if (myflags & dist) {
- ccprintf(stream, "%s.start_dist\n", myname);
+ result_t _pdf = 0.0;
+ result_t _cdf = 0.0;
+ if (flags & dist) {
+ ccprintf(stream, "%s.start_dist\n", name);
for (int i = 0; i < _size; ++i) {
- string subname, subdesc;
- subname = to_string(i);
- if (mysubnames) {
- if (!subname.empty()) {
- subname = (*mysubnames)[i];
- }
- }
- if (mysubdescs) {
- subdesc = (*mysubdescs)[i];
- }
- if (!(myflags & (pdf | cdf))) {
- PrintOne(stream, vec[i], subname, subdesc, myprecision,
- myflags | __substat);
- } else {
- if (_total) {
- _pdf = vec[i] / _total;
- _cdf += _pdf;
- } else {
- _pdf = _cdf = 0.0;
- }
- if (!(myflags & cdf)) {
- PrintOne(stream, vec[i], subname, subdesc, myprecision,
- myflags | __substat, _pdf);
- } else {
- PrintOne(stream, vec[i], subname, subdesc, myprecision,
- myflags | __substat, _pdf, _cdf);
- }
+ print.name = havesub ? subnames[i] : to_string(i);
+ print.desc = subdescs.empty() ? desc : subdescs[i];
+ print.flags |= __substat;
+ print.value = vec[i];
+
+ if (_total) {
+ _pdf = vec[i] / _total;
+ _cdf += _pdf;
}
+
+ if (flags & pdf)
+ print.pdf = _pdf;
+ if (flags & cdf)
+ print.cdf = _cdf;
+
+ print(stream);
}
- ccprintf(stream, "%s.end_dist\n", myname);
+ ccprintf(stream, "%s.end_dist\n", name);
} else {
for (int i = 0; i < _size; ++i) {
- string subname;
- if (mysubnames) {
- subname = (*mysubnames)[i];
- if (subname.empty())
- continue;
+ if (havesub && subnames[i].empty())
+ continue;
+
+ print.name = base;
+ print.name += havesub ? subnames[i] : to_string(i);
+ print.desc = subdescs.empty() ? desc : subdescs[i];
+ print.value = vec[i];
+
+ if (_total) {
+ _pdf = vec[i] / _total;
+ _cdf += _pdf;
} else {
- subname = to_string(i);
+ _pdf = _cdf = NAN;
}
- string name = myname + NAMESEP + subname;
- if (!(myflags & pdf)) {
- PrintOne(stream, vec[i], name, mydesc, myprecision,
- myflags);
- } else {
- if (_total) {
- _pdf = vec[i] / _total;
- _cdf += _pdf;
- } else {
- _pdf = _cdf = NAN;
- }
- PrintOne(stream, vec[i], name, mydesc, myprecision,
- myflags, _pdf, _cdf);
+ if (flags & pdf) {
+ print.pdf = _pdf;
+ print.cdf = _cdf;
}
+
+ print(stream);
}
}
}
}
-#endif
-#ifndef STAT_DISPLAY_COMPAT
+struct DistPrint
+{
+ string name;
+ string desc;
+ int precision;
+ DisplayMode mode;
+ FormatFlags flags;
+
+ result_t min_val;
+ result_t max_val;
+ result_t underflow;
+ result_t overflow;
+ rvec_t vec;
+ result_t sum;
+ result_t squares;
+ result_t samples;
+
+ int min;
+ int max;
+ int bucket_size;
+ int size;
+ bool fancy;
+
+ void operator()(ostream &stream) const;
+};
+
void
-DistDisplay(ostream &stream, const string &name, const string &desc,
- int precision, FormatFlags flags,
- result_t min_val, result_t max_val,
- result_t underflow, result_t overflow,
- const rvec_t &vec, int min, int max, int bucket_size, int size);
+DistPrint::operator()(ostream &stream) const
{
+ if (fancy) {
+ ScalarPrint print;
+ string base = name + ((mode == mode_m5) ? "::" : "_");
+
+ print.precision = precision;
+ print.flags = flags;
+ print.desc = desc;
+
+ print.name = base + "mean";
+ print.value = samples ? sum / samples : NAN;
+ print(stream);
+
+ print.name = base + "stdev";
+ print.value = samples ? sqrt((samples * squares - sum * sum) /
+ (samples * (samples - 1.0))) : NAN;
+ print(stream);
+
+ print.name = "**Ignore: " + base + "TOT";
+ print.value = samples;
+ print(stream);
+ return;
+ }
+
assert(size == vec.size());
result_t total = 0.0;
- result_t pdf, cdf = 0.0;
total += underflow;
for (int i = 0; i < size; ++i)
total += vec[i];
total += overflow;
- pdf = underflow / total;
- cdf += pdf;
+ string base = name + (mode == mode_m5 ? "::" : ".");
- PrintOne(stream, underflow, name + NAMESEP + "underflow", desc,
- precision, myflags, pdf, cdf);
+ ScalarPrint print;
+ print.desc = (mode == mode_m5) ? desc : "";
+ print.precision = precision;
+ print.mode = mode;
+ print.flags = flags;
- for (int i = 0; i < size; ++i) {
- stringstream namestr;
- namestr << name;
-
- int low = i * bucket_size + min;
- int high = ::std::min((i + 1) * bucket_size + min - 1, max);
- namestr << low;
- if (low < high)
- namestr << "-" << high;
-
- pdf = vec[i] / total;
- cdf += pdf;
- PrintOne(stream, vec[i], namestr.str(), desc, precision, myflags,
- pdf, cdf);
+ if (mode == mode_simplescalar) {
+ ccprintf(stream, "%-42s", base + "start_dist");
+ if (PrintDescriptions && !desc.empty())
+ ccprintf(stream, " # %s", desc);
+ stream << endl;
+ }
+
+ print.name = base + "samples";
+ print.value = samples;
+ print(stream);
+
+ print.name = base + "min_value";
+ print.value = min_val;
+ print(stream);
+
+ if (mode == mode_m5 || underflow > 0.0) {
+ print.name = base + "underflows";
+ print.value = underflow;
+ if (mode == mode_m5 && total) {
+ print.pdf = underflow / total;
+ print.cdf += print.pdf;
+ }
+ print(stream);
+ }
+
+
+ if (mode == mode_m5) {
+ for (int i = 0; i < size; ++i) {
+ stringstream namestr;
+ namestr << name;
+
+ int low = i * bucket_size + min;
+ int high = ::min((i + 1) * bucket_size + min - 1, max);
+ namestr << low;
+ if (low < high)
+ namestr << "-" << high;
+
+ print.name = namestr.str();
+ print.value = vec[i];
+ if (total) {
+ print.pdf = vec[i] / total;
+ print.cdf += print.pdf;
+ }
+ print(stream);
+ }
+
+ } else {
+ int _min;
+ result_t _pdf;
+ result_t _cdf = 0.0;
+
+ print.flags = flags | __substat;
+
+ for (int i = 0; i < size; ++i) {
+ if (flags & nozero && vec[i] == 0.0 ||
+ flags & nonan && isnan(vec[i]))
+ continue;
+
+ _min = i * bucket_size + min;
+ _pdf = vec[i] / total * 100.0;
+ _cdf += _pdf;
+
+
+ print.name = ValueToString(_min, mode, 0);
+ print.value = vec[i];
+ print.pdf = (flags & pdf) ? _pdf : NAN;
+ print.cdf = (flags & cdf) ? _cdf : NAN;
+ print(stream);
+ }
+
+ print.flags = flags;
+ if (flags & (pdf || cdf)) {
+ print.pdf = NAN;
+ print.cdf = NAN;
+ }
+ }
+
+ if (mode == mode_m5 || overflow > 0.0) {
+ print.name = base + "overflows";
+ print.value = overflow;
+ if (mode == mode_m5 && total) {
+ print.pdf = overflow / total;
+ print.cdf += print.pdf;
+ }
+ print(stream);
+ }
+
+ print.pdf = NAN;
+ print.cdf = NAN;
+
+ if (mode != mode_simplescalar) {
+ print.name = base + "total";
+ print.value = total;
+ print(stream);
+ }
+
+ print.name = base + "max_value";
+ print.value = max_val;
+ print(stream);
+
+ if (mode != mode_simplescalar && samples != 0) {
+ print.name = base + "mean";
+ print.value = sum / samples;
+ print(stream);
+
+ print.name = base + "stdev";
+ print.value = sqrt((samples * squares - sum * sum) /
+ (samples * (samples - 1.0)));
+ print(stream);
}
- pdf = overflow / total;
- cdf += pdf;
- PrintOne(stream, overflow, name + NAMESEP + "overflow", desc,
- precision, myflags, pdf, cdf);
- PrintOne(stream, total, name + NAMESEP + "total", desc,
- precision, myflags);
+ if (mode == mode_simplescalar)
+ ccprintf(stream, "%send_dist\n\n", base);
}
-#else
+
void
-DistDisplay(ostream &stream, const string &name, const string &desc,
- int precision, FormatFlags flags,
- result_t min_val, result_t max_val,
- result_t underflow, result_t overflow,
- const rvec_t &vec, int min, int max, int bucket_size, int size)
+ScalarDataBase::display(ostream &stream) const
{
- assert(size == vec.size());
- string blank;
+ ScalarPrint print;
+ print.value = val();
+ print.name = name;
+ print.desc = desc;
+ print.precision = precision;
+ print.flags = flags;
+
+ print(stream);
+}
- result_t total = 0.0;
+void
+VectorDataBase::display(ostream &stream) const
+{
+ int size = this->size();
+ const_cast<VectorDataBase *>(this)->update();
- total += underflow;
- for (int i = 0; i < size; ++i)
- total += vec[i];
- total += overflow;
+ VectorPrint print;
- ccprintf(stream, "%-42s", name + ".start_dist");
- if (PrintDescriptions && !desc.empty())
- ccprintf(stream, " # %s", desc);
- stream << endl;
+ print.name = name;
+ print.desc = desc;
+ print.mode = mode;
+ print.flags = flags;
+ print.precision = precision;
+ print.vec = val();
+ print.total = total();
- PrintOne(stream, total, name + ".samples", blank, precision, flags);
- PrintOne(stream, min_val, name + ".min_value", blank, precision, flags);
+ for (int i = 0; i < size; ++i) {
+ if (!subnames[i].empty()) {
+ print.subnames = subnames;
+ print.subnames.resize(size);
+ for (int i = 0; i < size; ++i) {
+ if (!subnames[i].empty() && !subdescs[i].empty()) {
+ print.subdescs = subdescs;
+ print.subdescs.resize(size);
+ break;
+ }
+ }
+ break;
+ }
+ }
- if (underflow > 0)
- PrintOne(stream, min_val, name + ".underflows", blank, precision,
- flags);
- int _min;
- result_t _pdf, _cdf, mypdf, mycdf;
+ print(stream);
+}
- _cdf = 0.0;
- for (int i = 0; i < size; ++i) {
- if (flags & nozero && vec[i] == 0.0 ||
- flags & nonan && isnan(vec[i]))
+void
+Vector2dDataBase::display(ostream &stream) const
+{
+ const_cast<Vector2dDataBase *>(this)->update();
+
+ bool havesub = false;
+ VectorPrint print;
+
+ print.subnames = y_subnames;
+ print.mode = mode;
+ print.flags = flags;
+ print.precision = precision;
+
+ if (!subnames.empty()) {
+ for (int i = 0; i < x; ++i)
+ if (!subnames[i].empty())
+ havesub = true;
+ }
+
+ rvec_t tot_vec(y);
+ result_t super_total = 0.0;
+ for (int i = 0; i < x; ++i) {
+ if (havesub && (i >= subnames.size() || subnames[i].empty()))
continue;
- _min = i * bucket_size + min;
- _pdf = vec[i] / total * 100.0;
- _cdf += _pdf;
+ int iy = i * y;
+ rvec_t yvec(y);
- mypdf = (flags & pdf) ? _pdf : NAN;
- mycdf = (flags & cdf) ? _cdf : NAN;
+ result_t total = 0.0;
+ for (int j = 0; j < y; ++j) {
+ yvec[j] = vec[iy + j];
+ tot_vec[j] += yvec[j];
+ total += yvec[j];
+ super_total += yvec[j];
+ }
- PrintOne(stream, vec[i], ValueToString(_min, 0), blank, precision,
- flags | __substat, mypdf, mycdf);
+ print.name = name + "_" + (havesub ? subnames[i] : to_string(i));
+ print.desc = desc;
+ print.vec = yvec;
+ print.total = total;
+ print(stream);
}
- if (overflow > 0)
- PrintOne(stream, overflow, name + ".overflows", blank, precision,
- flags);
- PrintOne(stream, max_val, name + ".max_value", blank, precision, flags);
- ccprintf(stream, "%s.end_dist\n\n", name);
+ if ((flags & ::Statistics::total) && (x > 1)) {
+ print.name = name;
+ print.desc = desc;
+ print.vec = tot_vec;
+ print.total = super_total;
+ print(stream);
+ }
+}
+
+void
+DistDataBase::display(ostream &stream) const
+{
+ const_cast<DistDataBase *>(this)->update();
+
+ DistPrint print;
+
+ print.name = name;
+ print.desc = desc;
+ print.precision = precision;
+ print.mode = mode;
+ print.flags = flags;
+
+ print.min_val = data.min_val;
+ print.max_val = data.max_val;
+ print.underflow = data.underflow;
+ print.overflow = data.overflow;
+ print.vec = data.vec;
+ print.sum = data.sum;
+ print.squares = data.squares;
+ print.samples = data.samples;
+
+ print.min = data.min;
+ print.max = data.max;
+ print.bucket_size = data.bucket_size;
+ print.size = data.size;
+ print.fancy = data.fancy;
+
+ print(stream);
+}
+
+void
+VectorDistDataBase::display(ostream &stream) const
+{
+ const_cast<VectorDistDataBase *>(this)->update();
+
+ for (int i = 0; i < size(); ++i) {
+ DistPrint print;
+
+ print.name = name +
+ (subnames[i].empty() ? ("_" + to_string(i)) : subnames[i]);
+ print.desc = subdescs[i].empty() ? desc : subdescs[i];
+ print.precision = precision;
+ print.mode = mode;
+ print.flags = flags;
+
+ print.min_val = data[i].min_val;
+ print.max_val = data[i].max_val;
+ print.underflow = data[i].underflow;
+ print.overflow = data[i].overflow;
+ print.vec = data[i].vec;
+ print.sum = data[i].sum;
+ print.squares = data[i].squares;
+ print.samples = data[i].samples;
+
+ print.min = data[i].min;
+ print.max = data[i].max;
+ print.bucket_size = data[i].bucket_size;
+ print.size = data[i].size;
+ print.fancy = data[i].fancy;
+
+ print(stream);
+ }
+}
+
+void
+FormulaBase::val(rvec_t &vec) const
+{
+ vec = root->val();
+}
+
+result_t
+FormulaBase::total() const
+{
+ return root->total();
+}
+
+size_t
+FormulaBase::size() const
+{
+ if (!root)
+ return 0;
+ else
+ return root->size();
+}
+
+bool
+FormulaBase::binned() const
+{
+ return root->binned();
+}
+
+void
+FormulaBase::reset()
+{
+}
+
+bool
+FormulaBase::zero() const
+{
+ rvec_t vec;
+ val(vec);
+ for (int i = 0; i < vec.size(); ++i)
+ if (vec[i] != 0.0)
+ return false;
+ return true;
}
-#endif
-/**
- * @todo get rid of the ugly hack **Ignore for total
- */
void
-FancyDisplay(ostream &stream, const string &name, const string &desc,
- int precision, FormatFlags flags, result_t mean,
- result_t variance, result_t total)
+FormulaBase::update(StatData *)
+{
+}
+
+Formula::Formula()
{
- result_t stdev = isnan(variance) ? NAN : sqrt(variance);
- PrintOne(stream, mean, name + NAMESEP + "mean", desc, precision, flags);
- PrintOne(stream, stdev, name + NAMESEP + "stdev", desc, precision, flags);
- PrintOne(stream, total, "**Ignore: " + name + NAMESEP + "TOT", desc, precision, flags);
+ setInit();
}
-} // namespace Detail
+Formula::Formula(Temp r)
+{
+ root = r;
+ assert(size());
+}
-MainBin::MainBin(const std::string &name)
+const Formula &
+Formula::operator=(Temp r)
+{
+ assert(!root && "Can't change formulas");
+ root = r;
+ assert(size());
+ return *this;
+}
+
+const Formula &
+Formula::operator+=(Temp r)
+{
+ if (root)
+ root = NodePtr(new BinaryNode<std::plus<result_t> >(root, r));
+ else
+ root = r;
+ assert(size());
+ return *this;
+}
+
+MainBin::MainBin(const string &name)
: _name(name), mem(NULL), memsize(-1)
{
- Detail::StatDB().regBin(this, name);
+ Database::StatDB().regBin(this, name);
}
MainBin::~MainBin()
@@ -927,14 +995,14 @@ MainBin::~MainBin()
char *
MainBin::memory(off_t off)
{
+ if (memsize == -1)
+ memsize = CeilPow2((size_t) offset());
+
if (!mem) {
mem = new char[memsize];
memset(mem, 0, memsize);
}
- if (memsize == -1)
- memsize = CeilPow2((size_t) offset());
-
assert(offset() <= size());
return mem + off;
}
@@ -942,13 +1010,13 @@ MainBin::memory(off_t off)
void
check()
{
- Detail::StatDB().check();
+ Database::StatDB().check();
}
void
dump(ostream &stream)
{
- Detail::StatDB().dump(stream);
+ Database::StatDB().dump(stream);
}
CallbackQueue resetQueue;
@@ -962,7 +1030,7 @@ RegResetCallback(Callback *cb)
void
reset()
{
- Detail::StatDB().reset();
+ Database::StatDB().reset();
resetQueue.process();
}