diff options
Diffstat (limited to 'base/statistics.hh')
-rw-r--r-- | base/statistics.hh | 2896 |
1 files changed, 0 insertions, 2896 deletions
diff --git a/base/statistics.hh b/base/statistics.hh deleted file mode 100644 index dd507c091..000000000 --- a/base/statistics.hh +++ /dev/null @@ -1,2896 +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 <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 *>(¶ms); - 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 *>(¶ms); - 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 *>(¶ms); - 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 ¶ms) - : 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 ¶ms) - { - 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 ¶ms) const - { - return samples == Counter(); - } - - void update(DistDataData *data, const Params ¶ms) - { - 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 ¶ms) - { - 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 ¶ms) - { - 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 ¶ms) const { return 1; } - /** - * Return true if no samples have been added. - * @return True if the sum is zero. - */ - bool zero(const Params ¶ms) 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 *>(¶ms); - 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 *>(¶ms); - 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__ |