diff options
Diffstat (limited to 'src/base/stats')
-rw-r--r-- | src/base/stats/events.cc | 2 | ||||
-rw-r--r-- | src/base/stats/flags.hh | 23 | ||||
-rw-r--r-- | src/base/stats/mysql.cc | 250 | ||||
-rw-r--r-- | src/base/stats/mysql.hh | 73 | ||||
-rw-r--r-- | src/base/stats/mysql_run.hh | 8 | ||||
-rw-r--r-- | src/base/stats/output.cc | 3 | ||||
-rw-r--r-- | src/base/stats/statdb.cc | 83 | ||||
-rw-r--r-- | src/base/stats/statdb.hh | 70 | ||||
-rw-r--r-- | src/base/stats/text.cc | 314 | ||||
-rw-r--r-- | src/base/stats/text.hh | 14 | ||||
-rw-r--r-- | src/base/stats/types.hh | 7 | ||||
-rw-r--r-- | src/base/stats/visit.hh | 28 |
12 files changed, 357 insertions, 518 deletions
diff --git a/src/base/stats/events.cc b/src/base/stats/events.cc index dc56fe75f..dcf52e6d8 100644 --- a/src/base/stats/events.cc +++ b/src/base/stats/events.cc @@ -38,7 +38,7 @@ using namespace std; namespace Stats { -Tick EventStart = ULL(0x7fffffffffffffff); +Tick EventStart = MaxTick; extern list<Output *> OutputList; diff --git a/src/base/stats/flags.hh b/src/base/stats/flags.hh index 69f73f66a..77eedaee8 100644 --- a/src/base/stats/flags.hh +++ b/src/base/stats/flags.hh @@ -30,6 +30,7 @@ #ifndef __BASE_STATS_FLAGS_HH__ #define __BASE_STATS_FLAGS_HH__ + namespace Stats { /** @@ -39,28 +40,28 @@ namespace Stats { typedef uint32_t StatFlags; /** Nothing extra to print. */ -const StatFlags none = 0x00000000; +const StatFlags none = 0x00000000; /** This Stat is Initialized */ -const StatFlags init = 0x00000001; +const StatFlags init = 0x00000001; /** Print this stat. */ -const StatFlags print = 0x00000002; +const StatFlags print = 0x00000002; /** Print the total. */ -const StatFlags total = 0x00000010; +const StatFlags total = 0x00000010; /** Print the percent of the total that this entry represents. */ -const StatFlags pdf = 0x00000020; +const StatFlags pdf = 0x00000020; /** Print the cumulative percentage of total upto this entry. */ -const StatFlags cdf = 0x00000040; +const StatFlags cdf = 0x00000040; /** Print the distribution. */ -const StatFlags dist = 0x00000080; +const StatFlags dist = 0x00000080; /** Don't print if this is zero. */ -const StatFlags nozero = 0x00000100; +const StatFlags nozero = 0x00000100; /** Don't print if this is NAN */ -const StatFlags nonan = 0x00000200; +const StatFlags nonan = 0x00000200; /** Used for SS compatability. */ -const StatFlags __substat = 0x80000000; +const StatFlags __substat = 0x80000000; /** Mask of flags that can't be set directly */ -const StatFlags __reserved = init | print | __substat; +const StatFlags __reserved = init | print | __substat; enum DisplayMode { diff --git a/src/base/stats/mysql.cc b/src/base/stats/mysql.cc index 39a687fff..1e0c923f1 100644 --- a/src/base/stats/mysql.cc +++ b/src/base/stats/mysql.cc @@ -40,7 +40,6 @@ #include "base/stats/flags.hh" #include "base/stats/mysql.hh" #include "base/stats/mysql_run.hh" -#include "base/stats/statdb.hh" #include "base/stats/types.hh" #include "base/str.hh" #include "base/userinfo.hh" @@ -458,7 +457,7 @@ InsertSubData::setup(MySqlRun *run) mysql.query(insert); // if (mysql.error) -// panic("could not insert subdata\n%s\n", mysql.error); +// panic("could not insert subdata\n%s\n", mysql.error); if (mysql.commit()) panic("could not commit transaction\n%s\n", mysql.error); @@ -493,21 +492,19 @@ MySql::configure() /* * set up all stats! */ - using namespace Database; - MySQL::Connection &mysql = run->conn(); - stat_list_t::const_iterator i, end = stats().end(); - for (i = stats().begin(); i != end; ++i) { + list<Info *>::const_iterator i, end = statsList().end(); + for (i = statsList().begin(); i != end; ++i) { (*i)->visit(*this); } - for (i = stats().begin(); i != end; ++i) { - StatData *data = *i; - if (data->prereq) { + for (i = statsList().begin(); i != end; ++i) { + Info *info = *i; + if (info->prereq) { // update the prerequisite - uint16_t stat_id = find(data->id); - uint16_t prereq_id = find(data->prereq->id); + uint16_t stat_id = find(info->id); + uint16_t prereq_id = find(info->prereq->id); assert(stat_id && prereq_id); stringstream update; @@ -528,153 +525,156 @@ MySql::configure() configured = true; } - bool -MySql::configure(const StatData &data, string type) +MySql::configure(const Info &info, string type) { stat.init(); - stat.name = data.name; - stat.descr = data.desc; + stat.name = info.name; + stat.descr = info.desc; stat.type = type; - stat.print = data.flags & print; - stat.prec = data.precision; - stat.nozero = data.flags & nozero; - stat.nonan = data.flags & nonan; - stat.total = data.flags & total; - stat.pdf = data.flags & pdf; - stat.cdf = data.flags & cdf; + stat.print = info.flags & print; + stat.prec = info.precision; + stat.nozero = info.flags & nozero; + stat.nonan = info.flags & nonan; + stat.total = info.flags & total; + stat.pdf = info.flags & pdf; + stat.cdf = info.flags & cdf; return stat.print; } void -MySql::configure(const ScalarData &data) +MySql::configure(const ScalarInfoBase &info) { - if (!configure(data, "SCALAR")) + if (!configure(info, "SCALAR")) return; - insert(data.id, stat.setup(run)); + insert(info.id, stat.setup(run)); } void -MySql::configure(const VectorData &data) +MySql::configure(const VectorInfoBase &info) { - if (!configure(data, "VECTOR")) + if (!configure(info, "VECTOR")) return; uint16_t statid = stat.setup(run); - if (!data.subnames.empty()) { + if (!info.subnames.empty()) { InsertSubData subdata; subdata.stat = statid; subdata.y = 0; - for (int i = 0; i < data.subnames.size(); ++i) { + for (off_type i = 0; i < info.subnames.size(); ++i) { subdata.x = i; - subdata.name = data.subnames[i]; - subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i]; + subdata.name = info.subnames[i]; + subdata.descr = info.subdescs.empty() ? "" : info.subdescs[i]; if (!subdata.name.empty() || !subdata.descr.empty()) subdata.setup(run); } } - insert(data.id, statid); + insert(info.id, statid); } void -MySql::configure(const DistData &data) +MySql::configure(const DistInfoBase &info) { - if (!configure(data, "DIST")) + if (!configure(info, "DIST")) return; - if (!data.data.fancy) { - stat.size = data.data.size; - stat.min = data.data.min; - stat.max = data.data.max; - stat.bktsize = data.data.bucket_size; + const DistParams *params = + safe_cast<const DistParams *>(info.storageParams); + if (!params->fancy) { + stat.size = params->buckets; + stat.min = params->min; + stat.max = params->max; + stat.bktsize = params->bucket_size; } - insert(data.id, stat.setup(run)); + insert(info.id, stat.setup(run)); } void -MySql::configure(const VectorDistData &data) +MySql::configure(const VectorDistInfoBase &info) { - if (!configure(data, "VECTORDIST")) + if (!configure(info, "VECTORDIST")) return; - if (!data.data[0].fancy) { - stat.size = data.data[0].size; - stat.min = data.data[0].min; - stat.max = data.data[0].max; - stat.bktsize = data.data[0].bucket_size; + const DistParams *params = + safe_cast<const DistParams *>(info.storageParams); + if (!params->fancy) { + stat.size = params->buckets; + stat.min = params->min; + stat.max = params->max; + stat.bktsize = params->bucket_size; } uint16_t statid = stat.setup(run); - if (!data.subnames.empty()) { + if (!info.subnames.empty()) { InsertSubData subdata; subdata.stat = statid; subdata.y = 0; - for (int i = 0; i < data.subnames.size(); ++i) { + for (off_type i = 0; i < info.subnames.size(); ++i) { subdata.x = i; - subdata.name = data.subnames[i]; - subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i]; + subdata.name = info.subnames[i]; + subdata.descr = info.subdescs.empty() ? "" : info.subdescs[i]; if (!subdata.name.empty() || !subdata.descr.empty()) subdata.setup(run); } } - insert(data.id, statid); + insert(info.id, statid); } void -MySql::configure(const Vector2dData &data) +MySql::configure(const Vector2dInfoBase &info) { - if (!configure(data, "VECTOR2D")) + if (!configure(info, "VECTOR2D")) return; uint16_t statid = stat.setup(run); - if (!data.subnames.empty()) { + if (!info.subnames.empty()) { InsertSubData subdata; subdata.stat = statid; subdata.y = -1; - for (int i = 0; i < data.subnames.size(); ++i) { + for (off_type i = 0; i < info.subnames.size(); ++i) { subdata.x = i; - subdata.name = data.subnames[i]; - subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i]; + subdata.name = info.subnames[i]; + subdata.descr = info.subdescs.empty() ? "" : info.subdescs[i]; if (!subdata.name.empty() || !subdata.descr.empty()) subdata.setup(run); } } - if (!data.y_subnames.empty()) { + if (!info.y_subnames.empty()) { InsertSubData subdata; subdata.stat = statid; subdata.x = -1; subdata.descr = ""; - for (int i = 0; i < data.y_subnames.size(); ++i) { + for (off_type i = 0; i < info.y_subnames.size(); ++i) { subdata.y = i; - subdata.name = data.y_subnames[i]; + subdata.name = info.y_subnames[i]; if (!subdata.name.empty()) subdata.setup(run); } } - insert(data.id, statid); + insert(info.id, statid); } void -MySql::configure(const FormulaData &data) +MySql::configure(const FormulaInfoBase &info) { MySQL::Connection &mysql = run->conn(); assert(mysql.connected()); - configure(data, "FORMULA"); - insert(data.id, stat.setup(run)); + configure(info, "FORMULA"); + insert(info.id, stat.setup(run)); - uint16_t stat = find(data.id); - string formula = data.str(); + uint16_t stat = find(info.id); + string formula = info.str(); stringstream insert_formula; ccprintf(insert_formula, @@ -683,7 +683,7 @@ MySql::configure(const FormulaData &data) mysql.query(insert_formula); // if (mysql.error) -// panic("could not insert formula\n%s\n", mysql.error); +// panic("could not insert formula\n%s\n", mysql.error); stringstream insert_ref; ccprintf(insert_ref, @@ -692,7 +692,7 @@ MySql::configure(const FormulaData &data) mysql.query(insert_ref); // if (mysql.error) -// panic("could not insert formula reference\n%s\n", mysql.error); +// panic("could not insert formula reference\n%s\n", mysql.error); if (mysql.commit()) panic("could not commit transaction\n%s\n", mysql.error); @@ -707,7 +707,6 @@ MySql::valid() const void MySql::output() { - using namespace Database; assert(valid()); if (!configured) @@ -718,9 +717,9 @@ MySql::output() MySQL::Connection &mysql = run->conn(); - Database::stat_list_t::const_iterator i, end = Database::stats().end(); - for (i = Database::stats().begin(); i != end; ++i) { - StatData *stat = *i; + list<Info *>::const_iterator i, end = statsList().end(); + for (i = statsList().begin(); i != end; ++i) { + Info *stat = *i; stat->visit(*this); if (mysql.commit()) panic("could not commit transaction\n%s\n", mysql.error); @@ -735,33 +734,32 @@ MySql::event(const std::string &event) newevent.insert(event); } - void -MySql::output(const ScalarData &data) +MySql::output(const ScalarInfoBase &info) { - if (!(data.flags & print)) + if (!(info.flags & print)) return; - newdata.stat = find(data.id); + newdata.stat = find(info.id); newdata.x = 0; newdata.y = 0; - newdata.data = data.value(); + newdata.data = info.value(); newdata.insert(); } void -MySql::output(const VectorData &data) +MySql::output(const VectorInfoBase &info) { - if (!(data.flags & print)) + if (!(info.flags & print)) return; - newdata.stat = find(data.id); + newdata.stat = find(info.id); newdata.y = 0; - const VCounter &cvec = data.value(); - int size = data.size(); - for (int x = 0; x < size; x++) { + const VCounter &cvec = info.value(); + size_type size = info.size(); + for (off_type x = 0; x < size; x++) { newdata.x = x; newdata.data = cvec[x]; newdata.insert(); @@ -769,7 +767,7 @@ MySql::output(const VectorData &data) } void -MySql::output(const DistDataData &data) +MySql::output(const DistData &data, const DistParams *params) { const int db_sum = -1; const int db_squares = -2; @@ -791,7 +789,7 @@ MySql::output(const DistDataData &data) newdata.data = data.samples; newdata.insert(); - if (data.samples && !data.fancy) { + if (data.samples && !params->fancy) { newdata.x = db_min_val; newdata.data = data.min_val; newdata.insert(); @@ -808,8 +806,8 @@ MySql::output(const DistDataData &data) newdata.data = data.overflow; newdata.insert(); - int size = data.cvec.size(); - for (int x = 0; x < size; x++) { + size_type size = data.cvec.size(); + for (off_type x = 0; x < size; x++) { newdata.x = x; newdata.data = data.cvec[x]; newdata.insert(); @@ -817,54 +815,54 @@ MySql::output(const DistDataData &data) } } - void -MySql::output(const DistData &data) +MySql::output(const DistInfoBase &info) { - if (!(data.flags & print)) + if (!(info.flags & print)) return; - newdata.stat = find(data.id); + newdata.stat = find(info.id); newdata.y = 0; - output(data.data); + output(info.data, safe_cast<const DistParams *>(info.storageParams)); } void -MySql::output(const VectorDistData &data) +MySql::output(const VectorDistInfoBase &info) { - if (!(data.flags & print)) + if (!(info.flags & print)) return; - newdata.stat = find(data.id); + newdata.stat = find(info.id); - int size = data.data.size(); - for (int y = 0; y < size; ++y) { + size_type size = info.data.size(); + for (off_type y = 0; y < size; ++y) { newdata.y = y; - output(data.data[y]); + output(info.data[y], + safe_cast<const DistParams *>(info.storageParams)); } } void -MySql::output(const Vector2dData &data) +MySql::output(const Vector2dInfoBase &info) { - if (!(data.flags & print)) + if (!(info.flags & print)) return; - newdata.stat = find(data.id); + newdata.stat = find(info.id); - int index = 0; - for (int x = 0; x < data.x; x++) { + off_type index = 0; + for (off_type x = 0; x < info.x; x++) { newdata.x = x; - for (int y = 0; y < data.y; y++) { + for (off_type y = 0; y < info.y; y++) { newdata.y = y; - newdata.data = data.cvec[index++]; + newdata.data = info.cvec[index++]; newdata.insert(); } } } void -MySql::output(const FormulaData &data) +MySql::output(const FormulaInfoBase &info) { } @@ -872,65 +870,65 @@ MySql::output(const FormulaData &data) * Implement the visitor */ void -MySql::visit(const ScalarData &data) +MySql::visit(const ScalarInfoBase &info) { if (!configured) - configure(data); + configure(info); else - output(data); + output(info); } void -MySql::visit(const VectorData &data) +MySql::visit(const VectorInfoBase &info) { if (!configured) - configure(data); + configure(info); else - output(data); + output(info); } void -MySql::visit(const DistData &data) +MySql::visit(const DistInfoBase &info) { return; if (!configured) - configure(data); + configure(info); else - output(data); + output(info); } void -MySql::visit(const VectorDistData &data) +MySql::visit(const VectorDistInfoBase &info) { return; if (!configured) - configure(data); + configure(info); else - output(data); + output(info); } void -MySql::visit(const Vector2dData &data) +MySql::visit(const Vector2dInfoBase &info) { return; if (!configured) - configure(data); + configure(info); else - output(data); + output(info); } void -MySql::visit(const FormulaData &data) +MySql::visit(const FormulaInfoBase &info) { if (!configured) - configure(data); + configure(info); else - output(data); + output(info); } bool initMySQL(string host, string user, string password, string database, - string project, string name, string sample) + string project, string name, string sample) { extern list<Output *> OutputList; static MySql mysql; diff --git a/src/base/stats/mysql.hh b/src/base/stats/mysql.hh index 0ce381c2f..86a4d6d23 100644 --- a/src/base/stats/mysql.hh +++ b/src/base/stats/mysql.hh @@ -40,7 +40,7 @@ namespace MySQL { class Connection; } namespace Stats { -class DistDataData; +class DistInfoBase; class MySqlRun; struct SetupStat @@ -56,6 +56,7 @@ struct SetupStat bool total; bool pdf; bool cdf; + double min; double max; double bktsize; @@ -69,9 +70,9 @@ class InsertData { private: char *query; - int size; + size_type size; bool first; - static const int maxsize = 1024*1024; + static const size_type maxsize = 1024*1024; public: MySqlRun *run; @@ -95,9 +96,9 @@ class InsertEvent { private: char *query; - int size; + size_type size; bool first; - static const int maxsize = 1024*1024; + static const size_type maxsize = 1024*1024; typedef std::map<std::string, uint32_t> event_map_t; event_map_t events; @@ -121,19 +122,21 @@ class MySql : public Output SetupStat stat; InsertData newdata; InsertEvent newevent; - std::list<FormulaData *> formulas; + std::list<FormulaInfoBase *> formulas; bool configured; protected: std::map<int, int> idmap; - void insert(int sim_id, int db_id) + void + insert(int sim_id, int db_id) { using namespace std; idmap.insert(make_pair(sim_id, db_id)); } - int find(int sim_id) + int + find(int sim_id) { using namespace std; map<int,int>::const_iterator i = idmap.find(sim_id); @@ -146,19 +149,19 @@ class MySql : public Output ~MySql(); void connect(const std::string &host, const std::string &user, - const std::string &passwd, const std::string &db, - const std::string &name, const std::string &sample, - const std::string &project); + const std::string &passwd, const std::string &db, + const std::string &name, const std::string &sample, + const std::string &project); bool connected() const; public: // Implement Visit - virtual void visit(const ScalarData &data); - virtual void visit(const VectorData &data); - virtual void visit(const DistData &data); - virtual void visit(const VectorDistData &data); - virtual void visit(const Vector2dData &data); - virtual void visit(const FormulaData &data); + virtual void visit(const ScalarInfoBase &info); + virtual void visit(const VectorInfoBase &info); + virtual void visit(const DistInfoBase &info); + virtual void visit(const VectorDistInfoBase &info); + virtual void visit(const Vector2dInfoBase &info); + virtual void visit(const FormulaInfoBase &info); // Implement Output virtual bool valid() const; @@ -169,33 +172,33 @@ class MySql : public Output protected: // Output helper - void output(const DistDataData &data); - void output(const ScalarData &data); - void output(const VectorData &data); - void output(const DistData &data); - void output(const VectorDistData &data); - void output(const Vector2dData &data); - void output(const FormulaData &data); + void output(const ScalarInfoBase &info); + void output(const VectorInfoBase &info); + void output(const DistInfoBase &info); + void output(const VectorDistInfoBase &info); + void output(const Vector2dInfoBase &info); + void output(const FormulaInfoBase &info); + void output(const DistData &data, const DistParams *params); void configure(); - bool configure(const StatData &data, std::string type); - void configure(const ScalarData &data); - void configure(const VectorData &data); - void configure(const DistData &data); - void configure(const VectorDistData &data); - void configure(const Vector2dData &data); - void configure(const FormulaData &data); + bool configure(const Info &info, std::string type); + void configure(const ScalarInfoBase &info); + void configure(const VectorInfoBase &info); + void configure(const DistInfoBase &info); + void configure(const VectorDistInfoBase &info); + void configure(const Vector2dInfoBase &info); + void configure(const FormulaInfoBase &info); }; bool initMySQL(std::string host, std::string database, std::string user, - std::string passwd, std::string project, std::string name, - std::string sample); + std::string passwd, std::string project, std::string name, + std::string sample); #if !USE_MYSQL inline bool initMySQL(std::string host, std::string user, std::string password, - std::string database, std::string project, std::string name, - std::string sample) + std::string database, std::string project, std::string name, + std::string sample) { return false; } diff --git a/src/base/stats/mysql_run.hh b/src/base/stats/mysql_run.hh index 487224551..7c606370e 100644 --- a/src/base/stats/mysql_run.hh +++ b/src/base/stats/mysql_run.hh @@ -46,7 +46,7 @@ struct MySqlRun protected: void setup(const std::string &name, const std::string &sample, - const std::string &user, const std::string &project); + const std::string &user, const std::string &project); void remove(const std::string &name); void cleanup(); @@ -54,9 +54,9 @@ struct MySqlRun public: bool connected() const { return mysql.connected(); } void connect(const std::string &host, const std::string &user, - const std::string &passwd, const std::string &db, - const std::string &name, const std::string &sample, - const std::string &project); + const std::string &passwd, const std::string &db, + const std::string &name, const std::string &sample, + const std::string &project); MySQL::Connection &conn() { return mysql; } uint16_t run() const { return run_id; } diff --git a/src/base/stats/output.cc b/src/base/stats/output.cc index 9f2b91c77..31aa21c45 100644 --- a/src/base/stats/output.cc +++ b/src/base/stats/output.cc @@ -30,6 +30,7 @@ #include <list> +#include "base/statistics.hh" #include "base/stats/output.hh" #include "sim/eventq.hh" #include "sim/host.hh" @@ -49,6 +50,8 @@ dump() return; lastDump = curTick; + prepare(); + list<Output *>::iterator i = OutputList.begin(); list<Output *>::iterator end = OutputList.end(); for (; i != end; ++i) { diff --git a/src/base/stats/statdb.cc b/src/base/stats/statdb.cc deleted file mode 100644 index f9136807a..000000000 --- a/src/base/stats/statdb.cc +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2004-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Nathan Binkert - */ - -#include "base/misc.hh" -#include "base/trace.hh" -#include "base/statistics.hh" -#include "base/stats/statdb.hh" - -using namespace std; - -namespace Stats { -namespace Database { - -StatData * -find(void *stat) -{ - stat_map_t::const_iterator i = map().find(stat); - - if (i == map().end()) - return NULL; - - return (*i).second; -} - -void -regStat(void *stat, StatData *data) -{ - if (map().find(stat) != map().end()) - panic("shouldn't register stat twice!"); - - stats().push_back(data); - -#ifndef NDEBUG - pair<stat_map_t::iterator, bool> result = -#endif - map().insert(make_pair(stat, data)); - assert(result.second && "this should never fail"); - assert(map().find(stat) != map().end()); -} - -void -regPrint(void *stat) -{ - StatData *data = find(stat); - assert(data); - data->flags |= print; -} - -TheDatabase &db() -{ - static TheDatabase db; - return db; -} - -/* namespace Database */ } -/* namespace Stats */ } diff --git a/src/base/stats/statdb.hh b/src/base/stats/statdb.hh deleted file mode 100644 index a5b9be7eb..000000000 --- a/src/base/stats/statdb.hh +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2004-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Nathan Binkert - */ - -#ifndef __BASE_STATS_STATDB_HH__ -#define __BASE_STATS_STATDB_HH__ - -#include <iosfwd> -#include <list> -#include <map> -#include <string> - -class Python; - -namespace Stats { - -class StatData; - -namespace Database { - -typedef std::map<void *, StatData *> stat_map_t; -typedef std::list<StatData *> stat_list_t; - -// We wrap the database in a struct to make sure it is built in time. -struct TheDatabase -{ - stat_map_t map; - stat_list_t stats; -}; - -TheDatabase &db(); -inline stat_map_t &map() { return db().map; } -inline stat_list_t &stats() { return db().stats; } - -StatData *find(void *stat); -void regStat(void *stat, StatData *data); -void regPrint(void *stat); - -inline std::string name() { return "Statistics Database"; } - -/* namespace Database */ } -/* namespace Stats */ } - -#endif // __BASE_STATS_STATDB_HH__ diff --git a/src/base/stats/text.cc b/src/base/stats/text.cc index a018c4837..c3e484cf4 100644 --- a/src/base/stats/text.cc +++ b/src/base/stats/text.cc @@ -43,7 +43,6 @@ #include "base/misc.hh" #include "base/statistics.hh" -#include "base/stats/statdb.hh" #include "base/stats/text.hh" #include "base/stats/visit.hh" @@ -107,7 +106,8 @@ Text::open(std::ostream &_stream) mystream = false; stream = &_stream; - assert(valid()); + if (!valid()) + fatal("Unable to open output stream for writing\n"); } void @@ -118,35 +118,34 @@ Text::open(const std::string &file) mystream = true; stream = new ofstream(file.c_str(), ios::trunc); - assert(valid()); + if (!valid()) + fatal("Unable to open statistics file for writing\n"); } bool Text::valid() const { - return stream != NULL; + return stream != NULL && stream->good(); } void Text::output() { - using namespace Database; - ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n"); - stat_list_t::const_iterator i, end = stats().end(); - for (i = stats().begin(); i != end; ++i) + list<Info *>::const_iterator i, end = statsList().end(); + for (i = statsList().begin(); i != end; ++i) (*i)->visit(*this); ccprintf(*stream, "\n---------- End Simulation Statistics ----------\n"); stream->flush(); } bool -Text::noOutput(const StatData &data) +Text::noOutput(const Info &info) { - if (!(data.flags & print)) + if (!(info.flags & print)) return true; - if (data.prereq && data.prereq->zero()) + if (info.prereq && info.prereq->zero()) return true; return false; @@ -191,8 +190,8 @@ struct ScalarPrint void ScalarPrint::operator()(ostream &stream) const { - if (flags & nozero && value == 0.0 || - flags & nonan && isnan(value)) + if ((flags & nozero && value == 0.0) || + (flags & nonan && isnan(value))) return; stringstream pdfstr, cdfstr; @@ -237,11 +236,11 @@ struct VectorPrint void VectorPrint::operator()(std::ostream &stream) const { - int _size = vec.size(); + size_type _size = vec.size(); Result _total = 0.0; if (flags & (pdf | cdf)) { - for (int i = 0; i < _size; ++i) { + for (off_type i = 0; i < _size; ++i) { _total += vec[i]; } } @@ -264,7 +263,7 @@ VectorPrint::operator()(std::ostream &stream) const print.value = vec[0]; print(stream); } else if (!compat) { - for (int i = 0; i < _size; ++i) { + for (off_type i = 0; i < _size; ++i) { if (havesub && (i >= subnames.size() || subnames[i].empty())) continue; @@ -296,7 +295,7 @@ VectorPrint::operator()(std::ostream &stream) const Result _cdf = 0.0; if (flags & dist) { ccprintf(stream, "%s.start_dist\n", name); - for (int i = 0; i < _size; ++i) { + for (off_type i = 0; i < _size; ++i) { print.name = havesub ? subnames[i] : to_string(i); print.desc = subdescs.empty() ? desc : subdescs[i]; print.flags |= __substat; @@ -316,7 +315,7 @@ VectorPrint::operator()(std::ostream &stream) const } ccprintf(stream, "%s.end_dist\n", name); } else { - for (int i = 0; i < _size; ++i) { + for (off_type i = 0; i < _size; ++i) { if (havesub && subnames[i].empty()) continue; @@ -352,27 +351,63 @@ struct DistPrint bool descriptions; int precision; - Result min_val; - Result max_val; - Result underflow; - Result overflow; - VResult vec; - Result sum; - Result squares; - Result samples; - Counter min; Counter max; Counter bucket_size; - int size; + size_type size; bool fancy; + const DistData &data; + + DistPrint(const DistInfoBase &info); + DistPrint(const VectorDistInfoBase &info, int i); + void init(const Info &info, const DistParams *params); void operator()(ostream &stream) const; }; +DistPrint::DistPrint(const DistInfoBase &info) + : data(info.data) +{ + init(info, safe_cast<const DistParams *>(info.storageParams)); +} + +DistPrint::DistPrint(const VectorDistInfoBase &info, int i) + : data(info.data[i]) +{ + init(info, safe_cast<const DistParams *>(info.storageParams)); + + name = info.name + "_" + + (info.subnames[i].empty() ? (to_string(i)) : info.subnames[i]); + + if (!info.subdescs[i].empty()) + desc = info.subdescs[i]; +} + +void +DistPrint::init(const Info &info, const DistParams *params) +{ + name = info.name; + desc = info.desc; + flags = info.flags; + compat = compat; + descriptions = descriptions; + precision = info.precision; + + fancy = params->fancy; + min = params->min; + max = params->max; + bucket_size = params->bucket_size; + size = params->buckets; +} + void DistPrint::operator()(ostream &stream) const { + Result stdev = NAN; + if (data.samples) + stdev = sqrt((data.samples * data.squares - data.sum * data.sum) / + (data.samples * (data.samples - 1.0))); + if (fancy) { ScalarPrint print; string base = name + (compat ? "_" : "::"); @@ -386,28 +421,27 @@ DistPrint::operator()(ostream &stream) const print.cdf = NAN; print.name = base + "mean"; - print.value = samples ? sum / samples : NAN; + print.value = data.samples ? data.sum / data.samples : NAN; print(stream); print.name = base + "stdev"; - print.value = samples ? sqrt((samples * squares - sum * sum) / - (samples * (samples - 1.0))) : NAN; + print.value = stdev; print(stream); print.name = "**Ignore: " + base + "TOT"; - print.value = samples; + print.value = data.samples; print(stream); return; } - assert(size == vec.size()); + assert(size == data.cvec.size()); Result total = 0.0; - total += underflow; - for (int i = 0; i < size; ++i) - total += vec[i]; - total += overflow; + total += data.underflow; + for (off_type i = 0; i < size; ++i) + total += data.cvec[i]; + total += data.overflow; string base = name + (compat ? "." : "::"); @@ -428,28 +462,27 @@ DistPrint::operator()(ostream &stream) const } print.name = base + "samples"; - print.value = samples; + print.value = data.samples; print(stream); print.name = base + "min_value"; - print.value = min_val; + print.value = data.min_val; print(stream); - if (!compat || underflow > 0.0) { + if (!compat || data.underflow > 0.0) { print.name = base + "underflows"; - print.value = underflow; + print.value = data.underflow; if (!compat && total) { - print.pdf = underflow / total; + print.pdf = data.underflow / total; print.cdf += print.pdf; } print(stream); } - if (!compat) { - for (int i = 0; i < size; ++i) { + for (off_type i = 0; i < size; ++i) { stringstream namestr; - namestr << name; + namestr << base; Counter low = i * bucket_size + min; Counter high = ::min(low + bucket_size, max); @@ -458,14 +491,13 @@ DistPrint::operator()(ostream &stream) const namestr << "-" << high; print.name = namestr.str(); - print.value = vec[i]; + print.value = data.cvec[i]; if (total) { - print.pdf = vec[i] / total; + print.pdf = data.cvec[i] / total; print.cdf += print.pdf; } print(stream); } - } else { Counter _min; Result _pdf; @@ -473,18 +505,18 @@ DistPrint::operator()(ostream &stream) const print.flags = flags | __substat; - for (int i = 0; i < size; ++i) { - if (flags & nozero && vec[i] == 0.0 || - flags & nonan && isnan(vec[i])) + for (off_type i = 0; i < size; ++i) { + if ((flags & nozero && data.cvec[i] == 0.0) || + (flags & nonan && isnan(data.cvec[i]))) continue; _min = i * bucket_size + min; - _pdf = vec[i] / total * 100.0; + _pdf = data.cvec[i] / total * 100.0; _cdf += _pdf; print.name = ValueToString(_min, 0, compat); - print.value = vec[i]; + print.value = data.cvec[i]; print.pdf = (flags & pdf) ? _pdf : NAN; print.cdf = (flags & cdf) ? _cdf : NAN; print(stream); @@ -493,11 +525,11 @@ DistPrint::operator()(ostream &stream) const print.flags = flags; } - if (!compat || overflow > 0.0) { + if (!compat || data.overflow > 0.0) { print.name = base + "overflows"; - print.value = overflow; + print.value = data.overflow; if (!compat && total) { - print.pdf = overflow / total; + print.pdf = data.overflow / total; print.cdf += print.pdf; } else { print.pdf = NAN; @@ -516,17 +548,16 @@ DistPrint::operator()(ostream &stream) const } print.name = base + "max_value"; - print.value = max_val; + print.value = data.max_val; print(stream); - if (!compat && samples != 0) { + if (!compat && data.samples != 0) { print.name = base + "mean"; - print.value = sum / samples; + print.value = data.sum / data.samples; print(stream); print.name = base + "stdev"; - print.value = sqrt((samples * squares - sum * sum) / - (samples * (samples - 1.0))); + print.value = stdev; print(stream); } @@ -535,19 +566,19 @@ DistPrint::operator()(ostream &stream) const } void -Text::visit(const ScalarData &data) +Text::visit(const ScalarInfoBase &info) { - if (noOutput(data)) + if (noOutput(info)) return; ScalarPrint print; - print.value = data.result(); - print.name = data.name; - print.desc = data.desc; - print.flags = data.flags; + print.value = info.result(); + print.name = info.name; + print.desc = info.desc; + print.flags = info.flags; print.compat = compat; print.descriptions = descriptions; - print.precision = data.precision; + print.precision = info.precision; print.pdf = NAN; print.cdf = NAN; @@ -555,32 +586,32 @@ Text::visit(const ScalarData &data) } void -Text::visit(const VectorData &data) +Text::visit(const VectorInfoBase &info) { - if (noOutput(data)) + if (noOutput(info)) return; - int size = data.size(); + size_type size = info.size(); VectorPrint print; - print.name = data.name; - print.desc = data.desc; - print.flags = data.flags; + print.name = info.name; + print.desc = info.desc; + print.flags = info.flags; print.compat = compat; print.descriptions = descriptions; - print.precision = data.precision; - print.vec = data.result(); - print.total = data.total(); - - if (!data.subnames.empty()) { - for (int i = 0; i < size; ++i) { - if (!data.subnames[i].empty()) { - print.subnames = data.subnames; + print.precision = info.precision; + print.vec = info.result(); + print.total = info.total(); + + if (!info.subnames.empty()) { + for (off_type i = 0; i < size; ++i) { + if (!info.subnames[i].empty()) { + print.subnames = info.subnames; print.subnames.resize(size); - for (int i = 0; i < size; ++i) { - if (!data.subnames[i].empty() && - !data.subdescs[i].empty()) { - print.subdescs = data.subdescs; + for (off_type i = 0; i < size; ++i) { + if (!info.subnames[i].empty() && + !info.subdescs[i].empty()) { + print.subdescs = info.subdescs; print.subdescs.resize(size); break; } @@ -594,53 +625,54 @@ Text::visit(const VectorData &data) } void -Text::visit(const Vector2dData &data) +Text::visit(const Vector2dInfoBase &info) { - if (noOutput(data)) + if (noOutput(info)) return; bool havesub = false; VectorPrint print; - print.subnames = data.y_subnames; - print.flags = data.flags; + print.subnames = info.y_subnames; + print.flags = info.flags; print.compat = compat; print.descriptions = descriptions; - print.precision = data.precision; + print.precision = info.precision; - if (!data.subnames.empty()) { - for (int i = 0; i < data.x; ++i) - if (!data.subnames[i].empty()) + if (!info.subnames.empty()) { + for (off_type i = 0; i < info.x; ++i) + if (!info.subnames[i].empty()) havesub = true; } - VResult tot_vec(data.y); + VResult tot_vec(info.y); Result super_total = 0.0; - for (int i = 0; i < data.x; ++i) { - if (havesub && (i >= data.subnames.size() || data.subnames[i].empty())) + for (off_type i = 0; i < info.x; ++i) { + if (havesub && (i >= info.subnames.size() || info.subnames[i].empty())) continue; - int iy = i * data.y; - VResult yvec(data.y); + off_type iy = i * info.y; + VResult yvec(info.y); Result total = 0.0; - for (int j = 0; j < data.y; ++j) { - yvec[j] = data.cvec[iy + j]; + for (off_type j = 0; j < info.y; ++j) { + yvec[j] = info.cvec[iy + j]; tot_vec[j] += yvec[j]; total += yvec[j]; super_total += yvec[j]; } - print.name = data.name + "_" + (havesub ? data.subnames[i] : to_string(i)); - print.desc = data.desc; + print.name = info.name + "_" + + (havesub ? info.subnames[i] : to_string(i)); + print.desc = info.desc; print.vec = yvec; print.total = total; print(*stream); } - if ((data.flags & ::Stats::total) && (data.x > 1)) { - print.name = data.name; - print.desc = data.desc; + if ((info.flags & ::Stats::total) && (info.x > 1)) { + print.name = info.name; + print.desc = info.desc; print.vec = tot_vec; print.total = super_total; print(*stream); @@ -648,82 +680,31 @@ Text::visit(const Vector2dData &data) } void -Text::visit(const DistData &data) +Text::visit(const DistInfoBase &info) { - if (noOutput(data)) + if (noOutput(info)) return; - DistPrint print; - - print.name = data.name; - print.desc = data.desc; - print.flags = data.flags; - print.compat = compat; - print.descriptions = descriptions; - print.precision = data.precision; - - print.min_val = data.data.min_val; - print.max_val = data.data.max_val; - print.underflow = data.data.underflow; - print.overflow = data.data.overflow; - print.vec.resize(data.data.cvec.size()); - for (int i = 0; i < print.vec.size(); ++i) - print.vec[i] = (Result)data.data.cvec[i]; - print.sum = data.data.sum; - print.squares = data.data.squares; - print.samples = data.data.samples; - - print.min = data.data.min; - print.max = data.data.max; - print.bucket_size = data.data.bucket_size; - print.size = data.data.size; - print.fancy = data.data.fancy; - + DistPrint print(info); print(*stream); } void -Text::visit(const VectorDistData &data) +Text::visit(const VectorDistInfoBase &info) { - if (noOutput(data)) + if (noOutput(info)) return; - for (int i = 0; i < data.size(); ++i) { - DistPrint print; - - print.name = data.name + - (data.subnames[i].empty() ? ("_" + to_string(i)) : data.subnames[i]); - print.desc = data.subdescs[i].empty() ? data.desc : data.subdescs[i]; - print.flags = data.flags; - print.compat = compat; - print.descriptions = descriptions; - print.precision = data.precision; - - print.min_val = data.data[i].min_val; - print.max_val = data.data[i].max_val; - print.underflow = data.data[i].underflow; - print.overflow = data.data[i].overflow; - print.vec.resize(data.data[i].cvec.size()); - for (int j = 0; j < print.vec.size(); ++j) - print.vec[j] = (Result)data.data[i].cvec[j]; - print.sum = data.data[i].sum; - print.squares = data.data[i].squares; - print.samples = data.data[i].samples; - - print.min = data.data[i].min; - print.max = data.data[i].max; - print.bucket_size = data.data[i].bucket_size; - print.size = data.data[i].size; - print.fancy = data.data[i].fancy; - + for (off_type i = 0; i < info.size(); ++i) { + DistPrint print(info, i); print(*stream); } } void -Text::visit(const FormulaData &data) +Text::visit(const FormulaInfoBase &info) { - visit((const VectorData &)data); + visit((const VectorInfoBase &)info); } bool @@ -746,5 +727,4 @@ initText(const string &filename, bool desc, bool compat) return true; } - /* namespace Stats */ } diff --git a/src/base/stats/text.hh b/src/base/stats/text.hh index 781d1083d..38e0202eb 100644 --- a/src/base/stats/text.hh +++ b/src/base/stats/text.hh @@ -46,7 +46,7 @@ class Text : public Output std::ostream *stream; protected: - bool noOutput(const StatData &data); + bool noOutput(const Info &info); public: bool compat; @@ -62,12 +62,12 @@ class Text : public Output void open(const std::string &file); // Implement Visit - virtual void visit(const ScalarData &data); - virtual void visit(const VectorData &data); - virtual void visit(const DistData &data); - virtual void visit(const VectorDistData &data); - virtual void visit(const Vector2dData &data); - virtual void visit(const FormulaData &data); + virtual void visit(const ScalarInfoBase &info); + virtual void visit(const VectorInfoBase &info); + virtual void visit(const DistInfoBase &info); + virtual void visit(const VectorDistInfoBase &info); + virtual void visit(const Vector2dInfoBase &info); + virtual void visit(const FormulaInfoBase &info); // Implement Output virtual bool valid() const; diff --git a/src/base/stats/types.hh b/src/base/stats/types.hh index b64e8fb17..e561f94ad 100644 --- a/src/base/stats/types.hh +++ b/src/base/stats/types.hh @@ -31,7 +31,9 @@ #ifndef __BASE_STATS_TYPES_HH__ #define __BASE_STATS_TYPES_HH__ +#include <limits> #include <vector> + #include "sim/host.hh" namespace Stats { @@ -41,11 +43,16 @@ typedef double Counter; /** vector of counters. */ typedef std::vector<Counter> VCounter; +typedef std::numeric_limits<Counter> CounterLimits; + /** All results are doubles. */ typedef double Result; /** vector of results. */ typedef std::vector<Result> VResult; +typedef unsigned int size_type; +typedef unsigned int off_type; + /* namespace Stats */ } #endif // __BASE_STATS_TYPES_HH__ diff --git a/src/base/stats/visit.hh b/src/base/stats/visit.hh index 0087c227c..9d6996689 100644 --- a/src/base/stats/visit.hh +++ b/src/base/stats/visit.hh @@ -38,26 +38,26 @@ namespace Stats { -class StatData; -class ScalarData; -class VectorData; -class DistDataData; -class DistData; -class VectorDistData; -class Vector2dData; -class FormulaData; +class Info; +class ScalarInfoBase; +class VectorInfoBase; +class DistInfoBase; +class DistInfoBase; +class VectorDistInfoBase; +class Vector2dInfoBase; +class FormulaInfoBase; struct Visit { Visit(); virtual ~Visit(); - virtual void visit(const ScalarData &data) = 0; - virtual void visit(const VectorData &data) = 0; - virtual void visit(const DistData &data) = 0; - virtual void visit(const VectorDistData &data) = 0; - virtual void visit(const Vector2dData &data) = 0; - virtual void visit(const FormulaData &data) = 0; + virtual void visit(const ScalarInfoBase &info) = 0; + virtual void visit(const VectorInfoBase &info) = 0; + virtual void visit(const DistInfoBase &info) = 0; + virtual void visit(const VectorDistInfoBase &info) = 0; + virtual void visit(const Vector2dInfoBase &info) = 0; + virtual void visit(const FormulaInfoBase &info) = 0; }; /* namespace Stats */ } |