2 * Copyright (c) 2003 The Regents of The University of Michigan
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * Declaration of Statistics objects.
36 * Generalized N-dimensinal vector
40 * -- these both can use the same function that prints out a
41 * specific set of stats
42 * VectorStandardDeviation totals
45 #ifndef __STATISTICS_HH__
46 #define __STATISTICS_HH__
57 #include "base/cprintf.hh"
58 #include "base/intmath.hh"
59 #include "base/refcnt.hh"
60 #include "base/str.hh"
61 #include "sim/host.hh"
64 // Un-comment this to enable weirdo-stat debugging
71 /** Define Not a number. */
73 /** Need to define __nan() */
79 /** The current simulated cycle. */
82 /* A namespace for all of the Statistics */
83 namespace Statistics {
84 /** All results are doubles. */
85 typedef double result_t;
86 /** A vector to hold results. */
87 typedef std::vector<result_t> rvec_t;
90 * Define the storage for format flags.
91 * @todo Can probably shrink this.
93 typedef u_int32_t StatFlags;
95 /** Nothing extra to print. */
96 const StatFlags none = 0x00000000;
97 /** This Stat is Initialized */
98 const StatFlags init = 0x00000001;
99 /** Print this stat. */
100 const StatFlags print = 0x00000002;
101 /** Print the total. */
102 const StatFlags total = 0x00000010;
103 /** Print the percent of the total that this entry represents. */
104 const StatFlags pdf = 0x00000020;
105 /** Print the cumulative percentage of total upto this entry. */
106 const StatFlags cdf = 0x00000040;
107 /** Print the distribution. */
108 const StatFlags dist = 0x00000080;
109 /** Don't print if this is zero. */
110 const StatFlags nozero = 0x00000100;
111 /** Don't print if this is NAN */
112 const StatFlags nonan = 0x00000200;
113 /** Used for SS compatability. */
114 const StatFlags __substat = 0x80000000;
116 /** Mask of flags that can't be set directly */
117 const StatFlags __reserved = init | print | __substat;
126 extern DisplayMode DefaultMode;
128 /* Contains the statistic implementation details */
129 //////////////////////////////////////////////////////////////////////
131 // Statistics Framework Base classes
133 //////////////////////////////////////////////////////////////////////
136 /** The name of the stat. */
138 /** The description of the stat. */
140 /** The formatting flags. */
142 /** The display precision. */
146 /** A pointer to a prerequisite Stat. */
147 const StatData *prereq;
150 : flags(none), precision(-1), prereq(0)
156 * @return true if the stat is binned.
158 virtual bool binned() const = 0;
161 * Print this stat to the given ostream.
162 * @param stream The stream to print to.
164 virtual void display(std::ostream &stream, DisplayMode mode) const = 0;
165 bool dodisplay() const { return !prereq || !prereq->zero(); }
168 * Reset the corresponding stat to the default state.
170 virtual void reset() = 0;
173 * @return true if this stat has a value and satisfies its
174 * requirement as a prereq
176 virtual bool zero() const = 0;
179 * Check that this stat has been set up properly and is ready for
181 * @return true for success
183 virtual bool check() const = 0;
184 bool baseCheck() const;
187 * Checks if the first stat's name is alphabetically less than the second.
188 * This function breaks names up at periods and considers each subname
190 * @param stat1 The first stat.
191 * @param stat2 The second stat.
192 * @return stat1's name is alphabetically before stat2's
194 static bool less(StatData *stat1, StatData *stat2);
197 struct ScalarDataBase : public StatData
199 virtual result_t val() const = 0;
200 virtual result_t total() const = 0;
202 virtual void display(std::ostream &stream, DisplayMode mode) const;
206 class ScalarData : public ScalarDataBase
212 ScalarData(T &stat) : s(stat) {}
214 virtual bool binned() const { return s.binned(); }
215 virtual bool check() const { return s.check(); }
216 virtual result_t val() const { return s.val(); }
217 virtual result_t total() const { return s.total(); }
218 virtual void reset() { s.reset(); }
219 virtual bool zero() const { return s.zero(); }
222 struct VectorDataBase : public StatData
224 /** Names and descriptions of subfields. */
225 mutable std::vector<std::string> subnames;
226 mutable std::vector<std::string> subdescs;
228 virtual void display(std::ostream &stream, DisplayMode mode) const;
230 virtual size_t size() const = 0;
231 virtual const rvec_t &val() const = 0;
232 virtual result_t total() const = 0;
233 virtual void update()
235 if (!subnames.empty()) {
237 if (subnames.size() < s)
240 if (subdescs.size() < s)
247 class VectorData : public VectorDataBase
254 VectorData(T &stat) : s(stat) {}
256 virtual bool binned() const { return s.binned(); }
257 virtual bool check() const { return s.check(); }
258 virtual bool zero() const { return s.zero(); }
259 virtual void reset() { s.reset(); }
261 virtual size_t size() const { return s.size(); }
262 virtual const rvec_t &val() const
267 virtual result_t total() const { return s.total(); }
268 virtual void update()
270 VectorDataBase::update();
293 struct DistDataBase : public StatData
295 /** Local storage for the entry values, used for printing. */
298 virtual void display(std::ostream &stream, DisplayMode mode) const;
299 virtual void update() = 0;
303 class DistData : public DistDataBase
309 DistData(T &stat) : s(stat) {}
311 virtual bool binned() const { return s.binned(); }
312 virtual bool check() const { return s.check(); }
313 virtual void reset() { s.reset(); }
314 virtual bool zero() const { return s.zero(); }
315 virtual void update() { return s.update(this); }
318 struct VectorDistDataBase : public StatData
320 std::vector<DistDataData> data;
322 /** Names and descriptions of subfields. */
323 mutable std::vector<std::string> subnames;
324 mutable std::vector<std::string> subdescs;
326 /** Local storage for the entry values, used for printing. */
329 virtual size_t size() const = 0;
330 virtual void display(std::ostream &stream, DisplayMode mode) const;
331 virtual void update()
334 if (subnames.size() < s)
337 if (subdescs.size() < s)
343 class VectorDistData : public VectorDistDataBase
349 VectorDistData(T &stat) : s(stat) {}
351 virtual bool binned() const { return T::bin_t::binned; }
352 virtual bool check() const { return s.check(); }
353 virtual void reset() { s.reset(); }
354 virtual size_t size() const { return s.size(); }
355 virtual bool zero() const { return s.zero(); }
356 virtual void update()
358 VectorDistDataBase::update();
359 return s.update(this);
363 struct Vector2dDataBase : public StatData
365 /** Names and descriptions of subfields. */
366 std::vector<std::string> subnames;
367 std::vector<std::string> subdescs;
368 std::vector<std::string> y_subnames;
370 /** Local storage for the entry values, used for printing. */
375 virtual void display(std::ostream &stream, DisplayMode mode) const;
376 virtual void update()
378 if (subnames.size() < x)
384 class Vector2dData : public Vector2dDataBase
390 Vector2dData(T &stat) : s(stat) {}
392 virtual bool binned() const { return T::bin_t::binned; }
393 virtual bool check() const { return s.check(); }
394 virtual void reset() { s.reset(); }
395 virtual bool zero() const { return s.zero(); }
396 virtual void update()
398 Vector2dDataBase::update();
407 StatData *find() const;
408 void map(StatData *data);
410 StatData *statData();
411 const StatData *statData() const;
417 template <class Parent, class Child, template <class Child> class Data>
418 class Wrap : public Child
421 Parent &self() { return *reinterpret_cast<Parent *>(this); }
424 Data<Child> *statData()
426 StatData *__data = DataAccess::statData();
427 Data<Child> *ptr = dynamic_cast<Data<Child> *>(__data);
433 const Data<Child> *statData() const
435 const StatData *__data = DataAccess::statData();
436 const Data<Child> *ptr = dynamic_cast<const Data<Child> *>(__data);
444 map(new Data<Child>(*this));
448 * Set the name and marks this stat to print at the end of simulation.
449 * @param name The new name.
450 * @return A reference to this stat.
452 Parent &name(const std::string &_name)
454 Data<Child> *data = statData();
461 * Set the description and marks this stat to print at the end of
463 * @param desc The new description.
464 * @return A reference to this stat.
466 Parent &desc(const std::string &_desc)
468 statData()->desc = _desc;
473 * Set the precision and marks this stat to print at the end of simulation.
474 * @param p The new precision
475 * @return A reference to this stat.
477 Parent &precision(int _precision)
479 statData()->precision = _precision;
484 * Set the flags and marks this stat to print at the end of simulation.
485 * @param f The new flags.
486 * @return A reference to this stat.
488 Parent &flags(StatFlags _flags)
490 statData()->flags |= _flags;
495 * Set the prerequisite stat and marks this stat to print at the end of
497 * @param prereq The prerequisite stat.
498 * @return A reference to this stat.
501 Parent &prereq(const T &prereq)
503 statData()->prereq = prereq.statData();
508 template <class Parent, class Child, template <class Child> class Data>
509 class WrapVec : public Wrap<Parent, Child, Data>
512 // The following functions are specific to vectors. If you use them
513 // in a non vector context, you will get a nice compiler error!
516 * Set the subfield name for the given index, and marks this stat to print
517 * at the end of simulation.
518 * @param index The subfield index.
519 * @param name The new name of the subfield.
520 * @return A reference to this stat.
522 Parent &subname(int index, const std::string &name)
524 std::vector<std::string> &subn = statData()->subnames;
525 if (subn.size() <= index)
526 subn.resize(index + 1);
532 * Set the subfield description for the given index and marks this stat to
533 * print at the end of simulation.
534 * @param index The subfield index.
535 * @param desc The new description of the subfield
536 * @return A reference to this stat.
538 Parent &subdesc(int index, const std::string &desc)
540 std::vector<std::string> &subd = statData()->subdescs;
541 if (subd.size() <= index)
542 subd.resize(index + 1);
550 template <class Parent, class Child, template <class Child> class Data>
551 class WrapVec2d : public WrapVec<Parent, Child, Data>
555 * @warning This makes the assumption that if you're gonna subnames a 2d
556 * vector, you're subnaming across all y
558 Parent &ysubnames(const char **names)
560 Data<Child> *data = statData();
561 data->y_subnames.resize(y);
562 for (int i = 0; i < y; ++i)
563 data->y_subnames[i] = names[i];
566 Parent &ysubname(int index, const std::string subname)
568 Data<Child> *data = statData();
570 data->y_subnames.resize(y);
571 data->y_subnames[i] = subname.c_str();
576 //////////////////////////////////////////////////////////////////////
580 //////////////////////////////////////////////////////////////////////
583 * Templatized storage and interface for a simple scalar stat.
585 template <typename T>
589 /** The paramaters for this storage type, none for a scalar. */
593 /** The statistic value. */
603 * Builds this storage element and calls the base constructor of the
606 StatStor(const Params &) : data(Null()) {}
609 * The the stat to the given value.
610 * @param val The new value.
611 * @param p The paramters of this storage type.
613 void set(T val, const Params &p) { data = val; }
615 * Increment the stat by the given value.
616 * @param val The new value.
617 * @param p The paramters of this storage type.
619 void inc(T val, const Params &p) { data += val; }
621 * Decrement the stat by the given value.
622 * @param val The new value.
623 * @param p The paramters of this storage type.
625 void dec(T val, const Params &p) { data -= val; }
627 * Return the value of this stat as a result type.
628 * @param p The parameters of this storage type.
629 * @return The value of this stat.
631 result_t val(const Params &p) const { return (result_t)data; }
633 * Return the value of this stat as its base type.
634 * @param p The params of this storage type.
635 * @return The value of this stat.
637 T value(const Params &p) const { return data; }
639 * Reset stat value to default
641 void reset() { data = Null(); }
644 * @return true if zero value
646 bool zero() const { return data == Null(); }
650 * Templatized storage and interface to a per-cycle average stat. This keeps
651 * a current count and updates a total (count * cycles) when this count
652 * changes. This allows the quick calculation of a per cycle count of the item
653 * being watched. This is good for keeping track of residencies in structures
654 * among other things.
655 * @todo add lateny to the stat and fix binning.
657 template <typename T>
661 /** The paramaters for this storage type */
665 * The current count. We stash this here because the current
666 * value is not a binned value.
672 /** The total count for all cycles. */
673 mutable result_t total;
674 /** The cycle that current last changed. */
679 * Build and initializes this stat storage.
681 AvgStor(Params &p) : total(0), last(0) { p.current = T(); }
684 * Set the current count to the one provided, update the total and last
686 * @param val The new count.
687 * @param p The parameters for this storage.
689 void set(T val, Params &p) {
690 total += p.current * (curTick - last);
696 * Increment the current count by the provided value, calls set.
697 * @param val The amount to increment.
698 * @param p The parameters for this storage.
700 void inc(T val, Params &p) { set(p.current + val, p); }
703 * Deccrement the current count by the provided value, calls set.
704 * @param val The amount to decrement.
705 * @param p The parameters for this storage.
707 void dec(T val, Params &p) { set(p.current - val, p); }
710 * Return the current average.
711 * @param p The parameters for this storage.
712 * @return The current average.
714 result_t val(const Params &p) const {
715 total += p.current * (curTick - last);
717 return (result_t)(total + p.current) / (result_t)(curTick + 1);
721 * Return the current count.
722 * @param p The parameters for this storage.
723 * @return The current count.
725 T value(const Params &p) const { return p.current; }
728 * Reset stat value to default
737 * @return true if zero value
739 bool zero() const { return total == 0.0; }
743 * Implementation of a scalar stat. The type of stat is determined by the
744 * Storage template. The storage for this stat is held within the Bin class.
745 * This allows for breaking down statistics across multiple bins easily.
747 template <typename T, template <typename T> class Storage, class Bin>
748 class ScalarBase : public DataAccess
751 /** Define the type of the storage class. */
752 typedef Storage<T> storage_t;
753 /** Define the params of the storage class. */
754 typedef typename storage_t::Params params_t;
755 /** Define the bin type. */
756 typedef typename Bin::Bin<storage_t> bin_t;
759 /** The bin of this stat. */
761 /** The parameters for this stat. */
766 * Retrieve the storage from the bin.
767 * @return The storage object for this stat.
769 storage_t *data() { return bin.data(params); }
771 * Retrieve a const pointer to the storage from the bin.
772 * @return A const pointer to the storage object for this stat.
774 const storage_t *data() const
776 bin_t *_bin = const_cast<bin_t *>(&bin);
777 params_t *_params = const_cast<params_t *>(¶ms);
778 return _bin->data(*_params);
783 * Copy constructor, copies are not allowed.
785 ScalarBase(const ScalarBase &stat);
789 const ScalarBase &operator=(const ScalarBase &);
793 * Return the current value of this stat as its base type.
794 * @return The current value.
796 T value() const { return data()->value(params); }
800 * Create and initialize this stat, register it with the database.
808 // Common operators for stats
810 * Increment the stat by 1. This calls the associated storage object inc
813 void operator++() { data()->inc(1, params); }
815 * Decrement the stat by 1. This calls the associated storage object dec
818 void operator--() { data()->dec(1, params); }
820 /** Increment the stat by 1. */
821 void operator++(int) { ++*this; }
822 /** Decrement the stat by 1. */
823 void operator--(int) { --*this; }
826 * Set the data value to the given value. This calls the associated storage
827 * object set function.
828 * @param v The new value.
830 template <typename U>
831 void operator=(const U& v) { data()->set(v, params); }
834 * Increment the stat by the given value. This calls the associated
835 * storage object inc function.
836 * @param v The value to add.
838 template <typename U>
839 void operator+=(const U& v) { data()->inc(v, params); }
842 * Decrement the stat by the given value. This calls the associated
843 * storage object dec function.
844 * @param v The value to substract.
846 template <typename U>
847 void operator-=(const U& v) { data()->dec(v, params); }
850 * Return the number of elements, always 1 for a scalar.
853 size_t size() const { return 1; }
855 * Return true if stat is binned.
856 *@return True is stat is binned.
858 bool binned() const { return bin_t::binned; }
860 bool check() const { return bin.initialized(); }
863 * Reset stat value to default
865 void reset() { bin.reset(); }
867 result_t val() { return data()->val(params); }
869 result_t total() { return val(); }
871 bool zero() { return val() == 0.0; }
874 //////////////////////////////////////////////////////////////////////
878 //////////////////////////////////////////////////////////////////////
879 template <typename T, template <typename T> class Storage, class Bin>
883 * Implementation of a vector of stats. The type of stat is determined by the
884 * Storage class. @sa ScalarBase
886 template <typename T, template <typename T> class Storage, class Bin>
887 class VectorBase : public DataAccess
890 /** Define the type of the storage class. */
891 typedef Storage<T> storage_t;
892 /** Define the params of the storage class. */
893 typedef typename storage_t::Params params_t;
894 /** Define the bin type. */
895 typedef typename Bin::VectorBin<storage_t> bin_t;
898 /** The bin of this stat. */
900 /** The parameters for this stat. */
905 * Retrieve the storage from the bin for the given index.
906 * @param index The vector index to access.
907 * @return The storage object at the given index.
909 storage_t *data(int index) { return bin.data(index, params); }
911 * Retrieve a const pointer to the storage from the bin
912 * for the given index.
913 * @param index The vector index to access.
914 * @return A const pointer to the storage object at the given index.
916 const storage_t *data(int index) const
918 bin_t *_bin = const_cast<bin_t *>(&bin);
919 params_t *_params = const_cast<params_t *>(¶ms);
920 return _bin->data(index, *_params);
924 // Copying stats is not allowed
925 /** Copying stats isn't allowed. */
926 VectorBase(const VectorBase &stat);
927 /** Copying stats isn't allowed. */
928 const VectorBase &operator=(const VectorBase &);
932 * Copy the values to a local vector and return a reference to it.
933 * @return A reference to a vector of the stat values.
935 void val(rvec_t &vec) const
938 for (int i = 0; i < size(); ++i)
939 vec[i] = data(i)->val(params);
943 * @return True is stat is binned.
945 bool binned() const { return bin_t::binned; }
948 * Return a total of all entries in this vector.
949 * @return The total of all vector entries.
951 result_t total() const {
952 result_t total = 0.0;
953 for (int i = 0; i < size(); ++i)
954 total += data(i)->val(params);
959 * @return the number of elements in this vector.
961 size_t size() const { return bin.size(); }
965 for (int i = 0; i < size(); ++i)
971 bool check() const { return bin.initialized(); }
972 void reset() { bin.reset(); }
977 /** Friend this class with the associated scalar proxy. */
978 friend class ScalarProxy<T, Storage, Bin>;
981 * Return a reference (ScalarProxy) to the stat at the given index.
982 * @param index The vector index to access.
983 * @return A reference of the stat.
985 ScalarProxy<T, Storage, Bin> operator[](int index);
987 void update(StatData *data) {}
991 * A proxy class to access the stat at a given index in a VectorBase stat.
992 * Behaves like a ScalarBase.
994 template <typename T, template <typename T> class Storage, class Bin>
998 /** Define the type of the storage class. */
999 typedef Storage<T> storage_t;
1000 /** Define the params of the storage class. */
1001 typedef typename storage_t::Params params_t;
1002 /** Define the bin type. */
1003 typedef typename Bin::VectorBin<storage_t> bin_t;
1006 /** Pointer to the bin in the parent VectorBase. */
1008 /** Pointer to the params in the parent VectorBase. */
1010 /** The index to access in the parent VectorBase. */
1015 * Retrieve the storage from the bin.
1016 * @return The storage from the bin for this stat.
1018 storage_t *data() { return bin->data(index, *params); }
1020 * Retrieve a const pointer to the storage from the bin.
1021 * @return A const pointer to the storage for this stat.
1023 const storage_t *data() const
1025 bin_t *_bin = const_cast<bin_t *>(bin);
1026 params_t *_params = const_cast<params_t *>(params);
1027 return _bin->data(index, *_params);
1032 * Return the current value of this statas a result type.
1033 * @return The current value.
1035 result_t val() const { return data()->val(*params); }
1037 * Return the current value of this stat as its base type.
1038 * @return The current value.
1040 T value() const { return data()->value(*params); }
1044 * Create and initialize this proxy, do not register it with the database.
1045 * @param b The bin to use.
1046 * @param p The params to use.
1047 * @param i The index to access.
1049 ScalarProxy(bin_t &b, params_t &p, int i)
1050 : bin(&b), params(&p), index(i) {}
1052 * Create a copy of the provided ScalarProxy.
1053 * @param sp The proxy to copy.
1055 ScalarProxy(const ScalarProxy &sp)
1056 : bin(sp.bin), params(sp.params), index(sp.index) {}
1058 * Set this proxy equal to the provided one.
1059 * @param sp The proxy to copy.
1060 * @return A reference to this proxy.
1062 const ScalarProxy &operator=(const ScalarProxy &sp) {
1070 // Common operators for stats
1072 * Increment the stat by 1. This calls the associated storage object inc
1075 void operator++() { data()->inc(1, *params); }
1077 * Decrement the stat by 1. This calls the associated storage object dec
1080 void operator--() { data()->dec(1, *params); }
1082 /** Increment the stat by 1. */
1083 void operator++(int) { ++*this; }
1084 /** Decrement the stat by 1. */
1085 void operator--(int) { --*this; }
1088 * Set the data value to the given value. This calls the associated storage
1089 * object set function.
1090 * @param v The new value.
1092 template <typename U>
1093 void operator=(const U& v) { data()->set(v, *params); }
1096 * Increment the stat by the given value. This calls the associated
1097 * storage object inc function.
1098 * @param v The value to add.
1100 template <typename U>
1101 void operator+=(const U& v) { data()->inc(v, *params); }
1104 * Decrement the stat by the given value. This calls the associated
1105 * storage object dec function.
1106 * @param v The value to substract.
1108 template <typename U>
1109 void operator-=(const U& v) { data()->dec(v, *params); }
1112 * Return the number of elements, always 1 for a scalar.
1115 size_t size() const { return 1; }
1118 * Return true if stat is binned.
1119 *@return false since Proxies aren't printed/binned
1121 bool binned() const { return false; }
1124 * This stat has no state. Nothing to reset
1129 template <typename T, template <typename T> class Storage, class Bin>
1130 inline ScalarProxy<T, Storage, Bin>
1131 VectorBase<T, Storage, Bin>::operator[](int index)
1133 assert (index >= 0 && index < size());
1134 return ScalarProxy<T, Storage, Bin>(bin, params, index);
1137 template <typename T, template <typename T> class Storage, class Bin>
1140 template <typename T, template <typename T> class Storage, class Bin>
1141 class Vector2dBase : public DataAccess
1144 typedef Storage<T> storage_t;
1145 typedef typename storage_t::Params params_t;
1148 typedef typename Bin::VectorBin<storage_t> bin_t;
1157 storage_t *data(int index) { return bin.data(index, params); }
1158 const storage_t *data(int index) const
1160 bin_t *_bin = const_cast<bin_t *>(&bin);
1161 params_t *_params = const_cast<params_t *>(¶ms);
1162 return _bin->data(index, *_params);
1166 // Copying stats is not allowed
1167 Vector2dBase(const Vector2dBase &stat);
1168 const Vector2dBase &operator=(const Vector2dBase &);
1173 void update(Vector2dDataBase *data)
1175 int size = this->size();
1176 data->vec.resize(size);
1177 for (int i = 0; i < size; ++i)
1178 data->vec[i] = this->data(i)->val(params);
1181 std::string ysubname(int i) const { return (*y_subnames)[i]; }
1183 friend class VectorProxy<T, Storage, Bin>;
1184 VectorProxy<T, Storage, Bin> operator[](int index);
1186 size_t size() const { return bin.size(); }
1187 bool zero() const { return data(0)->value(params) == 0.0; }
1190 * Reset stat value to default
1192 void reset() { bin.reset(); }
1194 bool check() { return bin.initialized(); }
1197 template <typename T, template <typename T> class Storage, class Bin>
1201 typedef Storage<T> storage_t;
1202 typedef typename storage_t::Params params_t;
1203 typedef typename Bin::VectorBin<storage_t> bin_t;
1212 mutable rvec_t *vec;
1214 storage_t *data(int index) {
1215 assert(index < len);
1216 return bin->data(offset + index, *params);
1219 const storage_t *data(int index) const {
1220 bin_t *_bin = const_cast<bin_t *>(bin);
1221 params_t *_params = const_cast<params_t *>(params);
1222 return _bin->data(offset + index, *_params);
1226 const rvec_t &val() const {
1228 vec->resize(size());
1230 vec = new rvec_t(size());
1232 for (int i = 0; i < size(); ++i)
1233 (*vec)[i] = data(i)->val(*params);
1238 result_t total() const {
1239 result_t total = 0.0;
1240 for (int i = 0; i < size(); ++i)
1241 total += data(i)->val(*params);
1246 VectorProxy(bin_t &b, params_t &p, int o, int l)
1247 : bin(&b), params(&p), offset(o), len(l), vec(NULL)
1249 VectorProxy(const VectorProxy &sp)
1250 : bin(sp.bin), params(sp.params), offset(sp.offset), len(sp.len),
1258 const VectorProxy &operator=(const VectorProxy &sp)
1270 ScalarProxy<T, Storage, Bin> operator[](int index)
1272 assert (index >= 0 && index < size());
1273 return ScalarProxy<T, Storage, Bin>(*bin, *params, offset + index);
1276 size_t size() const { return len; }
1279 * Return true if stat is binned.
1280 *@return false since Proxies aren't printed/binned
1282 bool binned() const { return false; }
1285 * This stat has no state. Nothing to reset.
1290 template <typename T, template <typename T> class Storage, class Bin>
1291 inline VectorProxy<T, Storage, Bin>
1292 Vector2dBase<T, Storage, Bin>::operator[](int index)
1294 int offset = index * y;
1295 assert (index >= 0 && offset < size());
1296 return VectorProxy<T, Storage, Bin>(bin, params, offset, y);
1299 //////////////////////////////////////////////////////////////////////
1301 // Non formula statistics
1303 //////////////////////////////////////////////////////////////////////
1306 * Templatized storage and interface for a distrbution stat.
1308 template <typename T>
1312 /** The parameters for a distribution stat. */
1315 /** The minimum value to track. */
1317 /** The maximum value to track. */
1319 /** The number of entries in each bucket. */
1321 /** The number of buckets. Equal to (max-min)/bucket_size. */
1324 enum { fancy = false };
1327 /** The smallest value sampled. */
1329 /** The largest value sampled. */
1331 /** The number of values sampled less than min. */
1333 /** The number of values sampled more than max. */
1335 /** The current sum. */
1337 /** The sum of squares. */
1339 /** The number of samples. */
1341 /** Counter for each bucket. */
1346 * Construct this storage with the supplied params.
1347 * @param params The parameters.
1349 DistStor(const Params ¶ms)
1350 : min_val(INT_MAX), max_val(INT_MIN), underflow(0), overflow(0),
1351 sum(T()), squares(T()), samples(0), vec(params.size)
1357 * Add a value to the distribution for the given number of times.
1358 * @param val The value to add.
1359 * @param number The number of times to add the value.
1360 * @param params The paramters of the distribution.
1362 void sample(T val, int number, const Params ¶ms)
1364 if (val < params.min)
1365 underflow += number;
1366 else if (val > params.max)
1369 int index = (val - params.min) / params.bucket_size;
1370 assert(index < size(params));
1371 vec[index] += number;
1380 T sample = val * number;
1382 squares += sample * sample;
1387 * Return the number of buckets in this distribution.
1388 * @return the number of buckets.
1389 * @todo Is it faster to return the size from the parameters?
1391 size_t size(const Params &) const { return vec.size(); }
1394 * Returns true if any calls to sample have been made.
1395 * @param params The paramters of the distribution.
1396 * @return True if any values have been sampled.
1398 bool zero(const Params ¶ms) const
1400 return samples == 0;
1403 void update(DistDataData *data, const Params ¶ms)
1405 data->min = params.min;
1406 data->max = params.max;
1407 data->bucket_size = params.bucket_size;
1408 data->size = params.size;
1410 data->min_val = (min_val == INT_MAX) ? 0 : min_val;
1411 data->max_val = (max_val == INT_MIN) ? 0 : max_val;
1412 data->underflow = underflow;
1413 data->overflow = overflow;
1414 data->vec.resize(params.size);
1415 for (int i = 0; i < params.size; ++i)
1416 data->vec[i] = vec[i];
1419 data->squares = squares;
1420 data->samples = samples;
1424 * Reset stat value to default
1433 int size = vec.size();
1434 for (int i = 0; i < size; ++i)
1444 * Templatized storage and interface for a distribution that calculates mean
1447 template <typename T>
1452 * No paramters for this storage.
1455 enum { fancy = true };
1458 /** The current sum. */
1460 /** The sum of squares. */
1462 /** The number of samples. */
1467 * Create and initialize this storage.
1469 FancyStor(const Params &) : sum(T()), squares(T()), samples(0) {}
1472 * Add a value the given number of times to this running average.
1473 * Update the running sum and sum of squares, increment the number of
1474 * values seen by the given number.
1475 * @param val The value to add.
1476 * @param number The number of times to add the value.
1477 * @param p The parameters of this stat.
1479 void sample(T val, int number, const Params &p)
1481 T value = val * number;
1483 squares += value * value;
1487 void update(DistDataData *data, const Params ¶ms)
1490 data->squares = squares;
1491 data->samples = samples;
1495 * Return the number of entries in this stat, 1
1498 size_t size(const Params &) const { return 1; }
1501 * Return true if no samples have been added.
1502 * @return True if no samples have been added.
1504 bool zero(const Params &) const { return samples == 0; }
1507 * Reset stat value to default
1518 * Templatized storage for distribution that calculates per cycle mean and
1521 template <typename T>
1525 /** No parameters for this storage. */
1527 enum { fancy = true };
1530 /** Current total. */
1532 /** Current sum of squares. */
1537 * Create and initialize this storage.
1539 AvgFancy(const Params &) : sum(T()), squares(T()) {}
1542 * Add a value to the distribution for the given number of times.
1543 * Update the running sum and sum of squares.
1544 * @param val The value to add.
1545 * @param number The number of times to add the value.
1546 * @param p The paramters of the distribution.
1548 void sample(T val, int number, const Params& p)
1550 T value = val * number;
1552 squares += value * value;
1555 void update(DistDataData *data, const Params ¶ms)
1558 data->squares = squares;
1559 data->samples = curTick;
1563 * Return the number of entries, in this case 1.
1566 size_t size(const Params ¶ms) const { return 1; }
1568 * Return true if no samples have been added.
1569 * @return True if the sum is zero.
1571 bool zero(const Params ¶ms) const { return sum == 0; }
1573 * Reset stat value to default
1583 * Implementation of a distribution stat. The type of distribution is
1584 * determined by the Storage template. @sa ScalarBase
1586 template <typename T, template <typename T> class Storage, class Bin>
1587 class DistBase : public DataAccess
1590 /** Define the type of the storage class. */
1591 typedef Storage<T> storage_t;
1592 /** Define the params of the storage class. */
1593 typedef typename storage_t::Params params_t;
1594 /** Define the bin type. */
1595 typedef typename Bin::Bin<storage_t> bin_t;
1598 /** The bin of this stat. */
1600 /** The parameters for this stat. */
1605 * Retrieve the storage from the bin.
1606 * @return The storage object for this stat.
1608 storage_t *data() { return bin.data(params); }
1610 * Retrieve a const pointer to the storage from the bin.
1611 * @return A const pointer to the storage object for this stat.
1613 const storage_t *data() const
1615 bin_t *_bin = const_cast<bin_t *>(&bin);
1616 params_t *_params = const_cast<params_t *>(¶ms);
1617 return _bin->data(*_params);
1621 // Copying stats is not allowed
1622 /** Copies are not allowed. */
1623 DistBase(const DistBase &stat);
1624 /** Copies are not allowed. */
1625 const DistBase &operator=(const DistBase &);
1631 * Add a value to the distribtion n times. Calls sample on the storage
1633 * @param v The value to add.
1634 * @param n The number of times to add it, defaults to 1.
1636 template <typename U>
1637 void sample(const U& v, int n = 1) { data()->sample(v, n, params); }
1640 * Return the number of entries in this stat.
1641 * @return The number of entries.
1643 size_t size() const { return data()->size(params); }
1645 * Return true if no samples have been added.
1646 * @return True if there haven't been any samples.
1648 bool zero() const { return data()->zero(params); }
1650 void update(DistDataBase *base)
1652 base->data.fancy = storage_t::fancy;
1653 data()->update(&(base->data), params);
1656 * @return True is stat is binned.
1658 bool binned() const { return bin_t::binned; }
1660 * Reset stat value to default
1667 bool check() { return bin.initialized(); }
1670 template <typename T, template <typename T> class Storage, class Bin>
1673 template <typename T, template <typename T> class Storage, class Bin>
1674 class VectorDistBase : public DataAccess
1677 typedef Storage<T> storage_t;
1678 typedef typename storage_t::Params params_t;
1681 typedef typename Bin::VectorBin<storage_t> bin_t;
1688 storage_t *data(int index) { return bin.data(index, params); }
1689 const storage_t *data(int index) const
1691 bin_t *_bin = const_cast<bin_t *>(&bin);
1692 params_t *_params = const_cast<params_t *>(¶ms);
1693 return _bin->data(index, *_params);
1697 // Copying stats is not allowed
1698 VectorDistBase(const VectorDistBase &stat);
1699 const VectorDistBase &operator=(const VectorDistBase &);
1704 friend class DistProxy<T, Storage, Bin>;
1705 DistProxy<T, Storage, Bin> operator[](int index);
1706 const DistProxy<T, Storage, Bin> operator[](int index) const;
1708 size_t size() const { return bin.size(); }
1709 bool zero() const { return false; }
1711 * Return true if stat is binned.
1712 *@return True is stat is binned.
1714 bool binned() const { return bin_t::binned; }
1716 * Reset stat value to default
1718 void reset() { bin.reset(); }
1720 bool check() { return bin.initialized(); }
1721 void update(VectorDistDataBase *base)
1723 int size = this->size();
1724 base->data.resize(size);
1725 for (int i = 0; i < size; ++i) {
1726 base->data[i].fancy = storage_t::fancy;
1727 data(i)->update(&(base->data[i]), params);
1732 template <typename T, template <typename T> class Storage, class Bin>
1736 typedef Storage<T> storage_t;
1737 typedef typename storage_t::Params params_t;
1738 typedef typename Bin::Bin<storage_t> bin_t;
1739 typedef VectorDistBase<T, Storage, Bin> base_t;
1744 const base_t *cstat;
1749 storage_t *data() { return stat->data(index); }
1750 const storage_t *data() const { return cstat->data(index); }
1753 DistProxy(const VectorDistBase<T, Storage, Bin> &s, int i)
1754 : cstat(&s), index(i) {}
1755 DistProxy(const DistProxy &sp)
1756 : cstat(sp.cstat), index(sp.index) {}
1757 const DistProxy &operator=(const DistProxy &sp) {
1758 cstat = sp.cstat; index = sp.index; return *this;
1762 template <typename U>
1763 void sample(const U& v, int n = 1) { data()->sample(v, n, cstat->params); }
1765 size_t size() const { return 1; }
1766 bool zero() const { return data()->zero(cstat->params); }
1768 * Return true if stat is binned.
1769 *@return false since Proxies are not binned/printed.
1771 bool binned() const { return false; }
1773 * Proxy has no state. Nothing to reset.
1778 template <typename T, template <typename T> class Storage, class Bin>
1779 inline DistProxy<T, Storage, Bin>
1780 VectorDistBase<T, Storage, Bin>::operator[](int index)
1782 assert (index >= 0 && index < size());
1783 return DistProxy<T, Storage, Bin>(*this, index);
1786 template <typename T, template <typename T> class Storage, class Bin>
1787 inline const DistProxy<T, Storage, Bin>
1788 VectorDistBase<T, Storage, Bin>::operator[](int index) const
1790 assert (index >= 0 && index < size());
1791 return DistProxy<T, Storage, Bin>(*this, index);
1795 template <typename T, template <typename T> class Storage, class Bin>
1797 VectorDistBase<T, Storage, Bin>::total(int index) const
1800 for (int i=0; i < x_size(); ++i) {
1801 total += data(i)->val(*params);
1806 //////////////////////////////////////////////////////////////////////
1810 //////////////////////////////////////////////////////////////////////
1813 * Base class for formula statistic node. These nodes are used to build a tree
1814 * that represents the formula.
1816 class Node : public RefCounted
1820 * Return the number of nodes in the subtree starting at this node.
1821 * @return the number of nodes in this subtree.
1823 virtual size_t size() const = 0;
1825 * Return the result vector of this subtree.
1826 * @return The result vector of this subtree.
1828 virtual const rvec_t &val() const = 0;
1830 * Return the total of the result vector.
1831 * @return The total of the result vector.
1833 virtual result_t total() const = 0;
1835 * Return true if stat is binned.
1836 *@return True is stat is binned.
1838 virtual bool binned() const = 0;
1841 /** Reference counting pointer to a function Node. */
1842 typedef RefCountingPtr<Node> NodePtr;
1844 class ScalarStatNode : public Node
1847 const ScalarDataBase *data;
1848 mutable rvec_t result;
1851 ScalarStatNode(const ScalarDataBase *d) : data(d), result(1) {}
1852 virtual const rvec_t &val() const
1854 result[0] = data->val();
1857 virtual result_t total() const { return data->val(); };
1859 virtual size_t size() const { return 1; }
1861 * Return true if stat is binned.
1862 *@return True is stat is binned.
1864 virtual bool binned() const { return data->binned(); }
1867 template <typename T, template <typename T> class Storage, class Bin>
1868 class ScalarProxyNode : public Node
1871 const ScalarProxy<T, Storage, Bin> proxy;
1872 mutable rvec_t result;
1875 ScalarProxyNode(const ScalarProxy<T, Storage, Bin> &p)
1876 : proxy(p), result(1) { }
1877 virtual const rvec_t &val() const
1879 result[0] = proxy.val();
1882 virtual result_t total() const { return proxy.val(); };
1884 virtual size_t size() const { return 1; }
1886 * Return true if stat is binned.
1887 *@return True is stat is binned.
1889 virtual bool binned() const { return proxy.binned(); }
1892 class VectorStatNode : public Node
1895 const VectorDataBase *data;
1898 VectorStatNode(const VectorDataBase *d) : data(d) { }
1899 virtual const rvec_t &val() const { return data->val(); }
1900 virtual result_t total() const { return data->total(); };
1902 virtual size_t size() const { return data->size(); }
1904 * Return true if stat is binned.
1905 *@return True is stat is binned.
1907 virtual bool binned() const { return data->binned(); }
1910 template <typename T>
1911 class ConstNode : public Node
1917 ConstNode(T s) : data(1, (result_t)s) {}
1918 const rvec_t &val() const { return data; }
1919 virtual result_t total() const { return data[0]; };
1921 virtual size_t size() const { return 1; }
1923 * Return true if stat is binned.
1924 *@return False since constants aren't binned.
1926 virtual bool binned() const { return false; }
1929 template <typename T>
1930 class FunctorNode : public Node
1934 mutable rvec_t result;
1937 FunctorNode(T &f) : functor(f) { result.resize(1); }
1938 const rvec_t &val() const {
1939 result[0] = (result_t)functor();
1942 virtual result_t total() const { return (result_t)functor(); };
1944 virtual size_t size() const { return 1; }
1946 * Return true if stat is binned.
1947 *@return False since Functors aren't binned
1949 virtual bool binned() const { return false; }
1952 template <typename T>
1953 class ScalarNode : public Node
1957 mutable rvec_t result;
1960 ScalarNode(T &s) : scalar(s) { result.resize(1); }
1961 const rvec_t &val() const {
1962 result[0] = (result_t)scalar;
1965 virtual result_t total() const { return (result_t)scalar; };
1967 virtual size_t size() const { return 1; }
1969 * Return true if stat is binned.
1970 *@return False since Scalar's aren't binned
1972 virtual bool binned() const { return false; }
1976 class UnaryNode : public Node
1980 mutable rvec_t result;
1983 UnaryNode(NodePtr p) : l(p) {}
1985 const rvec_t &val() const {
1986 const rvec_t &lvec = l->val();
1987 int size = lvec.size();
1991 result.resize(size);
1993 for (int i = 0; i < size; ++i)
1994 result[i] = op(lvec[i]);
1999 result_t total() const {
2001 return op(l->total());
2004 virtual size_t size() const { return l->size(); }
2006 * Return true if child of node is binned.
2007 *@return True if child of node is binned.
2009 virtual bool binned() const { return l->binned(); }
2013 class BinaryNode : public Node
2018 mutable rvec_t result;
2021 BinaryNode(NodePtr a, NodePtr b) : l(a), r(b) {}
2023 const rvec_t &val() const {
2025 const rvec_t &lvec = l->val();
2026 const rvec_t &rvec = r->val();
2028 assert(lvec.size() > 0 && rvec.size() > 0);
2030 if (lvec.size() == 1 && rvec.size() == 1) {
2032 result[0] = op(lvec[0], rvec[0]);
2033 } else if (lvec.size() == 1) {
2034 int size = rvec.size();
2035 result.resize(size);
2036 for (int i = 0; i < size; ++i)
2037 result[i] = op(lvec[0], rvec[i]);
2038 } else if (rvec.size() == 1) {
2039 int size = lvec.size();
2040 result.resize(size);
2041 for (int i = 0; i < size; ++i)
2042 result[i] = op(lvec[i], rvec[0]);
2043 } else if (rvec.size() == lvec.size()) {
2044 int size = rvec.size();
2045 result.resize(size);
2046 for (int i = 0; i < size; ++i)
2047 result[i] = op(lvec[i], rvec[i]);
2053 result_t total() const {
2055 return op(l->total(), r->total());
2058 virtual size_t size() const {
2066 assert(ls == rs && "Node vector sizes are not equal");
2071 * Return true if any children of node are binned
2072 *@return True if either child of node is binned.
2074 virtual bool binned() const { return (l->binned() || r->binned()); }
2078 class SumNode : public Node
2082 mutable rvec_t result;
2085 SumNode(NodePtr p) : l(p), result(1) {}
2087 const rvec_t &val() const {
2088 const rvec_t &lvec = l->val();
2089 int size = lvec.size();
2095 for (int i = 0; i < size; ++i)
2096 result[0] = op(result[0], lvec[i]);
2101 result_t total() const {
2102 const rvec_t &lvec = l->val();
2103 int size = lvec.size();
2106 result_t result = 0.0;
2109 for (int i = 0; i < size; ++i)
2110 result = op(result, lvec[i]);
2115 virtual size_t size() const { return 1; }
2117 * Return true if child of node is binned.
2118 *@return True if child of node is binned.
2120 virtual bool binned() const { return l->binned(); }
2123 //////////////////////////////////////////////////////////////////////
2125 // Binning Interface
2127 //////////////////////////////////////////////////////////////////////
2136 off_t size() const { return memsize; }
2137 char *memory(off_t off);
2140 static MainBin *&curBin()
2142 static MainBin *current = NULL;
2146 static void setCurBin(MainBin *bin) { curBin() = bin; }
2147 static MainBin *current() { assert(curBin()); return curBin(); }
2149 static off_t &offset()
2151 static off_t offset = 0;
2155 static off_t new_offset(size_t size)
2157 size_t mask = sizeof(u_int64_t) - 1;
2158 off_t off = offset();
2160 // That one is for the last trailing flags byte.
2161 offset() += (size + 1 + mask) & ~mask;
2166 MainBin(const std::string &name);
2187 BinBase() : offset(-1) {}
2188 void allocate(size_t size)
2190 offset = new_offset(size);
2194 assert(offset != -1);
2195 return current()->memory(offset);
2199 template <class Storage>
2200 class Bin : public BinBase
2203 typedef typename Storage::Params Params;
2206 enum { binned = true };
2207 Bin() { allocate(sizeof(Storage)); }
2208 bool initialized() const { return true; }
2209 void init(Params ¶ms) { }
2211 int size() const { return 1; }
2214 data(Params ¶ms)
2216 assert(initialized());
2217 char *ptr = access();
2218 char *flags = ptr + sizeof(Storage);
2219 if (!(*flags & 0x1)) {
2221 new (ptr) Storage(params);
2223 return reinterpret_cast<Storage *>(ptr);
2229 char *ptr = access();
2230 char *flags = ptr + size() * sizeof(Storage);
2231 if (!(*flags & 0x1))
2234 Storage *s = reinterpret_cast<Storage *>(ptr);
2239 template <class Storage>
2240 class VectorBin : public BinBase
2243 typedef typename Storage::Params Params;
2249 enum { binned = true };
2250 VectorBin() : _size(0) {}
2252 bool initialized() const { return _size > 0; }
2253 void init(int s, Params ¶ms)
2255 assert(!initialized());
2258 allocate(_size * sizeof(Storage));
2261 int size() const { return _size; }
2263 Storage *data(int index, Params ¶ms)
2265 assert(initialized());
2266 assert(index >= 0 && index < size());
2267 char *ptr = access();
2268 char *flags = ptr + size() * sizeof(Storage);
2269 if (!(*flags & 0x1)) {
2271 for (int i = 0; i < size(); ++i)
2272 new (ptr + i * sizeof(Storage)) Storage(params);
2274 return reinterpret_cast<Storage *>(ptr + index * sizeof(Storage));
2278 char *ptr = access();
2279 char *flags = ptr + size() * sizeof(Storage);
2280 if (!(*flags & 0x1))
2283 for (int i = 0; i < _size; ++i) {
2284 char *p = ptr + i * sizeof(Storage);
2285 Storage *s = reinterpret_cast<Storage *>(p);
2294 template <class Storage>
2298 typedef typename Storage::Params Params;
2299 enum { binned = false };
2302 char ptr[sizeof(Storage)];
2307 reinterpret_cast<Storage *>(ptr)->~Storage();
2310 bool initialized() const { return true; }
2311 void init(Params ¶ms)
2313 new (ptr) Storage(params);
2315 int size() const{ return 1; }
2316 Storage *data(Params ¶ms)
2318 assert(initialized());
2319 return reinterpret_cast<Storage *>(ptr);
2323 Storage *s = reinterpret_cast<Storage *>(ptr);
2328 template <class Storage>
2332 typedef typename Storage::Params Params;
2333 enum { binned = false };
2340 VectorBin() : ptr(NULL) { }
2346 for (int i = 0; i < _size; ++i) {
2347 char *p = ptr + i * sizeof(Storage);
2348 reinterpret_cast<Storage *>(p)->~Storage();
2353 bool initialized() const { return ptr != NULL; }
2354 void init(int s, Params ¶ms)
2356 assert(s > 0 && "size must be positive!");
2357 assert(!initialized());
2359 ptr = new char[_size * sizeof(Storage)];
2360 for (int i = 0; i < _size; ++i)
2361 new (ptr + i * sizeof(Storage)) Storage(params);
2364 int size() const { return _size; }
2366 Storage *data(int index, Params ¶ms)
2368 assert(initialized());
2369 assert(index >= 0 && index < size());
2370 return reinterpret_cast<Storage *>(ptr + index * sizeof(Storage));
2374 for (int i = 0; i < _size; ++i) {
2375 char *p = ptr + i * sizeof(Storage);
2376 Storage *s = reinterpret_cast<Storage *>(p);
2383 //////////////////////////////////////////////////////////////////////
2385 // Visible Statistics Types
2387 //////////////////////////////////////////////////////////////////////
2389 * @defgroup VisibleStats "Statistic Types"
2390 * These are the statistics that are used in the simulator. By default these
2391 * store counters and don't use binning, but are templatized to accept any type
2392 * and any Bin class.
2397 * This is an easy way to assign all your stats to be binned or not
2398 * binned. If the typedef is NoBin, nothing is binned. If it is
2399 * MainBin, then all stats are binned under that Bin.
2402 typedef MainBin DefaultBin;
2404 typedef NoBin DefaultBin;
2408 * This is a simple scalar statistic, like a counter.
2409 * @sa Stat, ScalarBase, StatStor
2411 template <typename T = Counter, class Bin = DefaultBin>
2412 class Scalar : public Wrap<Scalar<T, Bin>, ScalarBase<T, StatStor, Bin>, ScalarData>
2415 /** The base implementation. */
2416 typedef ScalarBase<T, StatStor, Bin> Base;
2424 * Sets the stat equal to the given value. Calls the base implementation
2426 * @param v The new value.
2428 template <typename U>
2429 void operator=(const U& v) { Base::operator=(v); }
2433 * A stat that calculates the per cycle average of a value.
2434 * @sa Stat, ScalarBase, AvgStor
2436 template <typename T = Counter, class Bin = DefaultBin>
2437 class Average : public Wrap<Average<T, Bin>, ScalarBase<T, AvgStor, Bin>, ScalarData>
2440 /** The base implementation. */
2441 typedef ScalarBase<T, AvgStor, Bin> Base;
2449 * Sets the stat equal to the given value. Calls the base implementation
2451 * @param v The new value.
2453 template <typename U>
2454 void operator=(const U& v) { Base::operator=(v); }
2458 * A vector of scalar stats.
2459 * @sa Stat, VectorBase, StatStor
2461 template <typename T = Counter, class Bin = DefaultBin>
2462 class Vector : public WrapVec<Vector<T, Bin>, VectorBase<T, StatStor, Bin>, VectorData>
2466 * Set this vector to have the given size.
2467 * @param size The new size.
2468 * @return A reference to this stat.
2470 Vector &init(size_t size) {
2471 bin.init(size, params);
2479 * A vector of Average stats.
2480 * @sa Stat, VectorBase, AvgStor
2482 template <typename T = Counter, class Bin = DefaultBin>
2483 class AverageVector : public WrapVec<AverageVector<T, Bin>, VectorBase<T, AvgStor, Bin>, VectorData>
2487 * Set this vector to have the given size.
2488 * @param size The new size.
2489 * @return A reference to this stat.
2491 AverageVector &init(size_t size) {
2492 bin.init(size, params);
2500 * A 2-Dimensional vecto of scalar stats.
2501 * @sa Stat, Vector2dBase, StatStor
2503 template <typename T = Counter, class Bin = DefaultBin>
2504 class Vector2d : public WrapVec2d<Vector2d<T, Bin>, Vector2dBase<T, StatStor, Bin>, Vector2dData>
2507 Vector2d &init(size_t _x, size_t _y) {
2508 statData()->x = x = _x;
2509 statData()->y = y = _y;
2510 bin.init(x * y, params);
2518 * A simple distribution stat.
2519 * @sa Stat, DistBase, DistStor
2521 template <typename T = Counter, class Bin = DefaultBin>
2522 class Distribution : public Wrap<Distribution<T, Bin>, DistBase<T, DistStor, Bin>, DistData>
2525 /** Base implementation. */
2526 typedef DistBase<T, DistStor, Bin> Base;
2527 /** The Parameter type. */
2528 typedef typename DistStor<T>::Params Params;
2532 * Set the parameters of this distribution. @sa DistStor::Params
2533 * @param min The minimum value of the distribution.
2534 * @param max The maximum value of the distribution.
2535 * @param bkt The number of values in each bucket.
2536 * @return A reference to this distribution.
2538 Distribution &init(T min, T max, int bkt) {
2541 params.bucket_size = bkt;
2542 params.size = (max - min) / bkt + 1;
2551 * Calculates the mean and variance of all the samples.
2552 * @sa Stat, DistBase, FancyStor
2554 template <typename T = Counter, class Bin = DefaultBin>
2555 class StandardDeviation : public Wrap<StandardDeviation<T, Bin>, DistBase<T, FancyStor, Bin>, DistData>
2558 /** The base implementation */
2559 typedef DistBase<T, DistStor, Bin> Base;
2560 /** The parameter type. */
2561 typedef typename DistStor<T>::Params Params;
2565 * Construct and initialize this distribution.
2567 StandardDeviation() {
2574 * Calculates the per cycle mean and variance of the samples.
2575 * @sa Stat, DistBase, AvgFancy
2577 template <typename T = Counter, class Bin = DefaultBin>
2578 class AverageDeviation : public Wrap<AverageDeviation<T, Bin>, DistBase<T, AvgFancy, Bin>, DistData>
2581 /** The base implementation */
2582 typedef DistBase<T, DistStor, Bin> Base;
2583 /** The parameter type. */
2584 typedef typename DistStor<T>::Params Params;
2588 * Construct and initialize this distribution.
2598 * A vector of distributions.
2599 * @sa Stat, VectorDistBase, DistStor
2601 template <typename T = Counter, class Bin = DefaultBin>
2602 class VectorDistribution : public WrapVec<VectorDistribution<T, Bin>, VectorDistBase<T, DistStor, Bin>, VectorDistData>
2605 /** The base implementation */
2606 typedef VectorDistBase<T, DistStor, Bin> Base;
2607 /** The parameter type. */
2608 typedef typename DistStor<T>::Params Params;
2612 * Initialize storage and parameters for this distribution.
2613 * @param size The size of the vector (the number of distributions).
2614 * @param min The minimum value of the distribution.
2615 * @param max The maximum value of the distribution.
2616 * @param bkt The number of values in each bucket.
2617 * @return A reference to this distribution.
2619 VectorDistribution &init(int size, T min, T max, int bkt) {
2622 params.bucket_size = bkt;
2623 params.size = (max - min) / bkt + 1;
2624 bin.init(size, params);
2632 * This is a vector of StandardDeviation stats.
2633 * @sa Stat, VectorDistBase, FancyStor
2635 template <typename T = Counter, class Bin = DefaultBin>
2636 class VectorStandardDeviation : public WrapVec<VectorStandardDeviation<T, Bin>, VectorDistBase<T, FancyStor, Bin>, VectorDistData>
2639 /** The base implementation */
2640 typedef VectorDistBase<T, FancyStor, Bin> Base;
2641 /** The parameter type. */
2642 typedef typename DistStor<T>::Params Params;
2646 * Initialize storage for this distribution.
2647 * @param size The size of the vector.
2648 * @return A reference to this distribution.
2650 VectorStandardDeviation &init(int size) {
2651 bin.init(size, params);
2659 * This is a vector of AverageDeviation stats.
2660 * @sa Stat, VectorDistBase, AvgFancy
2662 template <typename T = Counter, class Bin = DefaultBin>
2663 class VectorAverageDeviation : public WrapVec<VectorAverageDeviation<T, Bin>, VectorDistBase<T, AvgFancy, Bin>, VectorDistData>
2666 /** The base implementation */
2667 typedef VectorDistBase<T, AvgFancy, Bin> Base;
2668 /** The parameter type. */
2669 typedef typename DistStor<T>::Params Params;
2673 * Initialize storage for this distribution.
2674 * @param size The size of the vector.
2675 * @return A reference to this distribution.
2677 VectorAverageDeviation &init(int size) {
2678 bin.init(size, params);
2686 * A formula for statistics that is calculated when printed. A formula is
2687 * stored as a tree of Nodes that represent the equation to calculate.
2688 * @sa Stat, ScalarStat, VectorStat, Node, Temp
2690 class FormulaBase : public DataAccess
2693 /** The root of the tree which represents the Formula */
2699 * Return the result of the Fomula in a vector. If there were no Vector
2700 * components to the Formula, then the vector is size 1. If there were,
2701 * like x/y with x being a vector of size 3, then the result returned will
2702 * be x[0]/y, x[1]/y, x[2]/y, respectively.
2703 * @return The result vector.
2705 void val(rvec_t &vec) const;
2708 * Return the total Formula result. If there is a Vector
2709 * component to this Formula, then this is the result of the
2710 * Formula if the formula is applied after summing all the
2711 * components of the Vector. For example, if Formula is x/y where
2712 * x is size 3, then total() will return (x[1]+x[2]+x[3])/y. If
2713 * there is no Vector component, total() returns the same value as
2714 * the first entry in the rvec_t val() returns.
2715 * @return The total of the result vector.
2717 result_t total() const;
2720 * Return the number of elements in the tree.
2722 size_t size() const;
2725 * Return true if Formula is binned. i.e. any of its children
2727 * @return True if Formula is binned.
2729 bool binned() const;
2731 bool check() const { return true; }
2734 * Formulas don't need to be reset
2746 void update(StatData *);
2750 class Formula : public WrapVec<Formula, FormulaBase, VectorData>
2754 * Create and initialize thie formula, and register it with the database.
2759 * Create a formula with the given root node, register it with the
2761 * @param r The root of the expression tree.
2766 * Set an unitialized Formula to the given root.
2767 * @param r The root of the expression tree.
2768 * @return a reference to this formula.
2770 const Formula &operator=(Temp r);
2773 * Add the given tree to the existing one.
2774 * @param r The root of the expression tree.
2775 * @return a reference to this formula.
2777 const Formula &operator+=(Temp r);
2780 class FormulaNode : public Node
2783 const Formula &formula;
2787 FormulaNode(const Formula &f) : formula(f) {}
2789 virtual size_t size() const { return formula.size(); }
2790 virtual const rvec_t &val() const { formula.val(vec); return vec; }
2791 virtual result_t total() const { return formula.total(); }
2792 virtual bool binned() const { return formula.binned(); }
2796 * Helper class to construct formula node trees.
2802 * Pointer to a Node object.
2808 * Copy the given pointer to this class.
2809 * @param n A pointer to a Node object to copy.
2811 Temp(NodePtr n) : node(n) { }
2814 * Return the node pointer.
2815 * @return the node pointer.
2817 operator NodePtr() { return node;}
2821 * Create a new ScalarStatNode.
2822 * @param s The ScalarStat to place in a node.
2824 template <typename T, class Bin>
2825 Temp(const Scalar<T, Bin> &s)
2826 : node(new ScalarStatNode(s.statData())) { }
2829 * Create a new ScalarStatNode.
2830 * @param s The ScalarStat to place in a node.
2832 template <typename T, class Bin>
2833 Temp(const Average<T, Bin> &s)
2834 : node(new ScalarStatNode(s.statData())) { }
2837 * Create a new VectorStatNode.
2838 * @param s The VectorStat to place in a node.
2840 template <typename T, class Bin>
2841 Temp(const Vector<T, Bin> &s)
2842 : node(new VectorStatNode(s.statData())) { }
2847 Temp(const Formula &f)
2848 : node(new FormulaNode(f)) { }
2851 * Create a new ScalarProxyNode.
2852 * @param p The ScalarProxy to place in a node.
2854 template <typename T, template <typename T> class Storage, class Bin>
2855 Temp(const ScalarProxy<T, Storage, Bin> &p)
2856 : node(new ScalarProxyNode<T, Storage, Bin>(p)) { }
2859 * Create a ConstNode
2860 * @param value The value of the const node.
2862 Temp(signed char value)
2863 : node(new ConstNode<signed char>(value)) {}
2866 * Create a ConstNode
2867 * @param value The value of the const node.
2869 Temp(unsigned char value)
2870 : node(new ConstNode<unsigned char>(value)) {}
2873 * Create a ConstNode
2874 * @param value The value of the const node.
2876 Temp(signed short value)
2877 : node(new ConstNode<signed short>(value)) {}
2880 * Create a ConstNode
2881 * @param value The value of the const node.
2883 Temp(unsigned short value)
2884 : node(new ConstNode<unsigned short>(value)) {}
2887 * Create a ConstNode
2888 * @param value The value of the const node.
2890 Temp(signed int value)
2891 : node(new ConstNode<signed int>(value)) {}
2894 * Create a ConstNode
2895 * @param value The value of the const node.
2897 Temp(unsigned int value)
2898 : node(new ConstNode<unsigned int>(value)) {}
2901 * Create a ConstNode
2902 * @param value The value of the const node.
2904 Temp(signed long value)
2905 : node(new ConstNode<signed long>(value)) {}
2908 * Create a ConstNode
2909 * @param value The value of the const node.
2911 Temp(unsigned long value)
2912 : node(new ConstNode<unsigned long>(value)) {}
2915 * Create a ConstNode
2916 * @param value The value of the const node.
2918 Temp(signed long long value)
2919 : node(new ConstNode<signed long long>(value)) {}
2922 * Create a ConstNode
2923 * @param value The value of the const node.
2925 Temp(unsigned long long value)
2926 : node(new ConstNode<unsigned long long>(value)) {}
2929 * Create a ConstNode
2930 * @param value The value of the const node.
2933 : node(new ConstNode<float>(value)) {}
2936 * Create a ConstNode
2937 * @param value The value of the const node.
2940 : node(new ConstNode<double>(value)) {}
2949 void dump(std::ostream &stream, DisplayMode mode = DefaultMode);
2951 void registerResetCallback(Callback *cb);
2954 operator+(Temp l, Temp r)
2956 return NodePtr(new BinaryNode<std::plus<result_t> >(l, r));
2960 operator-(Temp l, Temp r)
2962 return NodePtr(new BinaryNode<std::minus<result_t> >(l, r));
2966 operator*(Temp l, Temp r)
2968 return NodePtr(new BinaryNode<std::multiplies<result_t> >(l, r));
2972 operator/(Temp l, Temp r)
2974 return NodePtr(new BinaryNode<std::divides<result_t> >(l, r));
2978 operator%(Temp l, Temp r)
2980 return NodePtr(new BinaryNode<std::modulus<result_t> >(l, r));
2986 return NodePtr(new UnaryNode<std::negate<result_t> >(l));
2989 template <typename T>
2993 return NodePtr(new ConstNode<T>(val));
2996 template <typename T>
3000 return NodePtr(new FunctorNode<T>(val));
3003 template <typename T>
3007 return NodePtr(new ScalarNode<T>(val));
3013 return NodePtr(new SumNode<std::plus<result_t> >(val));
3015 extern bool PrintDescriptions;
3017 } // namespace statistics
3019 #endif // __STATISTICS_HH__