stats: create an enable phase, and a prepare phase.
authorNathan Binkert <nate@binkert.org>
Fri, 6 Mar 2009 03:09:53 +0000 (19:09 -0800)
committerNathan Binkert <nate@binkert.org>
Fri, 6 Mar 2009 03:09:53 +0000 (19:09 -0800)
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.

src/base/statistics.cc
src/base/statistics.hh
src/base/stats/output.cc
src/python/m5/core.py
src/python/m5/simulate.py
src/python/m5/stats.py
src/python/swig/stats.i

index c77816f239cafe71e7df2d9451caa6c0abfbe3a7..0a59248e7aec53e5dae7f55ef11c95368ee62132 100644 (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;
     }
 }
 
index ef22ebe2432f6b92bae8f11b75a6c10d2c00ae52..6240be7a21338ee426985c98441d5bd25a9a0b1a 100644 (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,23 +1885,20 @@ class VectorDistBase : public DataWrapVec<Derived, VectorDistInfo>
 #endif
     }
 
-    bool
-    check() const
-    {
-        return storage != NULL;
-    }
-
     void
-    update()
+    prepare()
     {
-        Derived &self = this->self();
         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]);
+    }
 
-        size_type size = self.size();
-        info.data.resize(size);
-        for (off_type i = 0; i < size; ++i) {
-            data(i)->update(info, info.data[i]);
-        }
+    bool
+    check() const
+    {
+        return storage != NULL;
     }
 };
 
@@ -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 */ }
index 9f2b91c77f3c65bafd20073c3112789ffb2ffa61..31aa21c458bdce5a97de5a3c429de0c96448d4c1 100644 (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) {
index 232fe2ceb3594d45356503dadbfb33f28138368a..1d7985be62b5e16526dec1b4df5e3aa6ea01aff2 100644 (file)
 # 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()
+
index 617ac3be27b5146974cd3f1d4c4cc275e8097c3b..45992fe85ecf8893fbdf3cd5bf478a981c8e6e71 100644 (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()
index 041a3f58dc4941a7e00db6356b6fbfa7e28a93c2..5bd9d5f6ab2b07dd41a45af388d71d46e128bc03 100644 (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()
index d36f82dbc53885f996b9d4c4ef984b74ab8a6556..284df8ff8f575d51b6ebc6f992a68b1aca4b0e3f 100644 (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();