statistics.hh
来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· HH 代码 · 共 2,775 行 · 第 1/5 页
HH
2,775 行
} void doInit() { new (storage) Storage(params); setInit(); } 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); } /** * Reset stat value to default */ void reset() { data()->reset(); } bool check() { return true; }};template <class Stat>class DistProxy;template <class Stor>class VectorDistBase : public DataAccess{ public: typedef Stor Storage; typedef typename Storage::Params Params; typedef DistProxy<VectorDistBase<Storage> > Proxy; friend class DistProxy<VectorDistBase<Storage> >; protected: Storage *storage; size_t _size; Params params; protected: Storage * data(int index) { return &storage[index]; } const Storage * data(int index) const { return &storage[index]; } void doInit(int s) { assert(s > 0 && "size must be positive!"); assert(!storage && "already initialized"); _size = s; char *ptr = new char[_size * sizeof(Storage)]; storage = reinterpret_cast<Storage *>(ptr); for (int i = 0; i < _size; ++i) new (&storage[i]) Storage(params); setInit(); } public: VectorDistBase() : storage(NULL) {} ~VectorDistBase() { if (!storage) return ; for (int i = 0; i < _size; ++i) data(i)->~Storage(); delete [] reinterpret_cast<char *>(storage); } Proxy operator[](int index); size_t size() const { return _size; } bool zero() const { return false;#if 0 for (int i = 0; i < size(); ++i) if (!data(i)->zero(params)) return false; return true;#endif } /** * Reset stat value to default */ void reset() { for (int i = 0; i < size(); ++i) data(i)->reset(); } bool check() { return storage != NULL; } 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 Stat>class DistProxy{ private: Stat *stat; int index; protected: typename Stat::Storage *data() { return stat->data(index); } const typename Stat::Storage *data() const { return stat->data(index); } public: DistProxy(Stat *s, int i) : stat(s), index(i) {} DistProxy(const DistProxy &sp) : stat(sp.stat), index(sp.index) {} const DistProxy &operator=(const DistProxy &sp) { stat = sp.stat; index = sp.index; return *this; } public: template <typename U> void sample(const U &v, int n = 1) { data()->sample(v, n, stat->params); } size_t size() const { return 1; } bool zero() const { return data()->zero(stat->params); } /** * Proxy has no state. Nothing to reset. */ void reset() { }};template <class Storage>inline typename VectorDistBase<Storage>::ProxyVectorDistBase<Storage>::operator[](int index){ assert (index >= 0 && index < size()); return typename VectorDistBase<Storage>::Proxy(this, index);}#if 0template <class Storage>ResultVectorDistBase<Storage>::total(int index) const{ int total = 0; for (int i = 0; i < x_size(); ++i) { total += data(i)->result(stat->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; /** * */ 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; } /** * */ virtual std::string str() const { return data->name; }};template <class Stat>class ScalarProxyNode : public Node{ private: const ScalarProxy<Stat> proxy; mutable VResult vresult; public: ScalarProxyNode(const ScalarProxy<Stat> &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; } /** * */ 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(); } 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; } virtual std::string str() const { return to_string(vresult[0]); }};template <class T>class ConstVectorNode : public Node{ private: VResult vresult; public: ConstVectorNode(const T &s) : vresult(s.begin(), s.end()) {} const VResult &result() const { return vresult; } virtual Result total() const { int size = this->size(); Result tmp = 0; for (int i = 0; i < size; i++) { tmp += vresult[i]; } return tmp; } virtual size_t size() const { return vresult.size(); } virtual std::string str() const { int size = this->size(); std::string tmp = "("; for (int i = 0; i < size; i++) { tmp += csprintf("%s ",to_string(vresult[i])); } tmp += ")"; return tmp; }};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 { const VResult &vec = this->result(); Result total = 0; for (int i = 0; i < size(); i++) total += vec[i]; return total; } virtual size_t size() const { return l->size(); } 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 { const VResult &vec = this->result(); Result total = 0; for (int i = 0; i < size(); i++) total += vec[i]; return 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; } } 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:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?