summaryrefslogtreecommitdiff
path: root/base/statistics.hh
diff options
context:
space:
mode:
Diffstat (limited to 'base/statistics.hh')
-rw-r--r--base/statistics.hh2897
1 files changed, 0 insertions, 2897 deletions
diff --git a/base/statistics.hh b/base/statistics.hh
deleted file mode 100644
index c46744cac..000000000
--- a/base/statistics.hh
+++ /dev/null
@@ -1,2897 +0,0 @@
-/*
- * Copyright (c) 2003-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.
- */
-
-/** @file
- * Declaration of Statistics objects.
- */
-
-/**
-* @todo
-*
-* Generalized N-dimensinal vector
-* documentation
-* key stats
-* interval stats
-* -- these both can use the same function that prints out a
-* specific set of stats
-* VectorStandardDeviation totals
-* Document Namespaces
-*/
-#ifndef __BASE_STATISTICS_HH__
-#define __BASE_STATISTICS_HH__
-
-#include <algorithm>
-#include <cassert>
-#include <cmath>
-#include <functional>
-#include <iosfwd>
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include "base/cprintf.hh"
-#include "base/intmath.hh"
-#include "base/refcnt.hh"
-#include "base/str.hh"
-#include "base/stats/bin.hh"
-#include "base/stats/flags.hh"
-#include "base/stats/visit.hh"
-#include "base/stats/types.hh"
-#include "config/stats_binning.hh"
-#include "sim/host.hh"
-
-class Callback;
-
-/** The current simulated cycle. */
-extern Tick curTick;
-
-/* A namespace for all of the Statistics */
-namespace Stats {
-
-/* Contains the statistic implementation details */
-//////////////////////////////////////////////////////////////////////
-//
-// Statistics Framework Base classes
-//
-//////////////////////////////////////////////////////////////////////
-struct StatData
-{
- /** The name of the stat. */
- std::string name;
- /** The description of the stat. */
- std::string desc;
- /** The formatting flags. */
- StatFlags flags;
- /** The display precision. */
- int precision;
- /** A pointer to a prerequisite Stat. */
- const StatData *prereq;
- /**
- * A unique stat ID for each stat in the simulator.
- * Can be used externally for lookups as well as for debugging.
- */
- int id;
-
- StatData();
- virtual ~StatData();
-
- /**
- * @return true if the stat is binned.
- */
- virtual bool binned() const = 0;
-
- /**
- * Reset the corresponding stat to the default state.
- */
- virtual void reset() = 0;
-
- /**
- * @return true if this stat has a value and satisfies its
- * requirement as a prereq
- */
- virtual bool zero() const = 0;
-
- /**
- * Check that this stat has been set up properly and is ready for
- * use
- * @return true for success
- */
- virtual bool check() const = 0;
- bool baseCheck() const;
-
- /**
- * Visitor entry for outputing statistics data
- */
- virtual void visit(Visit &visitor) = 0;
-
- /**
- * Checks if the first stat's name is alphabetically less than the second.
- * This function breaks names up at periods and considers each subname
- * separately.
- * @param stat1 The first stat.
- * @param stat2 The second stat.
- * @return stat1's name is alphabetically before stat2's
- */
- static bool less(StatData *stat1, StatData *stat2);
-};
-
-class ScalarData : public StatData
-{
- public:
- virtual Counter value() const = 0;
- virtual Result result() const = 0;
- virtual Result total() const = 0;
- virtual void visit(Visit &visitor) { visitor.visit(*this); }
-};
-
-template <class Stat>
-class ScalarStatData : public ScalarData
-{
- protected:
- Stat &s;
-
- public:
- ScalarStatData(Stat &stat) : s(stat) {}
-
- virtual bool binned() const { return s.binned(); }
- virtual bool check() const { return s.check(); }
- virtual Counter value() const { return s.value(); }
- virtual Result result() const { return s.result(); }
- virtual Result total() const { return s.total(); }
- virtual void reset() { s.reset(); }
- virtual bool zero() const { return s.zero(); }
-};
-
-struct VectorData : public StatData
-{
- /** Names and descriptions of subfields. */
- mutable std::vector<std::string> subnames;
- mutable std::vector<std::string> subdescs;
-
- virtual size_t 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()) {
- int s = size();
- if (subnames.size() < s)
- subnames.resize(s);
-
- if (subdescs.size() < s)
- subdescs.resize(s);
- }
- }
-};
-
-template <class Stat>
-class VectorStatData : public VectorData
-{
- protected:
- Stat &s;
- mutable VCounter cvec;
- mutable VResult rvec;
-
- public:
- VectorStatData(Stat &stat) : s(stat) {}
-
- virtual bool binned() const { return s.binned(); }
- virtual bool check() const { return s.check(); }
- virtual bool zero() const { return s.zero(); }
- virtual void reset() { s.reset(); }
-
- virtual size_t size() const { return s.size(); }
- virtual VCounter &value() const
- {
- s.value(cvec);
- return cvec;
- }
- virtual const VResult &result() const
- {
- s.result(rvec);
- return rvec;
- }
- virtual Result total() const { return s.total(); }
- virtual void visit(Visit &visitor)
- {
- update();
- s.update(this);
- visitor.visit(*this);
- }
-};
-
-struct DistDataData
-{
- Counter min_val;
- Counter max_val;
- Counter underflow;
- Counter overflow;
- VCounter cvec;
- Counter sum;
- Counter squares;
- Counter samples;
-
- Counter min;
- Counter max;
- Counter bucket_size;
- int size;
- bool fancy;
-};
-
-struct DistData : public StatData
-{
- /** Local storage for the entry values, used for printing. */
- DistDataData data;
-};
-
-template <class Stat>
-class DistStatData : public DistData
-{
- protected:
- Stat &s;
-
- public:
- DistStatData(Stat &stat) : s(stat) {}
-
- virtual bool binned() const { return s.binned(); }
- virtual bool check() const { return s.check(); }
- virtual void reset() { s.reset(); }
- virtual bool zero() const { return s.zero(); }
- virtual void visit(Visit &visitor)
- {
- s.update(this);
- visitor.visit(*this);
- }
-};
-
-struct VectorDistData : public StatData
-{
- std::vector<DistDataData> data;
-
- /** Names and descriptions of subfields. */
- mutable std::vector<std::string> subnames;
- mutable std::vector<std::string> subdescs;
-
- /** Local storage for the entry values, used for printing. */
- mutable VResult rvec;
-
- virtual size_t size() const = 0;
- void update()
- {
- int s = size();
- if (subnames.size() < s)
- subnames.resize(s);
-
- if (subdescs.size() < s)
- subdescs.resize(s);
- }
-};
-
-template <class Stat>
-class VectorDistStatData : public VectorDistData
-{
- protected:
- Stat &s;
- typedef typename Stat::bin_t bin_t;
-
- public:
- VectorDistStatData(Stat &stat) : s(stat) {}
-
- virtual bool binned() const { return bin_t::binned; }
- virtual bool check() const { return s.check(); }
- virtual void reset() { s.reset(); }
- virtual size_t size() const { return s.size(); }
- virtual bool zero() const { return s.zero(); }
- virtual void visit(Visit &visitor)
- {
- update();
- s.update(this);
- visitor.visit(*this);
- }
-};
-
-struct Vector2dData : public StatData
-{
- /** Names and descriptions of subfields. */
- std::vector<std::string> subnames;
- std::vector<std::string> subdescs;
- std::vector<std::string> y_subnames;
-
- /** Local storage for the entry values, used for printing. */
- mutable VCounter cvec;
- mutable int x;
- mutable int y;
-
- void update()
- {
- if (subnames.size() < x)
- subnames.resize(x);
- }
-};
-
-template <class Stat>
-class Vector2dStatData : public Vector2dData
-{
- protected:
- Stat &s;
- typedef typename Stat::bin_t bin_t;
-
- public:
- Vector2dStatData(Stat &stat) : s(stat) {}
-
- virtual bool binned() const { return bin_t::binned; }
- virtual bool check() const { return s.check(); }
- virtual void reset() { s.reset(); }
- virtual bool zero() const { return s.zero(); }
- virtual void visit(Visit &visitor)
- {
- update();
- s.update(this);
- visitor.visit(*this);
- }
-};
-
-
-class DataAccess
-{
- protected:
- StatData *find() const;
- void map(StatData *data);
-
- StatData *statData();
- const StatData *statData() const;
-
- void setInit();
- void setPrint();
-};
-
-template <class Parent, class Child, template <class> class Data>
-class Wrap : public Child
-{
- protected:
- Parent &self() { return *reinterpret_cast<Parent *>(this); }
-
- protected:
- Data<Child> *statData()
- {
- StatData *__data = DataAccess::statData();
- Data<Child> *ptr = dynamic_cast<Data<Child> *>(__data);
- assert(ptr);
- return ptr;
- }
-
- public:
- const Data<Child> *statData() const
- {
- const StatData *__data = DataAccess::statData();
- const Data<Child> *ptr = dynamic_cast<const Data<Child> *>(__data);
- assert(ptr);
- return ptr;
- }
-
- protected:
- /**
- * Copy constructor, copies are not allowed.
- */
- Wrap(const Wrap &stat);
- /**
- * Can't copy stats.
- */
- void operator=(const Wrap &);
-
- public:
- Wrap()
- {
- map(new Data<Child>(*this));
- }
-
- /**
- * Set the name and marks this stat to print at the end of simulation.
- * @param name The new name.
- * @return A reference to this stat.
- */
- Parent &name(const std::string &_name)
- {
- Data<Child> *data = this->statData();
- data->name = _name;
- this->setPrint();
- return this->self();
- }
-
- /**
- * Set the description and marks this stat to print at the end of
- * simulation.
- * @param desc The new description.
- * @return A reference to this stat.
- */
- Parent &desc(const std::string &_desc)
- {
- this->statData()->desc = _desc;
- return this->self();
- }
-
- /**
- * Set the precision and marks this stat to print at the end of simulation.
- * @param p The new precision
- * @return A reference to this stat.
- */
- Parent &precision(int _precision)
- {
- this->statData()->precision = _precision;
- return this->self();
- }
-
- /**
- * Set the flags and marks this stat to print at the end of simulation.
- * @param f The new flags.
- * @return A reference to this stat.
- */
- Parent &flags(StatFlags _flags)
- {
- this->statData()->flags |= _flags;
- return this->self();
- }
-
- /**
- * Set the prerequisite stat and marks this stat to print at the end of
- * simulation.
- * @param prereq The prerequisite stat.
- * @return A reference to this stat.
- */
- template <class Stat>
- Parent &prereq(const Stat &prereq)
- {
- this->statData()->prereq = prereq.statData();
- return this->self();
- }
-};
-
-template <class Parent, class Child, template <class Child> class Data>
-class WrapVec : public Wrap<Parent, Child, Data>
-{
- public:
- // The following functions are specific to vectors. If you use them
- // in a non vector context, you will get a nice compiler error!
-
- /**
- * Set the subfield name for the given index, and marks this stat to print
- * at the end of simulation.
- * @param index The subfield index.
- * @param name The new name of the subfield.
- * @return A reference to this stat.
- */
- Parent &subname(int index, const std::string &name)
- {
- std::vector<std::string> &subn = this->statData()->subnames;
- if (subn.size() <= index)
- subn.resize(index + 1);
- subn[index] = name;
- return this->self();
- }
-
- /**
- * Set the subfield description for the given index and marks this stat to
- * print at the end of simulation.
- * @param index The subfield index.
- * @param desc The new description of the subfield
- * @return A reference to this stat.
- */
- Parent &subdesc(int index, const std::string &desc)
- {
- std::vector<std::string> &subd = this->statData()->subdescs;
- if (subd.size() <= index)
- subd.resize(index + 1);
- subd[index] = desc;
-
- return this->self();
- }
-
-};
-
-template <class Parent, class Child, template <class Child> class Data>
-class WrapVec2d : public WrapVec<Parent, Child, Data>
-{
- public:
- /**
- * @warning This makes the assumption that if you're gonna subnames a 2d
- * vector, you're subnaming across all y
- */
- Parent &ysubnames(const char **names)
- {
- Data<Child> *data = this->statData();
- data->y_subnames.resize(this->y);
- for (int i = 0; i < this->y; ++i)
- data->y_subnames[i] = names[i];
- return this->self();
- }
- Parent &ysubname(int index, const std::string subname)
- {
- Data<Child> *data = this->statData();
- assert(index < this->y);
- data->y_subnames.resize(this->y);
- data->y_subnames[index] = subname.c_str();
- return this->self();
- }
-};
-
-//////////////////////////////////////////////////////////////////////
-//
-// Simple Statistics
-//
-//////////////////////////////////////////////////////////////////////
-
-/**
- * Templatized storage and interface for a simple scalar stat.
- */
-struct StatStor
-{
- public:
- /** The paramaters for this storage type, none for a scalar. */
- struct Params { };
-
- private:
- /** The statistic value. */
- Counter data;
-
- public:
- /**
- * Builds this storage element and calls the base constructor of the
- * datatype.
- */
- StatStor(const Params &) : data(Counter()) {}
-
- /**
- * The the stat to the given value.
- * @param val The new value.
- * @param p The paramters of this storage type.
- */
- void set(Counter val, const Params &p) { data = val; }
- /**
- * Increment the stat by the given value.
- * @param val The new value.
- * @param p The paramters of this storage type.
- */
- void inc(Counter val, const Params &p) { data += val; }
- /**
- * Decrement the stat by the given value.
- * @param val The new value.
- * @param p The paramters of this storage type.
- */
- void dec(Counter val, const Params &p) { data -= val; }
- /**
- * Return the value of this stat as its base type.
- * @param p The params of this storage type.
- * @return The value of this stat.
- */
- Counter value(const Params &p) const { return data; }
- /**
- * Return the value of this stat as a result type.
- * @param p The parameters of this storage type.
- * @return The value of this stat.
- */
- Result result(const Params &p) const { return (Result)data; }
- /**
- * Reset stat value to default
- */
- void reset() { data = Counter(); }
-
- /**
- * @return true if zero value
- */
- bool zero() const { return data == Counter(); }
-};
-
-/**
- * Templatized storage and interface to a per-cycle average stat. This keeps
- * a current count and updates a total (count * cycles) when this count
- * changes. This allows the quick calculation of a per cycle count of the item
- * being watched. This is good for keeping track of residencies in structures
- * among other things.
- * @todo add lateny to the stat and fix binning.
- */
-struct AvgStor
-{
- public:
- /** The paramaters for this storage type */
- struct Params
- {
- /**
- * The current count. We stash this here because the current
- * value is not a binned value.
- */
- Counter current;
- };
-
- private:
- /** The total count for all cycles. */
- mutable Result total;
- /** The cycle that current last changed. */
- mutable Tick last;
-
- public:
- /**
- * Build and initializes this stat storage.
- */
- AvgStor(Params &p) : total(0), last(0) { p.current = Counter(); }
-
- /**
- * Set the current count to the one provided, update the total and last
- * set values.
- * @param val The new count.
- * @param p The parameters for this storage.
- */
- void set(Counter val, Params &p) {
- total += p.current * (curTick - last);
- last = curTick;
- p.current = val;
- }
-
- /**
- * Increment the current count by the provided value, calls set.
- * @param val The amount to increment.
- * @param p The parameters for this storage.
- */
- void inc(Counter val, Params &p) { set(p.current + val, p); }
-
- /**
- * Deccrement the current count by the provided value, calls set.
- * @param val The amount to decrement.
- * @param p The parameters for this storage.
- */
- void dec(Counter val, Params &p) { set(p.current - val, p); }
-
- /**
- * Return the current count.
- * @param p The parameters for this storage.
- * @return The current count.
- */
- Counter value(const Params &p) const { return p.current; }
-
- /**
- * Return the current average.
- * @param p The parameters for this storage.
- * @return The current average.
- */
- Result result(const Params &p) const
- {
- total += p.current * (curTick - last);
- last = curTick;
- return (Result)(total + p.current) / (Result)(curTick + 1);
- }
-
- /**
- * Reset stat value to default
- */
- void reset()
- {
- total = 0;
- last = curTick;
- }
-
- /**
- * @return true if zero value
- */
- bool zero() const { return total == 0.0; }
-};
-
-/**
- * Implementation of a scalar stat. The type of stat is determined by the
- * Storage template. The storage for this stat is held within the Bin class.
- * This allows for breaking down statistics across multiple bins easily.
- */
-template <class Storage, class Bin>
-class ScalarBase : public DataAccess
-{
- public:
- /** Define the params of the storage class. */
- typedef typename Storage::Params params_t;
- /** Define the bin type. */
- typedef typename Bin::template Bin<Storage> bin_t;
-
- protected:
- /** The bin of this stat. */
- bin_t bin;
- /** The parameters for this stat. */
- params_t params;
-
- protected:
- /**
- * Retrieve the storage from the bin.
- * @return The storage object for this stat.
- */
- Storage *data() { return bin.data(params); }
- /**
- * Retrieve a const pointer to the storage from the bin.
- * @return A const pointer to the storage object for this stat.
- */
- const Storage *data() const
- {
- bin_t *_bin = const_cast<bin_t *>(&bin);
- params_t *_params = const_cast<params_t *>(&params);
- return _bin->data(*_params);
- }
-
- public:
- /**
- * Return the current value of this stat as its base type.
- * @return The current value.
- */
- Counter value() const { return data()->value(params); }
-
- public:
- /**
- * Create and initialize this stat, register it with the database.
- */
- ScalarBase()
- {
- bin.init(params);
- }
-
- public:
- // Common operators for stats
- /**
- * Increment the stat by 1. This calls the associated storage object inc
- * function.
- */
- void operator++() { data()->inc(1, params); }
- /**
- * Decrement the stat by 1. This calls the associated storage object dec
- * function.
- */
- void operator--() { data()->dec(1, params); }
-
- /** Increment the stat by 1. */
- void operator++(int) { ++*this; }
- /** Decrement the stat by 1. */
- void operator--(int) { --*this; }
-
- /**
- * Set the data value to the given value. This calls the associated storage
- * object set function.
- * @param v The new value.
- */
- template <typename U>
- void operator=(const U &v) { data()->set(v, params); }
-
- /**
- * Increment the stat by the given value. This calls the associated
- * storage object inc function.
- * @param v The value to add.
- */
- template <typename U>
- void operator+=(const U &v) { data()->inc(v, params); }
-
- /**
- * Decrement the stat by the given value. This calls the associated
- * storage object dec function.
- * @param v The value to substract.
- */
- template <typename U>
- void operator-=(const U &v) { data()->dec(v, params); }
-
- /**
- * Return the number of elements, always 1 for a scalar.
- * @return 1.
- */
- size_t size() const { return 1; }
- /**
- * Return true if stat is binned.
- *@return True is stat is binned.
- */
- bool binned() const { return bin_t::binned; }
-
- bool check() const { return bin.initialized(); }
-
- /**
- * Reset stat value to default
- */
- void reset() { bin.reset(); }
-
- Counter value() { return data()->value(params); }
-
- Result result() { return data()->result(params); }
-
- Result total() { return result(); }
-
- bool zero() { return result() == 0.0; }
-
-};
-
-class ProxyData : public ScalarData
-{
- public:
- virtual void visit(Visit &visitor) { visitor.visit(*this); }
- virtual bool binned() const { return false; }
- virtual std::string str() const { return to_string(value()); }
- virtual size_t size() const { return 1; }
- virtual bool zero() const { return value() == 0; }
- virtual bool check() const { return true; }
- virtual void reset() { }
-};
-
-template <class T>
-class ValueProxy : public ProxyData
-{
- private:
- T *scalar;
-
- public:
- ValueProxy(T &val) : scalar(&val) {}
- virtual Counter value() const { return *scalar; }
- virtual Result result() const { return *scalar; }
- virtual Result total() const { return *scalar; }
-};
-
-template <class T>
-class FunctorProxy : public ProxyData
-{
- private:
- T *functor;
-
- public:
- FunctorProxy(T &func) : functor(&func) {}
- virtual Counter value() const { return (*functor)(); }
- virtual Result result() const { return (*functor)(); }
- virtual Result total() const { return (*functor)(); }
-};
-
-class ValueBase : public DataAccess
-{
- private:
- ProxyData *proxy;
-
- public:
- ValueBase() : proxy(NULL) { }
- ~ValueBase() { if (proxy) delete proxy; }
-
- template <class T>
- void scalar(T &value)
- {
- proxy = new ValueProxy<T>(value);
- setInit();
- }
-
- template <class T>
- void functor(T &func)
- {
- proxy = new FunctorProxy<T>(func);
- setInit();
- }
-
- Counter value() { return proxy->value(); }
- Result result() const { return proxy->result(); }
- Result total() const { return proxy->total(); };
- size_t size() const { return proxy->size(); }
-
- bool binned() const { return proxy->binned(); }
- std::string str() const { return proxy->str(); }
- bool zero() const { return proxy->zero(); }
- bool check() const { return proxy != NULL; }
- void reset() { }
-};
-
-//////////////////////////////////////////////////////////////////////
-//
-// Vector Statistics
-//
-//////////////////////////////////////////////////////////////////////
-template <class Storage, class Bin>
-class ScalarProxy;
-
-/**
- * Implementation of a vector of stats. The type of stat is determined by the
- * Storage class. @sa ScalarBase
- */
-template <class Storage, class Bin>
-class VectorBase : public DataAccess
-{
- public:
- /** Define the params of the storage class. */
- typedef typename Storage::Params params_t;
- /** Define the bin type. */
- typedef typename Bin::template VectorBin<Storage> bin_t;
-
- protected:
- /** The bin of this stat. */
- bin_t bin;
- /** The parameters for this stat. */
- params_t params;
-
- protected:
- /**
- * Retrieve the storage from the bin for the given index.
- * @param index The vector index to access.
- * @return The storage object at the given index.
- */
- Storage *data(int index) { return bin.data(index, params); }
- /**
- * Retrieve a const pointer to the storage from the bin
- * for the given index.
- * @param index The vector index to access.
- * @return A const pointer to the storage object at the given index.
- */
- const Storage *data(int index) const
- {
- bin_t *_bin = const_cast<bin_t *>(&bin);
- params_t *_params = const_cast<params_t *>(&params);
- return _bin->data(index, *_params);
- }
-
- public:
- void value(VCounter &vec) const
- {
- vec.resize(size());
- for (int i = 0; i < size(); ++i)
- vec[i] = data(i)->value(params);
- }
-
- /**
- * Copy the values to a local vector and return a reference to it.
- * @return A reference to a vector of the stat values.
- */
- void result(VResult &vec) const
- {
- vec.resize(size());
- for (int i = 0; i < size(); ++i)
- vec[i] = data(i)->result(params);
- }
-
- /**
- * @return True is stat is binned.
- */
- bool binned() const { return bin_t::binned; }
-
- /**
- * Return a total of all entries in this vector.
- * @return The total of all vector entries.
- */
- Result total() const {
- Result total = 0.0;
- for (int i = 0; i < size(); ++i)
- total += data(i)->result(params);
- return total;
- }
-
- /**
- * @return the number of elements in this vector.
- */
- size_t size() const { return bin.size(); }
-
- bool zero() const
- {
- for (int i = 0; i < size(); ++i)
- if (data(i)->zero())
- return true;
- return false;
- }
-
- bool check() const { return bin.initialized(); }
- void reset() { bin.reset(); }
-
- public:
- VectorBase() {}
-
- /** Friend this class with the associated scalar proxy. */
- friend class ScalarProxy<Storage, Bin>;
-
- /**
- * Return a reference (ScalarProxy) to the stat at the given index.
- * @param index The vector index to access.
- * @return A reference of the stat.
- */
- ScalarProxy<Storage, Bin> operator[](int index);
-
- void update(StatData *data) {}
-};
-
-const StatData * getStatData(const void *stat);
-
-/**
- * A proxy class to access the stat at a given index in a VectorBase stat.
- * Behaves like a ScalarBase.
- */
-template <class Storage, class Bin>
-class ScalarProxy
-{
- public:
- /** Define the params of the storage class. */
- typedef typename Storage::Params params_t;
- /** Define the bin type. */
- typedef typename Bin::template VectorBin<Storage> bin_t;
-
- private:
- /** Pointer to the bin in the parent VectorBase. */
- bin_t *bin;
- /** Pointer to the params in the parent VectorBase. */
- params_t *params;
- /** The index to access in the parent VectorBase. */
- int index;
- /** Keep a pointer to the original stat so was can get data */
- void *stat;
-
- protected:
- /**
- * Retrieve the storage from the bin.
- * @return The storage from the bin for this stat.
- */
- Storage *data() { return bin->data(index, *params); }
- /**
- * Retrieve a const pointer to the storage from the bin.
- * @return A const pointer to the storage for this stat.
- */
- const Storage *data() const
- {
- bin_t *_bin = const_cast<bin_t *>(bin);
- params_t *_params = const_cast<params_t *>(params);
- return _bin->data(index, *_params);
- }
-
- public:
- /**
- * Return the current value of this stat as its base type.
- * @return The current value.
- */
- Counter value() const { return data()->value(*params); }
-
- /**
- * Return the current value of this statas a result type.
- * @return The current value.
- */
- Result result() const { return data()->result(*params); }
-
- public:
- /**
- * Create and initialize this proxy, do not register it with the database.
- * @param b The bin to use.
- * @param p The params to use.
- * @param i The index to access.
- */
- ScalarProxy(bin_t &b, params_t &p, int i, void *s)
- : bin(&b), params(&p), index(i), stat(s) {}
- /**
- * Create a copy of the provided ScalarProxy.
- * @param sp The proxy to copy.
- */
- ScalarProxy(const ScalarProxy &sp)
- : bin(sp.bin), params(sp.params), index(sp.index), stat(sp.stat) {}
- /**
- * Set this proxy equal to the provided one.
- * @param sp The proxy to copy.
- * @return A reference to this proxy.
- */
- const ScalarProxy &operator=(const ScalarProxy &sp) {
- bin = sp.bin;
- params = sp.params;
- index = sp.index;
- stat = sp.stat;
- return *this;
- }
-
- public:
- // Common operators for stats
- /**
- * Increment the stat by 1. This calls the associated storage object inc
- * function.
- */
- void operator++() { data()->inc(1, *params); }
- /**
- * Decrement the stat by 1. This calls the associated storage object dec
- * function.
- */
- void operator--() { data()->dec(1, *params); }
-
- /** Increment the stat by 1. */
- void operator++(int) { ++*this; }
- /** Decrement the stat by 1. */
- void operator--(int) { --*this; }
-
- /**
- * Set the data value to the given value. This calls the associated storage
- * object set function.
- * @param v The new value.
- */
- template <typename U>
- void operator=(const U &v) { data()->set(v, *params); }
-
- /**
- * Increment the stat by the given value. This calls the associated
- * storage object inc function.
- * @param v The value to add.
- */
- template <typename U>
- void operator+=(const U &v) { data()->inc(v, *params); }
-
- /**
- * Decrement the stat by the given value. This calls the associated
- * storage object dec function.
- * @param v The value to substract.
- */
- template <typename U>
- void operator-=(const U &v) { data()->dec(v, *params); }
-
- /**
- * Return the number of elements, always 1 for a scalar.
- * @return 1.
- */
- size_t size() const { return 1; }
-
- /**
- * Return true if stat is binned.
- *@return false since Proxies aren't printed/binned
- */
- bool binned() const { return false; }
-
- /**
- * This stat has no state. Nothing to reset
- */
- void reset() { }
-
- public:
- const StatData *statData() const { return getStatData(stat); }
- std::string str() const
- {
- return csprintf("%s[%d]", this->statData()->name, index);
-
- }
-};
-
-template <class Storage, class Bin>
-inline ScalarProxy<Storage, Bin>
-VectorBase<Storage, Bin>::operator[](int index)
-{
- assert (index >= 0 && index < size());
- return ScalarProxy<Storage, Bin>(bin, params, index, this);
-}
-
-template <class Storage, class Bin>
-class VectorProxy;
-
-template <class Storage, class Bin>
-class Vector2dBase : public DataAccess
-{
- public:
- typedef typename Storage::Params params_t;
- typedef typename Bin::template VectorBin<Storage> bin_t;
-
- protected:
- size_t x;
- size_t y;
- bin_t bin;
- params_t params;
-
- protected:
- Storage *data(int index) { return bin.data(index, params); }
- const Storage *data(int index) const
- {
- bin_t *_bin = const_cast<bin_t *>(&bin);
- params_t *_params = const_cast<params_t *>(&params);
- return _bin->data(index, *_params);
- }
-
- public:
- Vector2dBase() {}
-
- void update(Vector2dData *data)
- {
- int size = this->size();
- data->cvec.resize(size);
- for (int i = 0; i < size; ++i)
- data->cvec[i] = this->data(i)->value(params);
- }
-
- std::string ysubname(int i) const { return (*this->y_subnames)[i]; }
-
- friend class VectorProxy<Storage, Bin>;
- VectorProxy<Storage, Bin> operator[](int index);
-
- size_t size() const { return bin.size(); }
- bool zero() const { return data(0)->value(params) == 0.0; }
-
- /**
- * Reset stat value to default
- */
- void reset() { bin.reset(); }
-
- bool check() { return bin.initialized(); }
-};
-
-template <class Storage, class Bin>
-class VectorProxy
-{
- public:
- typedef typename Storage::Params params_t;
- typedef typename Bin::template VectorBin<Storage> bin_t;
-
- private:
- bin_t *bin;
- params_t *params;
- int offset;
- int len;
- void *stat;
-
- private:
- mutable VResult *vec;
-
- Storage *data(int index) {
- assert(index < len);
- return bin->data(offset + index, *params);
- }
-
- const Storage *data(int index) const {
- bin_t *_bin = const_cast<bin_t *>(bin);
- params_t *_params = const_cast<params_t *>(params);
- return _bin->data(offset + index, *_params);
- }
-
- public:
- const VResult &result() const {
- if (vec)
- vec->resize(size());
- else
- vec = new VResult(size());
-
- for (int i = 0; i < size(); ++i)
- (*vec)[i] = data(i)->result(*params);
-
- return *vec;
- }
-
- Result total() const {
- Result total = 0.0;
- for (int i = 0; i < size(); ++i)
- total += data(i)->result(*params);
- return total;
- }
-
- public:
- VectorProxy(bin_t &b, params_t &p, int o, int l, void *s)
- : bin(&b), params(&p), offset(o), len(l), stat(s), vec(NULL)
- {
- }
-
- VectorProxy(const VectorProxy &sp)
- : bin(sp.bin), params(sp.params), offset(sp.offset), len(sp.len),
- stat(sp.stat), vec(NULL)
- {
- }
-
- ~VectorProxy()
- {
- if (vec)
- delete vec;
- }
-
- const VectorProxy &operator=(const VectorProxy &sp)
- {
- bin = sp.bin;
- params = sp.params;
- offset = sp.offset;
- len = sp.len;
- stat = sp.stat;
- if (vec)
- delete vec;
- vec = NULL;
- return *this;
- }
-
- ScalarProxy<Storage, Bin> operator[](int index)
- {
- assert (index >= 0 && index < size());
- return ScalarProxy<Storage, Bin>(*bin, *params, offset + index, stat);
- }
-
- size_t size() const { return len; }
-
- /**
- * Return true if stat is binned.
- *@return false since Proxies aren't printed/binned
- */
- bool binned() const { return false; }
-
- /**
- * This stat has no state. Nothing to reset.
- */
- void reset() { }
-};
-
-template <class Storage, class Bin>
-inline VectorProxy<Storage, Bin>
-Vector2dBase<Storage, Bin>::operator[](int index)
-{
- int offset = index * y;
- assert (index >= 0 && offset < size());
- return VectorProxy<Storage, Bin>(bin, params, offset, y, this);
-}
-
-//////////////////////////////////////////////////////////////////////
-//
-// Non formula statistics
-//
-//////////////////////////////////////////////////////////////////////
-
-/**
- * Templatized storage and interface for a distrbution stat.
- */
-struct DistStor
-{
- public:
- /** The parameters for a distribution stat. */
- struct Params
- {
- /** The minimum value to track. */
- Counter min;
- /** The maximum value to track. */
- Counter max;
- /** The number of entries in each bucket. */
- Counter bucket_size;
- /** The number of buckets. Equal to (max-min)/bucket_size. */
- int size;
- };
- enum { fancy = false };
-
- private:
- /** The smallest value sampled. */
- Counter min_val;
- /** The largest value sampled. */
- Counter max_val;
- /** The number of values sampled less than min. */
- Counter underflow;
- /** The number of values sampled more than max. */
- Counter overflow;
- /** The current sum. */
- Counter sum;
- /** The sum of squares. */
- Counter squares;
- /** The number of samples. */
- Counter samples;
- /** Counter for each bucket. */
- VCounter cvec;
-
- public:
- /**
- * Construct this storage with the supplied params.
- * @param params The parameters.
- */
- DistStor(const Params &params)
- : min_val(INT_MAX), max_val(INT_MIN), underflow(Counter()),
- overflow(Counter()), sum(Counter()), squares(Counter()),
- samples(Counter()), cvec(params.size)
- {
- reset();
- }
-
- /**
- * Add a value to the distribution for the given number of times.
- * @param val The value to add.
- * @param number The number of times to add the value.
- * @param params The paramters of the distribution.
- */
- void sample(Counter val, int number, const Params &params)
- {
- if (val < params.min)
- underflow += number;
- else if (val > params.max)
- overflow += number;
- else {
- int index = (int)floor((val - params.min) / params.bucket_size);
- assert(index < size(params));
- cvec[index] += number;
- }
-
- if (val < min_val)
- min_val = val;
-
- if (val > max_val)
- max_val = val;
-
- Counter sample = val * number;
- sum += sample;
- squares += sample * sample;
- samples += number;
- }
-
- /**
- * Return the number of buckets in this distribution.
- * @return the number of buckets.
- * @todo Is it faster to return the size from the parameters?
- */
- size_t size(const Params &) const { return cvec.size(); }
-
- /**
- * Returns true if any calls to sample have been made.
- * @param params The paramters of the distribution.
- * @return True if any values have been sampled.
- */
- bool zero(const Params &params) const
- {
- return samples == Counter();
- }
-
- void update(DistDataData *data, const Params &params)
- {
- data->min = params.min;
- data->max = params.max;
- data->bucket_size = params.bucket_size;
- data->size = params.size;
-
- data->min_val = (min_val == INT_MAX) ? 0 : min_val;
- data->max_val = (max_val == INT_MIN) ? 0 : max_val;
- data->underflow = underflow;
- data->overflow = overflow;
- data->cvec.resize(params.size);
- for (int i = 0; i < params.size; ++i)
- data->cvec[i] = cvec[i];
-
- data->sum = sum;
- data->squares = squares;
- data->samples = samples;
- }
-
- /**
- * Reset stat value to default
- */
- void reset()
- {
- min_val = INT_MAX;
- max_val = INT_MIN;
- underflow = 0;
- overflow = 0;
-
- int size = cvec.size();
- for (int i = 0; i < size; ++i)
- cvec[i] = Counter();
-
- sum = Counter();
- squares = Counter();
- samples = Counter();
- }
-};
-
-/**
- * Templatized storage and interface for a distribution that calculates mean
- * and variance.
- */
-struct FancyStor
-{
- public:
- /**
- * No paramters for this storage.
- */
- struct Params {};
- enum { fancy = true };
-
- private:
- /** The current sum. */
- Counter sum;
- /** The sum of squares. */
- Counter squares;
- /** The number of samples. */
- Counter samples;
-
- public:
- /**
- * Create and initialize this storage.
- */
- FancyStor(const Params &)
- : sum(Counter()), squares(Counter()), samples(Counter())
- { }
-
- /**
- * Add a value the given number of times to this running average.
- * Update the running sum and sum of squares, increment the number of
- * values seen by the given number.
- * @param val The value to add.
- * @param number The number of times to add the value.
- * @param p The parameters of this stat.
- */
- void sample(Counter val, int number, const Params &p)
- {
- Counter value = val * number;
- sum += value;
- squares += value * value;
- samples += number;
- }
-
- void update(DistDataData *data, const Params &params)
- {
- data->sum = sum;
- data->squares = squares;
- data->samples = samples;
- }
-
- /**
- * Return the number of entries in this stat, 1
- * @return 1.
- */
- size_t size(const Params &) const { return 1; }
-
- /**
- * Return true if no samples have been added.
- * @return True if no samples have been added.
- */
- bool zero(const Params &) const { return samples == Counter(); }
-
- /**
- * Reset stat value to default
- */
- void reset()
- {
- sum = Counter();
- squares = Counter();
- samples = Counter();
- }
-};
-
-/**
- * Templatized storage for distribution that calculates per cycle mean and
- * variance.
- */
-struct AvgFancy
-{
- public:
- /** No parameters for this storage. */
- struct Params {};
- enum { fancy = true };
-
- private:
- /** Current total. */
- Counter sum;
- /** Current sum of squares. */
- Counter squares;
-
- public:
- /**
- * Create and initialize this storage.
- */
- AvgFancy(const Params &) : sum(Counter()), squares(Counter()) {}
-
- /**
- * Add a value to the distribution for the given number of times.
- * Update the running sum and sum of squares.
- * @param val The value to add.
- * @param number The number of times to add the value.
- * @param p The paramters of the distribution.
- */
- void sample(Counter val, int number, const Params &p)
- {
- Counter value = val * number;
- sum += value;
- squares += value * value;
- }
-
- void update(DistDataData *data, const Params &params)
- {
- data->sum = sum;
- data->squares = squares;
- data->samples = curTick;
- }
-
- /**
- * Return the number of entries, in this case 1.
- * @return 1.
- */
- size_t size(const Params &params) const { return 1; }
- /**
- * Return true if no samples have been added.
- * @return True if the sum is zero.
- */
- bool zero(const Params &params) const { return sum == Counter(); }
- /**
- * Reset stat value to default
- */
- void reset()
- {
- sum = Counter();
- squares = Counter();
- }
-};
-
-/**
- * Implementation of a distribution stat. The type of distribution is
- * determined by the Storage template. @sa ScalarBase
- */
-template <class Storage, class Bin>
-class DistBase : public DataAccess
-{
- public:
- /** Define the params of the storage class. */
- typedef typename Storage::Params params_t;
- /** Define the bin type. */
- typedef typename Bin::template Bin<Storage> bin_t;
-
- protected:
- /** The bin of this stat. */
- bin_t bin;
- /** The parameters for this stat. */
- params_t params;
-
- protected:
- /**
- * Retrieve the storage from the bin.
- * @return The storage object for this stat.
- */
- Storage *data() { return bin.data(params); }
- /**
- * Retrieve a const pointer to the storage from the bin.
- * @return A const pointer to the storage object for this stat.
- */
- const Storage *data() const
- {
- bin_t *_bin = const_cast<bin_t *>(&bin);
- params_t *_params = const_cast<params_t *>(&params);
- return _bin->data(*_params);
- }
-
- public:
- DistBase() { }
-
- /**
- * Add a value to the distribtion n times. Calls sample on the storage
- * class.
- * @param v The value to add.
- * @param n The number of times to add it, defaults to 1.
- */
- template <typename U>
- void sample(const U &v, int n = 1) { data()->sample(v, n, params); }
-
- /**
- * Return the number of entries in this stat.
- * @return The number of entries.
- */
- size_t size() const { return data()->size(params); }
- /**
- * Return true if no samples have been added.
- * @return True if there haven't been any samples.
- */
- bool zero() const { return data()->zero(params); }
-
- void update(DistData *base)
- {
- base->data.fancy = Storage::fancy;
- data()->update(&(base->data), params);
- }
- /**
- * @return True is stat is binned.
- */
- bool binned() const { return bin_t::binned; }
- /**
- * Reset stat value to default
- */
- void reset()
- {
- bin.reset();
- }
-
- bool check() { return bin.initialized(); }
-};
-
-template <class Storage, class Bin>
-class DistProxy;
-
-template <class Storage, class Bin>
-class VectorDistBase : public DataAccess
-{
- public:
- typedef typename Storage::Params params_t;
- typedef typename Bin::template VectorBin<Storage> bin_t;
-
- protected:
- bin_t bin;
- params_t params;
-
- protected:
- Storage *data(int index) { return bin.data(index, params); }
- const Storage *data(int index) const
- {
- bin_t *_bin = const_cast<bin_t *>(&bin);
- params_t *_params = const_cast<params_t *>(&params);
- return _bin->data(index, *_params);
- }
-
- public:
- VectorDistBase() {}
-
- friend class DistProxy<Storage, Bin>;
- DistProxy<Storage, Bin> operator[](int index);
- const DistProxy<Storage, Bin> operator[](int index) const;
-
- size_t size() const { return bin.size(); }
- bool zero() const { return false; }
- /**
- * Return true if stat is binned.
- *@return True is stat is binned.
- */
- bool binned() const { return bin_t::binned; }
- /**
- * Reset stat value to default
- */
- void reset() { bin.reset(); }
-
- bool check() { return bin.initialized(); }
- void update(VectorDistData *base)
- {
- int size = this->size();
- base->data.resize(size);
- for (int i = 0; i < size; ++i) {
- base->data[i].fancy = Storage::fancy;
- data(i)->update(&(base->data[i]), params);
- }
- }
-};
-
-template <class Storage, class Bin>
-class DistProxy
-{
- public:
- typedef typename Storage::Params params_t;
- typedef typename Bin::template Bin<Storage> bin_t;
- typedef VectorDistBase<Storage, Bin> base_t;
-
- private:
- union {
- base_t *stat;
- const base_t *cstat;
- };
- int index;
-
- protected:
- Storage *data() { return stat->data(index); }
- const Storage *data() const { return cstat->data(index); }
-
- public:
- DistProxy(const VectorDistBase<Storage, Bin> &s, int i)
- : cstat(&s), index(i) {}
- DistProxy(const DistProxy &sp)
- : cstat(sp.cstat), index(sp.index) {}
- const DistProxy &operator=(const DistProxy &sp) {
- cstat = sp.cstat; index = sp.index; return *this;
- }
-
- public:
- template <typename U>
- void sample(const U &v, int n = 1) { data()->sample(v, n, cstat->params); }
-
- size_t size() const { return 1; }
- bool zero() const { return data()->zero(cstat->params); }
- /**
- * Return true if stat is binned.
- *@return false since Proxies are not binned/printed.
- */
- bool binned() const { return false; }
- /**
- * Proxy has no state. Nothing to reset.
- */
- void reset() { }
-};
-
-template <class Storage, class Bin>
-inline DistProxy<Storage, Bin>
-VectorDistBase<Storage, Bin>::operator[](int index)
-{
- assert (index >= 0 && index < size());
- return DistProxy<Storage, Bin>(*this, index);
-}
-
-template <class Storage, class Bin>
-inline const DistProxy<Storage, Bin>
-VectorDistBase<Storage, Bin>::operator[](int index) const
-{
- assert (index >= 0 && index < size());
- return DistProxy<Storage, Bin>(*this, index);
-}
-
-#if 0
-template <class Storage, class Bin>
-Result
-VectorDistBase<Storage, Bin>::total(int index) const
-{
- int total = 0;
- for (int i=0; i < x_size(); ++i) {
- total += data(i)->result(*params);
- }
-}
-#endif
-
-//////////////////////////////////////////////////////////////////////
-//
-// Formula Details
-//
-//////////////////////////////////////////////////////////////////////
-
-/**
- * Base class for formula statistic node. These nodes are used to build a tree
- * that represents the formula.
- */
-class Node : public RefCounted
-{
- public:
- /**
- * Return the number of nodes in the subtree starting at this node.
- * @return the number of nodes in this subtree.
- */
- virtual size_t size() const = 0;
- /**
- * Return the result vector of this subtree.
- * @return The result vector of this subtree.
- */
- virtual const VResult &result() const = 0;
- /**
- * Return the total of the result vector.
- * @return The total of the result vector.
- */
- virtual Result total() const = 0;
- /**
- * Return true if stat is binned.
- *@return True is stat is binned.
- */
- virtual bool binned() const = 0;
-
- /**
- *
- */
- virtual std::string str() const = 0;
-};
-
-/** Reference counting pointer to a function Node. */
-typedef RefCountingPtr<Node> NodePtr;
-
-class ScalarStatNode : public Node
-{
- private:
- const ScalarData *data;
- mutable VResult vresult;
-
- public:
- ScalarStatNode(const ScalarData *d) : data(d), vresult(1) {}
- virtual const VResult &result() const
- {
- vresult[0] = data->result();
- return vresult;
- }
- virtual Result total() const { return data->result(); };
-
- virtual size_t size() const { return 1; }
- /**
- * Return true if stat is binned.
- *@return True is stat is binned.
- */
- virtual bool binned() const { return data->binned(); }
-
- /**
- *
- */
- virtual std::string str() const { return data->name; }
-};
-
-template <class Storage, class Bin>
-class ScalarProxyNode : public Node
-{
- private:
- const ScalarProxy<Storage, Bin> proxy;
- mutable VResult vresult;
-
- public:
- ScalarProxyNode(const ScalarProxy<Storage, Bin> &p)
- : proxy(p), vresult(1) { }
- virtual const VResult &result() const
- {
- vresult[0] = proxy.result();
- return vresult;
- }
- virtual Result total() const { return proxy.result(); };
-
- virtual size_t size() const { return 1; }
- /**
- * Return true if stat is binned.
- *@return True is stat is binned.
- */
- virtual bool binned() const { return proxy.binned(); }
-
- /**
- *
- */
- virtual std::string str() const { return proxy.str(); }
-};
-
-class VectorStatNode : public Node
-{
- private:
- const VectorData *data;
-
- public:
- VectorStatNode(const VectorData *d) : data(d) { }
- virtual const VResult &result() const { return data->result(); }
- virtual Result total() const { return data->total(); };
-
- virtual size_t size() const { return data->size(); }
- /**
- * Return true if stat is binned.
- *@return True is stat is binned.
- */
- virtual bool binned() const { return data->binned(); }
-
- virtual std::string str() const { return data->name; }
-};
-
-template <class T>
-class ConstNode : public Node
-{
- private:
- VResult vresult;
-
- public:
- ConstNode(T s) : vresult(1, (Result)s) {}
- const VResult &result() const { return vresult; }
- virtual Result total() const { return vresult[0]; };
- virtual size_t size() const { return 1; }
-
- /**
- * Return true if stat is binned.
- *@return False since constants aren't binned.
- */
- virtual bool binned() const { return false; }
-
- virtual std::string str() const { return to_string(vresult[0]); }
-};
-
-template <class Op>
-struct OpString;
-
-template<>
-struct OpString<std::plus<Result> >
-{
- static std::string str() { return "+"; }
-};
-
-template<>
-struct OpString<std::minus<Result> >
-{
- static std::string str() { return "-"; }
-};
-
-template<>
-struct OpString<std::multiplies<Result> >
-{
- static std::string str() { return "*"; }
-};
-
-template<>
-struct OpString<std::divides<Result> >
-{
- static std::string str() { return "/"; }
-};
-
-template<>
-struct OpString<std::modulus<Result> >
-{
- static std::string str() { return "%"; }
-};
-
-template<>
-struct OpString<std::negate<Result> >
-{
- static std::string str() { return "-"; }
-};
-
-template <class Op>
-class UnaryNode : public Node
-{
- public:
- NodePtr l;
- mutable VResult vresult;
-
- public:
- UnaryNode(NodePtr &p) : l(p) {}
-
- const VResult &result() const
- {
- const VResult &lvec = l->result();
- int size = lvec.size();
-
- assert(size > 0);
-
- vresult.resize(size);
- Op op;
- for (int i = 0; i < size; ++i)
- vresult[i] = op(lvec[i]);
-
- return vresult;
- }
-
- Result total() const {
- Op op;
- return op(l->total());
- }
-
- virtual size_t size() const { return l->size(); }
- /**
- * Return true if child of node is binned.
- *@return True if child of node is binned.
- */
- virtual bool binned() const { return l->binned(); }
-
- virtual std::string str() const
- {
- return OpString<Op>::str() + l->str();
- }
-};
-
-template <class Op>
-class BinaryNode : public Node
-{
- public:
- NodePtr l;
- NodePtr r;
- mutable VResult vresult;
-
- public:
- BinaryNode(NodePtr &a, NodePtr &b) : l(a), r(b) {}
-
- const VResult &result() const
- {
- Op op;
- const VResult &lvec = l->result();
- const VResult &rvec = r->result();
-
- assert(lvec.size() > 0 && rvec.size() > 0);
-
- if (lvec.size() == 1 && rvec.size() == 1) {
- vresult.resize(1);
- vresult[0] = op(lvec[0], rvec[0]);
- } else if (lvec.size() == 1) {
- int size = rvec.size();
- vresult.resize(size);
- for (int i = 0; i < size; ++i)
- vresult[i] = op(lvec[0], rvec[i]);
- } else if (rvec.size() == 1) {
- int size = lvec.size();
- vresult.resize(size);
- for (int i = 0; i < size; ++i)
- vresult[i] = op(lvec[i], rvec[0]);
- } else if (rvec.size() == lvec.size()) {
- int size = rvec.size();
- vresult.resize(size);
- for (int i = 0; i < size; ++i)
- vresult[i] = op(lvec[i], rvec[i]);
- }
-
- return vresult;
- }
-
- Result total() const {
- Op op;
- return op(l->total(), r->total());
- }
-
- virtual size_t size() const {
- int ls = l->size();
- int rs = r->size();
- if (ls == 1)
- return rs;
- else if (rs == 1)
- return ls;
- else {
- assert(ls == rs && "Node vector sizes are not equal");
- return ls;
- }
- }
- /**
- * Return true if any children of node are binned
- *@return True if either child of node is binned.
- */
- virtual bool binned() const { return (l->binned() || r->binned()); }
-
- virtual std::string str() const
- {
- return csprintf("(%s %s %s)", l->str(), OpString<Op>::str(), r->str());
- }
-};
-
-template <class Op>
-class SumNode : public Node
-{
- public:
- NodePtr l;
- mutable VResult vresult;
-
- public:
- SumNode(NodePtr &p) : l(p), vresult(1) {}
-
- const VResult &result() const
- {
- const VResult &lvec = l->result();
- int size = lvec.size();
- assert(size > 0);
-
- vresult[0] = 0.0;
-
- Op op;
- for (int i = 0; i < size; ++i)
- vresult[0] = op(vresult[0], lvec[i]);
-
- return vresult;
- }
-
- Result total() const
- {
- const VResult &lvec = l->result();
- int size = lvec.size();
- assert(size > 0);
-
- Result vresult = 0.0;
-
- Op op;
- for (int i = 0; i < size; ++i)
- vresult = op(vresult, lvec[i]);
-
- return vresult;
- }
-
- virtual size_t size() const { return 1; }
- /**
- * Return true if child of node is binned.
- *@return True if child of node is binned.
- */
- virtual bool binned() const { return l->binned(); }
-
- virtual std::string str() const
- {
- return csprintf("total(%s)", l->str());
- }
-};
-
-
-//////////////////////////////////////////////////////////////////////
-//
-// Visible Statistics Types
-//
-//////////////////////////////////////////////////////////////////////
-/**
- * @defgroup VisibleStats "Statistic Types"
- * These are the statistics that are used in the simulator. By default these
- * store counters and don't use binning, but are templatized to accept any type
- * and any Bin class.
- * @{
- */
-
-/**
- * This is an easy way to assign all your stats to be binned or not
- * binned. If the typedef is NoBin, nothing is binned. If it is
- * MainBin, then all stats are binned under that Bin.
- */
-#if STATS_BINNING
-typedef MainBin DefaultBin;
-#else
-typedef NoBin DefaultBin;
-#endif
-
-/**
- * This is a simple scalar statistic, like a counter.
- * @sa Stat, ScalarBase, StatStor
- */
-template <class Bin = DefaultBin>
-class Scalar
- : public Wrap<Scalar<Bin>,
- ScalarBase<StatStor, Bin>,
- ScalarStatData>
-{
- public:
- /** The base implementation. */
- typedef ScalarBase<StatStor, Bin> Base;
-
- Scalar()
- {
- this->setInit();
- }
-
- /**
- * Sets the stat equal to the given value. Calls the base implementation
- * of operator=
- * @param v The new value.
- */
- template <typename U>
- void operator=(const U &v) { Base::operator=(v); }
-};
-
-class Value
- : public Wrap<Value,
- ValueBase,
- ScalarStatData>
-{
- public:
- /** The base implementation. */
- typedef ValueBase Base;
-
- template <class T>
- Value &scalar(T &value)
- {
- Base::scalar(value);
- return *this;
- }
-
- template <class T>
- Value &functor(T &func)
- {
- Base::functor(func);
- return *this;
- }
-};
-
-/**
- * A stat that calculates the per cycle average of a value.
- * @sa Stat, ScalarBase, AvgStor
- */
-template <class Bin = DefaultBin>
-class Average
- : public Wrap<Average<Bin>,
- ScalarBase<AvgStor, Bin>,
- ScalarStatData>
-{
- public:
- /** The base implementation. */
- typedef ScalarBase<AvgStor, Bin> Base;
-
- Average()
- {
- this->setInit();
- }
-
- /**
- * Sets the stat equal to the given value. Calls the base implementation
- * of operator=
- * @param v The new value.
- */
- template <typename U>
- void operator=(const U &v) { Base::operator=(v); }
-};
-
-/**
- * A vector of scalar stats.
- * @sa Stat, VectorBase, StatStor
- */
-template <class Bin = DefaultBin>
-class Vector
- : public WrapVec<Vector<Bin>,
- VectorBase<StatStor, Bin>,
- VectorStatData>
-{
- public:
- /** The base implementation. */
- typedef ScalarBase<StatStor, Bin> Base;
-
- /**
- * Set this vector to have the given size.
- * @param size The new size.
- * @return A reference to this stat.
- */
- Vector &init(size_t size) {
- this->bin.init(size, this->params);
- this->setInit();
-
- return *this;
- }
-};
-
-/**
- * A vector of Average stats.
- * @sa Stat, VectorBase, AvgStor
- */
-template <class Bin = DefaultBin>
-class AverageVector
- : public WrapVec<AverageVector<Bin>,
- VectorBase<AvgStor, Bin>,
- VectorStatData>
-{
- public:
- /**
- * Set this vector to have the given size.
- * @param size The new size.
- * @return A reference to this stat.
- */
- AverageVector &init(size_t size) {
- this->bin.init(size, this->params);
- this->setInit();
-
- return *this;
- }
-};
-
-/**
- * A 2-Dimensional vecto of scalar stats.
- * @sa Stat, Vector2dBase, StatStor
- */
-template <class Bin = DefaultBin>
-class Vector2d
- : public WrapVec2d<Vector2d<Bin>,
- Vector2dBase<StatStor, Bin>,
- Vector2dStatData>
-{
- public:
- Vector2d &init(size_t _x, size_t _y) {
- this->statData()->x = this->x = _x;
- this->statData()->y = this->y = _y;
- this->bin.init(this->x * this->y, this->params);
- this->setInit();
-
- return *this;
- }
-};
-
-/**
- * A simple distribution stat.
- * @sa Stat, DistBase, DistStor
- */
-template <class Bin = DefaultBin>
-class Distribution
- : public Wrap<Distribution<Bin>,
- DistBase<DistStor, Bin>,
- DistStatData>
-{
- public:
- /** Base implementation. */
- typedef DistBase<DistStor, Bin> Base;
- /** The Parameter type. */
- typedef typename DistStor::Params Params;
-
- public:
- /**
- * Set the parameters of this distribution. @sa DistStor::Params
- * @param min The minimum value of the distribution.
- * @param max The maximum value of the distribution.
- * @param bkt The number of values in each bucket.
- * @return A reference to this distribution.
- */
- Distribution &init(Counter min, Counter max, Counter bkt) {
- this->params.min = min;
- this->params.max = max;
- this->params.bucket_size = bkt;
- this->params.size = (int)rint((max - min) / bkt + 1.0);
- this->bin.init(this->params);
- this->setInit();
-
- return *this;
- }
-};
-
-/**
- * Calculates the mean and variance of all the samples.
- * @sa Stat, DistBase, FancyStor
- */
-template <class Bin = DefaultBin>
-class StandardDeviation
- : public Wrap<StandardDeviation<Bin>,
- DistBase<FancyStor, Bin>,
- DistStatData>
-{
- public:
- /** The base implementation */
- typedef DistBase<DistStor, Bin> Base;
- /** The parameter type. */
- typedef typename DistStor::Params Params;
-
- public:
- /**
- * Construct and initialize this distribution.
- */
- StandardDeviation() {
- this->bin.init(this->params);
- this->setInit();
- }
-};
-
-/**
- * Calculates the per cycle mean and variance of the samples.
- * @sa Stat, DistBase, AvgFancy
- */
-template <class Bin = DefaultBin>
-class AverageDeviation
- : public Wrap<AverageDeviation<Bin>,
- DistBase<AvgFancy, Bin>,
- DistStatData>
-{
- public:
- /** The base implementation */
- typedef DistBase<DistStor, Bin> Base;
- /** The parameter type. */
- typedef typename DistStor::Params Params;
-
- public:
- /**
- * Construct and initialize this distribution.
- */
- AverageDeviation()
- {
- this->bin.init(this->params);
- this->setInit();
- }
-};
-
-/**
- * A vector of distributions.
- * @sa Stat, VectorDistBase, DistStor
- */
-template <class Bin = DefaultBin>
-class VectorDistribution
- : public WrapVec<VectorDistribution<Bin>,
- VectorDistBase<DistStor, Bin>,
- VectorDistStatData>
-{
- public:
- /** The base implementation */
- typedef VectorDistBase<DistStor, Bin> Base;
- /** The parameter type. */
- typedef typename DistStor::Params Params;
-
- public:
- /**
- * Initialize storage and parameters for this distribution.
- * @param size The size of the vector (the number of distributions).
- * @param min The minimum value of the distribution.
- * @param max The maximum value of the distribution.
- * @param bkt The number of values in each bucket.
- * @return A reference to this distribution.
- */
- VectorDistribution &init(int size, Counter min, Counter max, Counter bkt) {
- this->params.min = min;
- this->params.max = max;
- this->params.bucket_size = bkt;
- this->params.size = (int)rint((max - min) / bkt + 1.0);
- this->bin.init(size, this->params);
- this->setInit();
-
- return *this;
- }
-};
-
-/**
- * This is a vector of StandardDeviation stats.
- * @sa Stat, VectorDistBase, FancyStor
- */
-template <class Bin = DefaultBin>
-class VectorStandardDeviation
- : public WrapVec<VectorStandardDeviation<Bin>,
- VectorDistBase<FancyStor, Bin>,
- VectorDistStatData>
-{
- public:
- /** The base implementation */
- typedef VectorDistBase<FancyStor, Bin> Base;
- /** The parameter type. */
- typedef typename DistStor::Params Params;
-
- public:
- /**
- * Initialize storage for this distribution.
- * @param size The size of the vector.
- * @return A reference to this distribution.
- */
- VectorStandardDeviation &init(int size) {
- this->bin.init(size, this->params);
- this->setInit();
-
- return *this;
- }
-};
-
-/**
- * This is a vector of AverageDeviation stats.
- * @sa Stat, VectorDistBase, AvgFancy
- */
-template <class Bin = DefaultBin>
-class VectorAverageDeviation
- : public WrapVec<VectorAverageDeviation<Bin>,
- VectorDistBase<AvgFancy, Bin>,
- VectorDistStatData>
-{
- public:
- /** The base implementation */
- typedef VectorDistBase<AvgFancy, Bin> Base;
- /** The parameter type. */
- typedef typename DistStor::Params Params;
-
- public:
- /**
- * Initialize storage for this distribution.
- * @param size The size of the vector.
- * @return A reference to this distribution.
- */
- VectorAverageDeviation &init(int size) {
- this->bin.init(size, this->params);
- this->setInit();
-
- return *this;
- }
-};
-
-/**
- * A formula for statistics that is calculated when printed. A formula is
- * stored as a tree of Nodes that represent the equation to calculate.
- * @sa Stat, ScalarStat, VectorStat, Node, Temp
- */
-class FormulaBase : public DataAccess
-{
- protected:
- /** The root of the tree which represents the Formula */
- NodePtr root;
- friend class Temp;
-
- public:
- /**
- * Return the result of the Fomula in a vector. If there were no Vector
- * components to the Formula, then the vector is size 1. If there were,
- * like x/y with x being a vector of size 3, then the result returned will
- * be x[0]/y, x[1]/y, x[2]/y, respectively.
- * @return The result vector.
- */
- void result(VResult &vec) const;
-
- /**
- * Return the total Formula result. If there is a Vector
- * component to this Formula, then this is the result of the
- * Formula if the formula is applied after summing all the
- * components of the Vector. For example, if Formula is x/y where
- * x is size 3, then total() will return (x[1]+x[2]+x[3])/y. If
- * there is no Vector component, total() returns the same value as
- * the first entry in the VResult val() returns.
- * @return The total of the result vector.
- */
- Result total() const;
-
- /**
- * Return the number of elements in the tree.
- */
- size_t size() const;
-
- /**
- * Return true if Formula is binned. i.e. any of its children
- * nodes are binned
- * @return True if Formula is binned.
- */
- bool binned() const;
-
- bool check() const { return true; }
-
- /**
- * Formulas don't need to be reset
- */
- void reset();
-
- /**
- *
- */
- bool zero() const;
-
- /**
- *
- */
- void update(StatData *);
-
- std::string str() const;
-};
-
-class FormulaData : public VectorData
-{
- public:
- virtual std::string str() const = 0;
- virtual bool check() const { return true; }
-};
-
-template <class Stat>
-class FormulaStatData : public FormulaData
-{
- protected:
- Stat &s;
- mutable VResult vec;
- mutable VCounter cvec;
-
- public:
- FormulaStatData(Stat &stat) : s(stat) {}
-
- virtual bool binned() const { return s.binned(); }
- virtual bool zero() const { return s.zero(); }
- virtual void reset() { s.reset(); }
-
- virtual size_t size() const { return s.size(); }
- virtual const VResult &result() const
- {
- s.result(vec);
- return vec;
- }
- virtual Result total() const { return s.total(); }
- virtual VCounter &value() const { return cvec; }
- virtual void visit(Visit &visitor)
- {
- update();
- s.update(this);
- visitor.visit(*this);
- }
- virtual std::string str() const { return s.str(); }
-};
-
-class Temp;
-class Formula
- : public WrapVec<Formula,
- FormulaBase,
- FormulaStatData>
-{
- public:
- /**
- * Create and initialize thie formula, and register it with the database.
- */
- Formula();
-
- /**
- * Create a formula with the given root node, register it with the
- * database.
- * @param r The root of the expression tree.
- */
- Formula(Temp r);
-
- /**
- * Set an unitialized Formula to the given root.
- * @param r The root of the expression tree.
- * @return a reference to this formula.
- */
- const Formula &operator=(Temp r);
-
- /**
- * Add the given tree to the existing one.
- * @param r The root of the expression tree.
- * @return a reference to this formula.
- */
- const Formula &operator+=(Temp r);
-};
-
-class FormulaNode : public Node
-{
- private:
- const Formula &formula;
- mutable VResult vec;
-
- public:
- FormulaNode(const Formula &f) : formula(f) {}
-
- virtual size_t size() const { return formula.size(); }
- virtual const VResult &result() const { formula.result(vec); return vec; }
- virtual Result total() const { return formula.total(); }
- virtual bool binned() const { return formula.binned(); }
-
- virtual std::string str() const { return formula.str(); }
-};
-
-/**
- * Helper class to construct formula node trees.
- */
-class Temp
-{
- protected:
- /**
- * Pointer to a Node object.
- */
- NodePtr node;
-
- public:
- /**
- * Copy the given pointer to this class.
- * @param n A pointer to a Node object to copy.
- */
- Temp(NodePtr n) : node(n) { }
-
- /**
- * Return the node pointer.
- * @return the node pointer.
- */
- operator NodePtr&() { return node;}
-
- public:
- /**
- * Create a new ScalarStatNode.
- * @param s The ScalarStat to place in a node.
- */
- template <class Bin>
- Temp(const Scalar<Bin> &s)
- : node(new ScalarStatNode(s.statData())) { }
-
- /**
- * Create a new ScalarStatNode.
- * @param s The ScalarStat to place in a node.
- */
- Temp(const Value &s)
- : node(new ScalarStatNode(s.statData())) { }
-
- /**
- * Create a new ScalarStatNode.
- * @param s The ScalarStat to place in a node.
- */
- template <class Bin>
- Temp(const Average<Bin> &s)
- : node(new ScalarStatNode(s.statData())) { }
-
- /**
- * Create a new VectorStatNode.
- * @param s The VectorStat to place in a node.
- */
- template <class Bin>
- Temp(const Vector<Bin> &s)
- : node(new VectorStatNode(s.statData())) { }
-
- /**
- *
- */
- Temp(const Formula &f)
- : node(new FormulaNode(f)) { }
-
- /**
- * Create a new ScalarProxyNode.
- * @param p The ScalarProxy to place in a node.
- */
- template <class Storage, class Bin>
- Temp(const ScalarProxy<Storage, Bin> &p)
- : node(new ScalarProxyNode<Storage, Bin>(p)) { }
-
- /**
- * Create a ConstNode
- * @param value The value of the const node.
- */
- Temp(signed char value)
- : node(new ConstNode<signed char>(value)) {}
-
- /**
- * Create a ConstNode
- * @param value The value of the const node.
- */
- Temp(unsigned char value)
- : node(new ConstNode<unsigned char>(value)) {}
-
- /**
- * Create a ConstNode
- * @param value The value of the const node.
- */
- Temp(signed short value)
- : node(new ConstNode<signed short>(value)) {}
-
- /**
- * Create a ConstNode
- * @param value The value of the const node.
- */
- Temp(unsigned short value)
- : node(new ConstNode<unsigned short>(value)) {}
-
- /**
- * Create a ConstNode
- * @param value The value of the const node.
- */
- Temp(signed int value)
- : node(new ConstNode<signed int>(value)) {}
-
- /**
- * Create a ConstNode
- * @param value The value of the const node.
- */
- Temp(unsigned int value)
- : node(new ConstNode<unsigned int>(value)) {}
-
- /**
- * Create a ConstNode
- * @param value The value of the const node.
- */
- Temp(signed long value)
- : node(new ConstNode<signed long>(value)) {}
-
- /**
- * Create a ConstNode
- * @param value The value of the const node.
- */
- Temp(unsigned long value)
- : node(new ConstNode<unsigned long>(value)) {}
-
- /**
- * Create a ConstNode
- * @param value The value of the const node.
- */
- Temp(signed long long value)
- : node(new ConstNode<signed long long>(value)) {}
-
- /**
- * Create a ConstNode
- * @param value The value of the const node.
- */
- Temp(unsigned long long value)
- : node(new ConstNode<unsigned long long>(value)) {}
-
- /**
- * Create a ConstNode
- * @param value The value of the const node.
- */
- Temp(float value)
- : node(new ConstNode<float>(value)) {}
-
- /**
- * Create a ConstNode
- * @param value The value of the const node.
- */
- Temp(double value)
- : node(new ConstNode<double>(value)) {}
-};
-
-
-/**
- * @}
- */
-
-void check();
-void reset();
-void registerResetCallback(Callback *cb);
-
-inline Temp
-operator+(Temp l, Temp r)
-{
- return NodePtr(new BinaryNode<std::plus<Result> >(l, r));
-}
-
-inline Temp
-operator-(Temp l, Temp r)
-{
- return NodePtr(new BinaryNode<std::minus<Result> >(l, r));
-}
-
-inline Temp
-operator*(Temp l, Temp r)
-{
- return NodePtr(new BinaryNode<std::multiplies<Result> >(l, r));
-}
-
-inline Temp
-operator/(Temp l, Temp r)
-{
- return NodePtr(new BinaryNode<std::divides<Result> >(l, r));
-}
-
-inline Temp
-operator-(Temp l)
-{
- return NodePtr(new UnaryNode<std::negate<Result> >(l));
-}
-
-template <typename T>
-inline Temp
-constant(T val)
-{
- return NodePtr(new ConstNode<T>(val));
-}
-
-inline Temp
-sum(Temp val)
-{
- return NodePtr(new SumNode<std::plus<Result> >(val));
-}
-
-/* namespace Stats */ }
-
-#endif // __BASE_STATISTICS_HH__