stats: create an enable phase, and a prepare phase.

Enable more or less takes the place of check, but also allows stats to
do some other configuration.  Prepare moves all of the code that readies
a stat for dumping into a separate function in preparation for supporting
serialization of certain pieces of statistics data.
While we're at it, clean up the visitor code and some of the python code.
This commit is contained in:
Nathan Binkert 2009-03-05 19:09:53 -08:00
parent 9f45fbaaa6
commit 6f787e3d36
7 changed files with 214 additions and 161 deletions

View file

@ -32,6 +32,7 @@
#include <fstream>
#include <list>
#include <map>
#include <set>
#include <string>
#include "base/callback.hh"
@ -174,6 +175,41 @@ Info::baseCheck() const
return true;
}
void
Info::enable()
{
}
void
VectorInfoBase::enable()
{
size_type s = size();
if (subnames.size() < s)
subnames.resize(s);
if (subdescs.size() < s)
subdescs.resize(s);
}
void
VectorDistInfoBase::enable()
{
size_type s = size();
if (subnames.size() < s)
subnames.resize(s);
if (subdescs.size() < s)
subdescs.resize(s);
}
void
Vector2dInfoBase::enable()
{
if (subnames.size() < x)
subnames.resize(x);
if (subdescs.size() < x)
subdescs.resize(x);
if (y_subnames.size() < y)
y_subnames.resize(y);
}
Formula::Formula()
{
@ -244,11 +280,6 @@ Formula::zero() const
return true;
}
void
Formula::update()
{
}
string
Formula::str() const
{
@ -256,7 +287,7 @@ Formula::str() const
}
void
check()
enable()
{
typedef list<Info *>::iterator iter_t;
@ -277,17 +308,21 @@ check()
statsList().sort(Info::less);
if (i == end)
return;
iter_t last = i;
++i;
for (i = statsList().begin(); i != end; ++i) {
if ((*i)->name == (*last)->name)
panic("same name used twice! name=%s\n", (*i)->name);
Info *info = *i;
info->enable();
}
}
last = i;
void
prepare()
{
list<Info *>::iterator i = statsList().begin();
list<Info *>::iterator end = statsList().end();
while (i != end) {
Info *info = *i;
info->prepare();
++i;
}
}

View file

@ -122,6 +122,16 @@ class Info
virtual bool check() const = 0;
bool baseCheck() const;
/**
* Enable the stat for use
*/
virtual void enable();
/**
* Prepare the stat for dumping.
*/
virtual void prepare() = 0;
/**
* Reset the stat to the default state.
*/
@ -159,7 +169,13 @@ class InfoWrap : public Base
InfoWrap(Stat &stat) : s(stat) {}
bool check() const { return s.check(); }
void prepare() { s.prepare(); }
void reset() { s.reset(); }
void
visit(Visit &visitor)
{
visitor.visit(*static_cast<Base *>(this));
}
bool zero() const { return s.zero(); }
};
@ -169,7 +185,6 @@ class ScalarInfoBase : public Info
virtual Counter value() const = 0;
virtual Result result() const = 0;
virtual Result total() const = 0;
void visit(Visit &visitor) { visitor.visit(*this); }
};
template <class Stat>
@ -190,24 +205,14 @@ class VectorInfoBase : public Info
std::vector<std::string> subnames;
std::vector<std::string> subdescs;
public:
void enable();
public:
virtual size_type size() const = 0;
virtual const VCounter &value() const = 0;
virtual const VResult &result() const = 0;
virtual Result total() const = 0;
void
update()
{
if (!subnames.empty()) {
size_type s = size();
if (subnames.size() < s)
subnames.resize(s);
if (subdescs.size() < s)
subdescs.resize(s);
}
}
};
template <class Stat>
@ -237,14 +242,6 @@ class VectorInfo : public InfoWrap<Stat, VectorInfoBase>
}
Result total() const { return this->s.total(); }
void
visit(Visit &visitor)
{
this->update();
this->s.update();
visitor.visit(*this);
}
};
struct DistData
@ -271,13 +268,6 @@ class DistInfo : public InfoWrap<Stat, DistInfoBase>
{
public:
DistInfo(Stat &stat) : InfoWrap<Stat, DistInfoBase>(stat) {}
void
visit(Visit &visitor)
{
this->s.update();
visitor.visit(*this);
}
};
class VectorDistInfoBase : public Info
@ -288,6 +278,7 @@ class VectorDistInfoBase : public Info
/** Names and descriptions of subfields. */
std::vector<std::string> subnames;
std::vector<std::string> subdescs;
void enable();
protected:
/** Local storage for the entry values, used for printing. */
@ -295,17 +286,6 @@ class VectorDistInfoBase : public Info
public:
virtual size_type size() const = 0;
void
update()
{
size_type s = size();
if (subnames.size() < s)
subnames.resize(s);
if (subdescs.size() < s)
subdescs.resize(s);
}
};
template <class Stat>
@ -315,14 +295,6 @@ class VectorDistInfo : public InfoWrap<Stat, VectorDistInfoBase>
VectorDistInfo(Stat &stat) : InfoWrap<Stat, VectorDistInfoBase>(stat) {}
size_type size() const { return this->s.size(); }
void
visit(Visit &visitor)
{
this->update();
this->s.update();
visitor.visit(*this);
}
};
class Vector2dInfoBase : public Info
@ -339,13 +311,7 @@ class Vector2dInfoBase : public Info
/** Local storage for the entry values, used for printing. */
mutable VCounter cvec;
public:
void
update()
{
if (subnames.size() < x)
subnames.resize(x);
}
void enable();
};
template <class Stat>
@ -353,14 +319,6 @@ class Vector2dInfo : public InfoWrap<Stat, Vector2dInfoBase>
{
public:
Vector2dInfo(Stat &stat) : InfoWrap<Stat, Vector2dInfoBase>(stat) {}
void
visit(Visit &visitor)
{
this->update();
this->s.update();
visitor.visit(*this);
}
};
class InfoAccess
@ -382,7 +340,7 @@ class InfoAccess
/**
* Reset the stat to the default state.
*/
void reset() {}
void reset() { }
/**
* @return true if this stat has a value and satisfies its
@ -525,7 +483,7 @@ class DataWrapVec : public DataWrap<Derived, InfoType>
subname(off_type index, const std::string &name)
{
Derived &self = this->self();
Info *info = this->info();
Info *info = self.info();
std::vector<std::string> &subn = info->subnames;
if (subn.size() <= index)
@ -558,6 +516,17 @@ class DataWrapVec : public DataWrap<Derived, InfoType>
return this->self();
}
void
prepare()
{
Derived &self = this->self();
Info *info = this->info();
size_t size = self.size();
for (off_type i = 0; i < size; ++i)
self.data(i)->prepare(info);
}
void
reset()
{
@ -657,6 +626,10 @@ class StatStor
* @return The value of this stat.
*/
Result result() const { return (Result)data; }
/**
* Prepare stat data for dumping or serialization
*/
void prepare(Info *info) { }
/**
* Reset stat value to default
*/
@ -734,8 +707,7 @@ class AvgStor
Result
result() const
{
total += current * (curTick - last);
last = curTick;
assert(last == curTick);
return (Result)(total + current) / (Result)(curTick + 1);
}
@ -744,6 +716,16 @@ class AvgStor
*/
bool zero() const { return total == 0.0; }
/**
* Prepare stat data for dumping or serialization
*/
void
prepare(Info *info)
{
total += current * (curTick - last);
last = curTick;
}
/**
* Reset stat value to default
*/
@ -863,11 +845,6 @@ class ScalarBase : public DataWrap<Derived, ScalarInfo>
*/
size_type size() const { return 1; }
/**
* Reset stat value to default
*/
void reset() { data()->reset(this->info()); }
Counter value() { return data()->value(); }
Result result() { return data()->result(); }
@ -875,17 +852,22 @@ class ScalarBase : public DataWrap<Derived, ScalarInfo>
Result total() { return result(); }
bool zero() { return result() == 0.0; }
void reset() { data()->reset(this->info()); }
void prepare() { data()->prepare(this->info()); }
};
class ProxyInfo : public ScalarInfoBase
{
public:
void visit(Visit &visitor) { visitor.visit(*this); }
std::string str() const { return to_string(value()); }
size_type size() const { return 1; }
bool check() const { return true; }
void reset() {}
void prepare() { }
void reset() { }
bool zero() const { return value() == 0; }
void visit(Visit &visitor) { visitor.visit(*this); }
};
template <class T>
@ -950,6 +932,7 @@ class ValueBase : public DataWrap<Derived, ScalarInfo>
std::string str() const { return proxy->str(); }
bool zero() const { return proxy->zero(); }
bool check() const { return proxy != NULL; }
void prepare() { }
void reset() { }
};
@ -1230,8 +1213,6 @@ class VectorBase : public DataWrapVec<Derived, VectorInfo>
assert (index >= 0 && index < size());
return Proxy(this->self(), index);
}
void update() {}
};
template <class Stat>
@ -1348,16 +1329,6 @@ class Vector2dBase : public DataWrapVec2d<Derived, Vector2dInfo>
delete [] reinterpret_cast<char *>(storage);
}
void
update()
{
Info *info = this->info();
size_type size = this->size();
info->cvec.resize(size);
for (off_type i = 0; i < size; ++i)
info->cvec[i] = data(i)->value();
}
Derived &
init(size_type _x, size_type _y)
{
@ -1413,6 +1384,20 @@ class Vector2dBase : public DataWrapVec2d<Derived, Vector2dInfo>
#endif
}
void
prepare()
{
Info *info = this->info();
size_type size = this->size();
for (off_type i = 0; i < size; ++i)
data(i)->prepare(info);
info->cvec.resize(size);
for (off_type i = 0; i < size; ++i)
info->cvec[i] = data(i)->value();
}
/**
* Reset stat value to default
*/
@ -1541,7 +1526,7 @@ class DistStor
}
void
update(Info *info, DistData &data)
prepare(Info *info, DistData &data)
{
const Params *params = safe_cast<const Params *>(info->storageParams);
@ -1630,14 +1615,6 @@ class FancyStor
samples += number;
}
void
update(Info *info, DistData &data)
{
data.sum = sum;
data.squares = squares;
data.samples = samples;
}
/**
* Return the number of entries in this stat, 1
* @return 1.
@ -1650,6 +1627,14 @@ class FancyStor
*/
bool zero() const { return samples == Counter(); }
void
prepare(Info *info, DistData &data)
{
data.sum = sum;
data.squares = squares;
data.samples = samples;
}
/**
* Reset stat value to default
*/
@ -1702,14 +1687,6 @@ class AvgFancy
squares += value * value;
}
void
update(Info *info, DistData &data)
{
data.sum = sum;
data.squares = squares;
data.samples = curTick;
}
/**
* Return the number of entries, in this case 1.
* @return 1.
@ -1722,6 +1699,14 @@ class AvgFancy
*/
bool zero() const { return sum == Counter(); }
void
prepare(Info *info, DistData &data)
{
data.sum = sum;
data.squares = squares;
data.samples = curTick;
}
/**
* Reset stat value to default
*/
@ -1801,10 +1786,10 @@ class DistBase : public DataWrap<Derived, DistInfo>
bool zero() const { return data()->zero(); }
void
update()
prepare()
{
Info *info = this->info();
data()->update(info, info->data);
data()->prepare(info, info->data);
}
/**
@ -1900,24 +1885,21 @@ class VectorDistBase : public DataWrapVec<Derived, VectorDistInfo>
#endif
}
void
prepare()
{
Info *info = this->info();
size_type size = this->size();
info->data.resize(size);
for (off_type i = 0; i < size; ++i)
data(i)->prepare(info, info->data[i]);
}
bool
check() const
{
return storage != NULL;
}
void
update()
{
Derived &self = this->self();
Info *info = this->info();
size_type size = self.size();
info.data.resize(size);
for (off_type i = 0; i < size; ++i) {
data(i)->update(info, info.data[i]);
}
}
};
template <class Stat>
@ -2589,14 +2571,6 @@ class FormulaInfo : public InfoWrap<Stat, FormulaInfoBase>
Result total() const { return this->s.total(); }
VCounter &value() const { return cvec; }
void
visit(Visit &visitor)
{
this->update();
this->s.update();
visitor.visit(*this);
}
std::string str() const { return this->s.str(); }
};
@ -2677,11 +2651,6 @@ class Formula : public DataWrapVec<Formula, FormulaInfo>
*/
bool zero() const;
/**
*
*/
void update();
std::string str() const;
};
@ -2876,11 +2845,6 @@ class Temp
* @}
*/
void check();
void dump();
void reset();
void registerResetCallback(Callback *cb);
inline Temp
operator+(Temp l, Temp r)
{
@ -2931,6 +2895,34 @@ sum(Temp val)
return NodePtr(new SumNode<std::plus<Result> >(val));
}
/**
* Enable the statistics package. Before the statistics package is
* enabled, all statistics must be created and initialized and once
* the package is enabled, no more statistics can be created.
*/
void enable();
/**
* Prepare all stats for data access. This must be done before
* dumping and serialization.
*/
void prepare();
/**
* Dump all statistics data to the registered outputs
*/
void dump();
/**
* Reset all statistics to the base state
*/
void reset();
/**
* Register a callback that should be called whenever statistics are
* reset
*/
void registerResetCallback(Callback *cb);
std::list<Info *> &statsList();
/* namespace Stats */ }

View file

@ -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) {

View file

@ -27,7 +27,14 @@
# Authors: Nathan Binkert
import internal
from internal.core import initAll, regAllStats
def setOutputDir(dir):
internal.core.setOutputDir(dir)
def initAll():
internal.core.initAll()
def regAllStats():
internal.core.regAllStats()

View file

@ -33,6 +33,8 @@ import sys
# import the SWIG-wrapped main C++ functions
import internal
import core
import stats
from main import options
import SimObject
import ticks
@ -52,23 +54,23 @@ def instantiate(root):
ini_file.close()
# Initialize the global statistics
internal.stats.initSimStats()
stats.initSimStats()
# Create the C++ sim objects and connect ports
root.createCCObject()
root.connectPorts()
# Do a second pass to finish initializing the sim objects
internal.core.initAll()
core.initAll()
# Do a third pass to initialize statistics
internal.core.regAllStats()
core.regAllStats()
# Check to make sure that the stats package is properly initialized
internal.stats.check()
# We're done registering statistics. Enable the stats package now.
stats.enable()
# Reset to put the stats in a consistent state.
internal.stats.reset()
stats.reset()
def doDot(root):
dot = pydot.Dot()

View file

@ -28,9 +28,6 @@
import internal
from internal.stats import dump
from internal.stats import initSimStats
from internal.stats import reset
from internal.stats import StatEvent as event
def initText(filename, desc=True, compat=True):
@ -44,3 +41,19 @@ def initMySQL(host, database, user='', passwd='', project='test', name='test',
internal.stats.initMySQL(host, database, user, passwd, project, name,
sample)
def initSimStats():
internal.stats.initSimStats()
def enable():
internal.stats.enable()
def dump():
# Currently prepare happens in the dump, but we should maybe move
# that out.
#internal.stats.prepare()
internal.stats.dump()
def reset():
internal.stats.reset()

View file

@ -48,7 +48,8 @@ void initMySQL(std::string host, std::string database, std::string user,
void StatEvent(bool dump, bool reset, Tick when = curTick, Tick repeat = 0);
void check();
void enable();
void prepare();
void dump();
void reset();