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/refcnt.hh"
58 #include "base/str.hh"
59 #include "base/intmath.hh"
61 #include "sim/host.hh"
64 #include "base/trace.hh"
67 // Un-comment this to enable weirdo-stat debugging
74 /** Define Not a number. */
76 /** Need to define __nan() */
82 /** The current simulated cycle. */
85 /* A namespace for all of the Statistics */
86 namespace Statistics {
87 /** All results are doubles. */
88 typedef double result_t;
89 /** A vector to hold results. */
90 typedef std::vector<result_t> rvec_t;
93 * Define the storage for format flags.
94 * @todo Can probably shrink this.
96 typedef u_int32_t FormatFlags;
97 /** Nothing extra to print. */
98 const FormatFlags none = 0x0000;
99 /** Print the total. */
100 const FormatFlags total = 0x0001;
101 /** Print the percent of the total that this entry represents. */
102 const FormatFlags pdf = 0x0002;
103 /** Print the cumulative percentage of total upto this entry. */
104 const FormatFlags cdf = 0x0004;
105 /** Don't print if this is zero. */
106 const FormatFlags nozero = 0x0010;
107 /** Don't print if this is NAN */
108 const FormatFlags nonan = 0x0020;
109 /** Print the distribution. */
110 const FormatFlags dist = 0x0100;
111 /** Used for SS compatability. */
112 const FormatFlags __substat = 0x8000;
113 /** Mask of flags that can't be set directly */
114 const FormatFlags __reserved = __substat;
123 extern DisplayMode default_mode;
125 /* Contains the statistic implementation details */
126 //////////////////////////////////////////////////////////////////////
128 // Statistics Framework Base classes
130 //////////////////////////////////////////////////////////////////////
133 /** True if the stat has been initialized. */
135 /** True if the stat should be printed. */
137 /** The name of the stat. */
139 /** The description of the stat. */
141 /** The display precision. */
145 /** The formatting flags. */
149 /** A pointer to a prerequisite Stat. */
150 const StatData *prereq;
153 : init(false), print(false), precision(-1), mode(default_mode),
160 * @return true if the stat is binned.
162 virtual bool binned() const = 0;
165 * Print this stat to the given ostream.
166 * @param stream The stream to print to.
168 virtual void display(std::ostream &stream) const = 0;
169 bool dodisplay() const { return !prereq || !prereq->zero(); }
172 * Reset the corresponding stat to the default state.
174 virtual void reset() = 0;
177 * @return true if this stat has a value and satisfies its
178 * requirement as a prereq
180 virtual bool zero() const = 0;
183 * Check that this stat has been set up properly and is ready for
185 * @return true for success
187 virtual bool check() const = 0;
188 bool baseCheck() const;
191 * Checks if the first stat's name is alphabetically less than the second.
192 * This function breaks names up at periods and considers each subname
194 * @param stat1 The first stat.
195 * @param stat2 The second stat.
196 * @return stat1's name is alphabetically before stat2's
198 static bool less(StatData *stat1, StatData *stat2);
201 struct ScalarDataBase : public StatData
203 virtual result_t val() const = 0;
204 virtual result_t total() const = 0;
206 virtual void display(std::ostream &stream) const;
210 class ScalarData : public ScalarDataBase
216 ScalarData(T &stat) : s(stat) {}
218 virtual bool binned() const { return s.binned(); }
219 virtual bool check() const { return s.check(); }
220 virtual result_t val() const { return s.val(); }
221 virtual result_t total() const { return s.total(); }
222 virtual void reset() { s.reset(); }
223 virtual bool zero() const { return s.zero(); }
226 struct VectorDataBase : public StatData
228 /** Names and descriptions of subfields. */
229 mutable std::vector<std::string> subnames;
230 mutable std::vector<std::string> subdescs;
232 virtual void display(std::ostream &stream) const;
234 virtual size_t size() const = 0;
235 virtual const rvec_t &val() const = 0;
236 virtual result_t total() const = 0;
237 virtual void update()
240 if (subnames.size() < s)
243 if (subdescs.size() < s)
249 class VectorData : public VectorDataBase
256 VectorData(T &stat) : s(stat) {}
258 virtual bool binned() const { return s.binned(); }
259 virtual bool check() const { return s.check(); }
260 virtual bool zero() const { return s.zero(); }
261 virtual void reset() { s.reset(); }
263 virtual size_t size() const { return s.size(); }
264 virtual const rvec_t &val() const
269 virtual result_t total() const { return s.total(); }
270 virtual void update()
272 VectorDataBase::update();
296 struct DistDataBase : public StatData
298 /** Local storage for the entry values, used for printing. */
301 virtual void display(std::ostream &stream) const;
302 virtual void update() = 0;
306 class DistData : public DistDataBase
312 DistData(T &stat) : s(stat) {}
314 virtual bool binned() const { return s.binned(); }
315 virtual bool check() const { return s.check(); }
316 virtual void reset() { s.reset(); }
317 virtual bool zero() const { return s.zero(); }
318 virtual void update() { return s.update(this); }
321 struct VectorDistDataBase : public StatData
323 std::vector<DistDataData> data;
325 /** Names and descriptions of subfields. */
326 mutable std::vector<std::string> subnames;
327 mutable std::vector<std::string> subdescs;
329 /** Local storage for the entry values, used for printing. */
332 virtual size_t size() const = 0;
333 virtual void display(std::ostream &stream) const;
334 virtual void update()
337 if (subnames.size() < s)
340 if (subdescs.size() < s)
346 class VectorDistData : public VectorDistDataBase
352 VectorDistData(T &stat) : s(stat) {}
354 virtual bool binned() const { return T::bin_t::binned; }
355 virtual bool check() const { return s.check(); }
356 virtual void reset() { s.reset(); }
357 virtual size_t size() const { return s.size(); }
358 virtual bool zero() const { return s.zero(); }
359 virtual void update()
361 VectorDistDataBase::update();
362 return s.update(this);
366 struct Vector2dDataBase : public StatData
368 /** Names and descriptions of subfields. */
369 std::vector<std::string> subnames;
370 std::vector<std::string> subdescs;
371 std::vector<std::string> y_subnames;
373 /** Local storage for the entry values, used for printing. */
378 virtual void display(std::ostream &stream) const;
379 virtual void update()
381 if (subnames.size() < x)
387 class Vector2dData : public Vector2dDataBase
393 Vector2dData(T &stat) : s(stat) {}
395 virtual bool binned() const { return T::bin_t::binned; }
396 virtual bool check() const { return s.check(); }
397 virtual void reset() { s.reset(); }
398 virtual bool zero() const { return s.zero(); }
399 virtual void update()
401 Vector2dDataBase::update();
410 StatData *find() const;
411 void map(StatData *data);
413 StatData *statData();
414 const StatData *statData() const;
420 template <class Parent, class Child, template <class Child> class Data>
421 class Wrap : public Child
424 Parent &self() { return *reinterpret_cast<Parent *>(this); }
427 Data<Child> *statData()
429 StatData *__data = DataAccess::statData();
430 Data<Child> *ptr = dynamic_cast<Data<Child> *>(__data);
436 const Data<Child> *statData() const
438 const StatData *__data = DataAccess::statData();
439 const Data<Child> *ptr = dynamic_cast<const Data<Child> *>(__data);
447 map(new Data<Child>(*this));
451 * Set the name and marks this stat to print at the end of simulation.
452 * @param name The new name.
453 * @return A reference to this stat.
455 Parent &name(const std::string &_name)
457 Data<Child> *data = statData();
464 * Set the description and marks this stat to print at the end of
466 * @param desc The new description.
467 * @return A reference to this stat.
469 Parent &desc(const std::string &_desc)
471 statData()->desc = _desc;
476 * Set the precision and marks this stat to print at the end of simulation.
477 * @param p The new precision
478 * @return A reference to this stat.
480 Parent &precision(int _precision)
482 statData()->precision = _precision;
487 * Set the flags and marks this stat to print at the end of simulation.
488 * @param f The new flags.
489 * @return A reference to this stat.
491 Parent &flags(FormatFlags _flags)
493 statData()->flags |= _flags;
498 * Set the prerequisite stat and marks this stat to print at the end of
500 * @param prereq The prerequisite stat.
501 * @return A reference to this stat.
504 Parent &prereq(const T &prereq)
506 statData()->prereq = prereq.statData();
511 template <class Parent, class Child, template <class Child> class Data>
512 class WrapVec : public Wrap<Parent, Child, Data>
515 // The following functions are specific to vectors. If you use them
516 // in a non vector context, you will get a nice compiler error!
519 * Set the subfield name for the given index, and marks this stat to print
520 * at the end of simulation.
521 * @param index The subfield index.
522 * @param name The new name of the subfield.
523 * @return A reference to this stat.
525 Parent &subname(int index, const std::string &name)
527 std::vector<std::string> &subn = statData()->subnames;
528 if (subn.size() <= index)
529 subn.resize(index + 1);
535 * Set the subfield description for the given index and marks this stat to
536 * print at the end of simulation.
537 * @param index The subfield index.
538 * @param desc The new description of the subfield
539 * @return A reference to this stat.
541 Parent &subdesc(int index, const std::string &desc)
543 std::vector<std::string> &subd = statData()->subdescs;
544 if (subd.size() <= index)
545 subd.resize(index + 1);
553 template <class Parent, class Child, template <class Child> class Data>
554 class WrapVec2d : public WrapVec<Parent, Child, Data>
558 * @warning This makes the assumption that if you're gonna subnames a 2d
559 * vector, you're subnaming across all y
561 Parent &ysubnames(const char **names)
563 Data<Child> *data = statData();
564 data->y_subnames.resize(y);
565 for (int i = 0; i < y; ++i)
566 data->y_subnames[i] = names[i];
569 Parent &ysubname(int index, const std::string subname)
571 Data<Child> *data = statData();
573 data->y_subnames.resize(y);
574 data->y_subnames[i] = subname.c_str();
579 //////////////////////////////////////////////////////////////////////
583 //////////////////////////////////////////////////////////////////////
586 * Templatized storage and interface for a simple scalar stat.
588 template <typename T>
592 /** The paramaters for this storage type, none for a scalar. */
596 /** The statistic value. */
606 * Builds this storage element and calls the base constructor of the
609 StatStor(const Params &) : data(Null()) {}
612 * The the stat to the given value.
613 * @param val The new value.
614 * @param p The paramters of this storage type.
616 void set(T val, const Params &p) { data = val; }
618 * Increment the stat by the given value.
619 * @param val The new value.
620 * @param p The paramters of this storage type.
622 void inc(T val, const Params &p) { data += val; }
624 * Decrement the stat by the given value.
625 * @param val The new value.
626 * @param p The paramters of this storage type.
628 void dec(T val, const Params &p) { data -= val; }
630 * Return the value of this stat as a result type.
631 * @param p The parameters of this storage type.
632 * @return The value of this stat.
634 result_t val(const Params &p) const { return (result_t)data; }
636 * Return the value of this stat as its base type.
637 * @param p The params of this storage type.
638 * @return The value of this stat.
640 T value(const Params &p) const { return data; }
642 * Reset stat value to default
644 void reset() { data = Null(); }
647 * @return true if zero value
649 bool zero() const { return data == Null(); }
653 * Templatized storage and interface to a per-cycle average stat. This keeps
654 * a current count and updates a total (count * cycles) when this count
655 * changes. This allows the quick calculation of a per cycle count of the item
656 * being watched. This is good for keeping track of residencies in structures
657 * among other things.
658 * @todo add lateny to the stat and fix binning.
660 template <typename T>
664 /** The paramaters for this storage type */
668 * The current count. We stash this here because the current
669 * value is not a binned value.
675 /** The total count for all cycles. */
676 mutable result_t total;
677 /** The cycle that current last changed. */
682 * Build and initializes this stat storage.
684 AvgStor(Params &p) : total(0), last(0) { p.current = T(); }
687 * Set the current count to the one provided, update the total and last
689 * @param val The new count.
690 * @param p The parameters for this storage.
692 void set(T val, Params &p) {
693 total += p.current * (curTick - last);
699 * Increment the current count by the provided value, calls set.
700 * @param val The amount to increment.
701 * @param p The parameters for this storage.
703 void inc(T val, Params &p) { set(p.current + val, p); }
706 * Deccrement the current count by the provided value, calls set.
707 * @param val The amount to decrement.
708 * @param p The parameters for this storage.
710 void dec(T val, Params &p) { set(p.current - val, p); }
713 * Return the current average.
714 * @param p The parameters for this storage.
715 * @return The current average.
717 result_t val(const Params &p) const {
718 total += p.current * (curTick - last);
720 return (result_t)(total + p.current) / (result_t)(curTick + 1);
724 * Return the current count.
725 * @param p The parameters for this storage.
726 * @return The current count.
728 T value(const Params &p) const { return p.current; }
731 * Reset stat value to default
740 * @return true if zero value
742 bool zero() const { return total == 0.0; }
746 * Implementation of a scalar stat. The type of stat is determined by the
747 * Storage template. The storage for this stat is held within the Bin class.
748 * This allows for breaking down statistics across multiple bins easily.
750 template <typename T, template <typename T> class Storage, class Bin>
751 class ScalarBase : public DataAccess
754 /** Define the type of the storage class. */
755 typedef Storage<T> storage_t;
756 /** Define the params of the storage class. */
757 typedef typename storage_t::Params params_t;
758 /** Define the bin type. */
759 typedef typename Bin::Bin<storage_t> bin_t;
762 /** The bin of this stat. */
764 /** The parameters for this stat. */
769 * Retrieve the storage from the bin.
770 * @return The storage object for this stat.
772 storage_t *data() { return bin.data(params); }
774 * Retrieve a const pointer to the storage from the bin.
775 * @return A const pointer to the storage object for this stat.
777 const storage_t *data() const
779 bin_t *_bin = const_cast<bin_t *>(&bin);
780 params_t *_params = const_cast<params_t *>(¶ms);
781 return _bin->data(*_params);
786 * Copy constructor, copies are not allowed.
788 ScalarBase(const ScalarBase &stat);
792 const ScalarBase &operator=(const ScalarBase &);
796 * Return the current value of this stat as its base type.
797 * @return The current value.
799 T value() const { return data()->value(params); }
803 * Create and initialize this stat, register it with the database.
811 // Common operators for stats
813 * Increment the stat by 1. This calls the associated storage object inc
816 void operator++() { data()->inc(1, params); }
818 * Decrement the stat by 1. This calls the associated storage object dec
821 void operator--() { data()->dec(1, params); }
823 /** Increment the stat by 1. */
824 void operator++(int) { ++*this; }
825 /** Decrement the stat by 1. */
826 void operator--(int) { --*this; }
829 * Set the data value to the given value. This calls the associated storage
830 * object set function.
831 * @param v The new value.
833 template <typename U>
834 void operator=(const U& v) { data()->set(v, params); }
837 * Increment the stat by the given value. This calls the associated
838 * storage object inc function.
839 * @param v The value to add.
841 template <typename U>
842 void operator+=(const U& v) { data()->inc(v, params); }
845 * Decrement the stat by the given value. This calls the associated
846 * storage object dec function.
847 * @param v The value to substract.
849 template <typename U>
850 void operator-=(const U& v) { data()->dec(v, params); }
853 * Return the number of elements, always 1 for a scalar.
856 size_t size() const { return 1; }
858 * Return true if stat is binned.
859 *@return True is stat is binned.
861 bool binned() const { return bin_t::binned; }
863 bool check() const { return bin.initialized(); }
866 * Reset stat value to default
868 void reset() { bin.reset(); }
870 result_t val() { return data()->val(params); }
872 result_t total() { return val(); }
874 bool zero() { return val() == 0.0; }
877 //////////////////////////////////////////////////////////////////////
881 //////////////////////////////////////////////////////////////////////
882 template <typename T, template <typename T> class Storage, class Bin>
886 * Implementation of a vector of stats. The type of stat is determined by the
887 * Storage class. @sa ScalarBase
889 template <typename T, template <typename T> class Storage, class Bin>
890 class VectorBase : public DataAccess
893 /** Define the type of the storage class. */
894 typedef Storage<T> storage_t;
895 /** Define the params of the storage class. */
896 typedef typename storage_t::Params params_t;
897 /** Define the bin type. */
898 typedef typename Bin::VectorBin<storage_t> bin_t;
901 /** The bin of this stat. */
903 /** The parameters for this stat. */
908 * Retrieve the storage from the bin for the given index.
909 * @param index The vector index to access.
910 * @return The storage object at the given index.
912 storage_t *data(int index) { return bin.data(index, params); }
914 * Retrieve a const pointer to the storage from the bin
915 * for the given index.
916 * @param index The vector index to access.
917 * @return A const pointer to the storage object at the given index.
919 const storage_t *data(int index) const
921 bin_t *_bin = const_cast<bin_t *>(&bin);
922 params_t *_params = const_cast<params_t *>(¶ms);
923 return _bin->data(index, *_params);
927 // Copying stats is not allowed
928 /** Copying stats isn't allowed. */
929 VectorBase(const VectorBase &stat);
930 /** Copying stats isn't allowed. */
931 const VectorBase &operator=(const VectorBase &);
935 * Copy the values to a local vector and return a reference to it.
936 * @return A reference to a vector of the stat values.
938 void val(rvec_t &vec) const
941 for (int i = 0; i < size(); ++i)
942 vec[i] = data(i)->val(params);
946 * @return True is stat is binned.
948 bool binned() const { return bin_t::binned; }
951 * Return a total of all entries in this vector.
952 * @return The total of all vector entries.
954 result_t total() const {
955 result_t total = 0.0;
956 for (int i = 0; i < size(); ++i)
957 total += data(i)->val(params);
962 * @return the number of elements in this vector.
964 size_t size() const { return bin.size(); }
968 for (int i = 0; i < size(); ++i)
974 bool check() const { return bin.initialized(); }
975 void reset() { bin.reset(); }
980 /** Friend this class with the associated scalar proxy. */
981 friend class ScalarProxy<T, Storage, Bin>;
984 * Return a reference (ScalarProxy) to the stat at the given index.
985 * @param index The vector index to access.
986 * @return A reference of the stat.
988 ScalarProxy<T, Storage, Bin> operator[](int index);
990 void update(StatData *data) {}
994 * A proxy class to access the stat at a given index in a VectorBase stat.
995 * Behaves like a ScalarBase.
997 template <typename T, template <typename T> class Storage, class Bin>
1001 /** Define the type of the storage class. */
1002 typedef Storage<T> storage_t;
1003 /** Define the params of the storage class. */
1004 typedef typename storage_t::Params params_t;
1005 /** Define the bin type. */
1006 typedef typename Bin::VectorBin<storage_t> bin_t;
1009 /** Pointer to the bin in the parent VectorBase. */
1011 /** Pointer to the params in the parent VectorBase. */
1013 /** The index to access in the parent VectorBase. */
1018 * Retrieve the storage from the bin.
1019 * @return The storage from the bin for this stat.
1021 storage_t *data() { return bin->data(index, *params); }
1023 * Retrieve a const pointer to the storage from the bin.
1024 * @return A const pointer to the storage for this stat.
1026 const storage_t *data() const
1028 bin_t *_bin = const_cast<bin_t *>(bin);
1029 params_t *_params = const_cast<params_t *>(params);
1030 return _bin->data(index, *_params);
1035 * Return the current value of this statas a result type.
1036 * @return The current value.
1038 result_t val() const { return data()->val(*params); }
1040 * Return the current value of this stat as its base type.
1041 * @return The current value.
1043 T value() const { return data()->value(*params); }
1047 * Create and initialize this proxy, do not register it with the database.
1048 * @param b The bin to use.
1049 * @param p The params to use.
1050 * @param i The index to access.
1052 ScalarProxy(bin_t &b, params_t &p, int i)
1053 : bin(&b), params(&p), index(i) {}
1055 * Create a copy of the provided ScalarProxy.
1056 * @param sp The proxy to copy.
1058 ScalarProxy(const ScalarProxy &sp)
1059 : bin(sp.bin), params(sp.params), index(sp.index) {}
1061 * Set this proxy equal to the provided one.
1062 * @param sp The proxy to copy.
1063 * @return A reference to this proxy.
1065 const ScalarProxy &operator=(const ScalarProxy &sp) {
1073 // Common operators for stats
1075 * Increment the stat by 1. This calls the associated storage object inc
1078 void operator++() { data()->inc(1, *params); }
1080 * Decrement the stat by 1. This calls the associated storage object dec
1083 void operator--() { data()->dec(1, *params); }
1085 /** Increment the stat by 1. */
1086 void operator++(int) { ++*this; }
1087 /** Decrement the stat by 1. */
1088 void operator--(int) { --*this; }
1091 * Set the data value to the given value. This calls the associated storage
1092 * object set function.
1093 * @param v The new value.
1095 template <typename U>
1096 void operator=(const U& v) { data()->set(v, *params); }
1099 * Increment the stat by the given value. This calls the associated
1100 * storage object inc function.
1101 * @param v The value to add.
1103 template <typename U>
1104 void operator+=(const U& v) { data()->inc(v, *params); }
1107 * Decrement the stat by the given value. This calls the associated
1108 * storage object dec function.
1109 * @param v The value to substract.
1111 template <typename U>
1112 void operator-=(const U& v) { data()->dec(v, *params); }
1115 * Return the number of elements, always 1 for a scalar.
1118 size_t size() const { return 1; }
1121 * Return true if stat is binned.
1122 *@return false since Proxies aren't printed/binned
1124 bool binned() const { return false; }
1127 * This stat has no state. Nothing to reset
1132 template <typename T, template <typename T> class Storage, class Bin>
1133 inline ScalarProxy<T, Storage, Bin>
1134 VectorBase<T, Storage, Bin>::operator[](int index)
1136 assert (index >= 0 && index < size());
1137 return ScalarProxy<T, Storage, Bin>(bin, params, index);
1140 template <typename T, template <typename T> class Storage, class Bin>
1143 template <typename T, template <typename T> class Storage, class Bin>
1144 class Vector2dBase : public DataAccess
1147 typedef Storage<T> storage_t;
1148 typedef typename storage_t::Params params_t;
1151 typedef typename Bin::VectorBin<storage_t> bin_t;
1160 storage_t *data(int index) { return bin.data(index, params); }
1161 const storage_t *data(int index) const
1163 bin_t *_bin = const_cast<bin_t *>(&bin);
1164 params_t *_params = const_cast<params_t *>(¶ms);
1165 return _bin->data(index, *_params);
1169 // Copying stats is not allowed
1170 Vector2dBase(const Vector2dBase &stat);
1171 const Vector2dBase &operator=(const Vector2dBase &);
1176 void update(Vector2dDataBase *data)
1178 int size = this->size();
1179 data->vec.resize(size);
1180 for (int i = 0; i < size; ++i)
1181 data->vec[i] = this->data(i)->val(params);
1184 std::string ysubname(int i) const { return (*y_subnames)[i]; }
1186 friend class VectorProxy<T, Storage, Bin>;
1187 VectorProxy<T, Storage, Bin> operator[](int index);
1189 size_t size() const { return bin.size(); }
1190 bool zero() const { return data(0)->value(params) == 0.0; }
1193 * Reset stat value to default
1195 void reset() { bin.reset(); }
1197 bool check() { return bin.initialized(); }
1200 template <typename T, template <typename T> class Storage, class Bin>
1204 typedef Storage<T> storage_t;
1205 typedef typename storage_t::Params params_t;
1206 typedef typename Bin::VectorBin<storage_t> bin_t;
1215 mutable rvec_t *vec;
1217 storage_t *data(int index) {
1218 assert(index < len);
1219 return bin->data(offset + index, *params);
1222 const storage_t *data(int index) const {
1223 bin_t *_bin = const_cast<bin_t *>(bin);
1224 params_t *_params = const_cast<params_t *>(params);
1225 return _bin->data(offset + index, *_params);
1229 const rvec_t &val() const {
1231 vec->resize(size());
1233 vec = new rvec_t(size());
1235 for (int i = 0; i < size(); ++i)
1236 (*vec)[i] = data(i)->val(*params);
1241 result_t total() const {
1242 result_t total = 0.0;
1243 for (int i = 0; i < size(); ++i)
1244 total += data(i)->val(*params);
1249 VectorProxy(bin_t &b, params_t &p, int o, int l)
1250 : bin(&b), params(&p), offset(o), len(l), vec(NULL)
1252 VectorProxy(const VectorProxy &sp)
1253 : bin(sp.bin), params(sp.params), offset(sp.offset), len(sp.len),
1261 const VectorProxy &operator=(const VectorProxy &sp)
1273 ScalarProxy<T, Storage, Bin> operator[](int index)
1275 assert (index >= 0 && index < size());
1276 return ScalarProxy<T, Storage, Bin>(*bin, *params, offset + index);
1279 size_t size() const { return len; }
1282 * Return true if stat is binned.
1283 *@return false since Proxies aren't printed/binned
1285 bool binned() const { return false; }
1288 * This stat has no state. Nothing to reset.
1293 template <typename T, template <typename T> class Storage, class Bin>
1294 inline VectorProxy<T, Storage, Bin>
1295 Vector2dBase<T, Storage, Bin>::operator[](int index)
1297 int offset = index * y;
1298 assert (index >= 0 && offset < size());
1299 return VectorProxy<T, Storage, Bin>(bin, params, offset, y);
1302 //////////////////////////////////////////////////////////////////////
1304 // Non formula statistics
1306 //////////////////////////////////////////////////////////////////////
1309 * Templatized storage and interface for a distrbution stat.
1311 template <typename T>
1315 /** The parameters for a distribution stat. */
1318 /** The minimum value to track. */
1320 /** The maximum value to track. */
1322 /** The number of entries in each bucket. */
1324 /** The number of buckets. Equal to (max-min)/bucket_size. */
1327 enum { fancy = false };
1330 /** The smallest value sampled. */
1332 /** The largest value sampled. */
1334 /** The number of values sampled less than min. */
1336 /** The number of values sampled more than max. */
1338 /** The current sum. */
1340 /** The sum of squares. */
1342 /** The number of samples. */
1344 /** Counter for each bucket. */
1349 * Construct this storage with the supplied params.
1350 * @param params The parameters.
1352 DistStor(const Params ¶ms)
1353 : min_val(INT_MAX), max_val(INT_MIN), underflow(0), overflow(0),
1354 sum(T()), squares(T()), samples(0), vec(params.size)
1360 * Add a value to the distribution for the given number of times.
1361 * @param val The value to add.
1362 * @param number The number of times to add the value.
1363 * @param params The paramters of the distribution.
1365 void sample(T val, int number, const Params ¶ms)
1367 if (val < params.min)
1368 underflow += number;
1369 else if (val > params.max)
1372 int index = (val - params.min) / params.bucket_size;
1373 assert(index < size(params));
1374 vec[index] += number;
1383 T sample = val * number;
1385 squares += sample * sample;
1390 * Return the number of buckets in this distribution.
1391 * @return the number of buckets.
1392 * @todo Is it faster to return the size from the parameters?
1394 size_t size(const Params &) const { return vec.size(); }
1397 * Returns true if any calls to sample have been made.
1398 * @param params The paramters of the distribution.
1399 * @return True if any values have been sampled.
1401 bool zero(const Params ¶ms) const
1403 return samples == 0;
1406 void update(DistDataData *data, DisplayMode mode, const Params ¶ms)
1408 data->min = params.min;
1409 data->max = params.max;
1410 data->bucket_size = params.bucket_size;
1411 data->size = params.size;
1413 if (mode == mode_m5)
1414 data->min_val = (min_val == INT_MAX) ? params.min : min_val;
1416 data->min_val = params.min;
1418 data->max_val = (max_val == INT_MIN) ? 0 : max_val;
1419 data->underflow = underflow;
1420 data->overflow = overflow;
1421 data->vec.resize(params.size);
1422 for (int i = 0; i < params.size; ++i)
1423 data->vec[i] = vec[i];
1426 data->squares = squares;
1427 data->samples = samples;
1431 * Reset stat value to default
1440 int size = vec.size();
1441 for (int i = 0; i < size; ++i)
1451 * Templatized storage and interface for a distribution that calculates mean
1454 template <typename T>
1459 * No paramters for this storage.
1462 enum { fancy = true };
1465 /** The current sum. */
1467 /** The sum of squares. */
1469 /** The number of samples. */
1474 * Create and initialize this storage.
1476 FancyStor(const Params &) : sum(T()), squares(T()), samples(0) {}
1479 * Add a value the given number of times to this running average.
1480 * Update the running sum and sum of squares, increment the number of
1481 * values seen by the given number.
1482 * @param val The value to add.
1483 * @param number The number of times to add the value.
1484 * @param p The parameters of this stat.
1486 void sample(T val, int number, const Params &p)
1488 T value = val * number;
1490 squares += value * value;
1494 void update(DistDataData *data, DisplayMode mode, const Params ¶ms)
1497 data->squares = squares;
1498 data->samples = samples;
1502 * Return the number of entries in this stat, 1
1505 size_t size(const Params &) const { return 1; }
1508 * Return true if no samples have been added.
1509 * @return True if no samples have been added.
1511 bool zero(const Params &) const { return samples == 0; }
1514 * Reset stat value to default
1525 * Templatized storage for distribution that calculates per cycle mean and
1528 template <typename T>
1532 /** No parameters for this storage. */
1534 enum { fancy = true };
1537 /** Current total. */
1539 /** Current sum of squares. */
1544 * Create and initialize this storage.
1546 AvgFancy(const Params &) : sum(T()), squares(T()) {}
1549 * Add a value to the distribution for the given number of times.
1550 * Update the running sum and sum of squares.
1551 * @param val The value to add.
1552 * @param number The number of times to add the value.
1553 * @param p The paramters of the distribution.
1555 void sample(T val, int number, const Params& p)
1557 T value = val * number;
1559 squares += value * value;
1562 void update(DistDataData *data, DisplayMode mode, const Params ¶ms)
1565 data->squares = squares;
1566 data->samples = curTick;
1570 * Return the number of entries, in this case 1.
1573 size_t size(const Params ¶ms) const { return 1; }
1575 * Return true if no samples have been added.
1576 * @return True if the sum is zero.
1578 bool zero(const Params ¶ms) const { return sum == 0; }
1580 * Reset stat value to default
1590 * Implementation of a distribution stat. The type of distribution is
1591 * determined by the Storage template. @sa ScalarBase
1593 template <typename T, template <typename T> class Storage, class Bin>
1594 class DistBase : public DataAccess
1597 /** Define the type of the storage class. */
1598 typedef Storage<T> storage_t;
1599 /** Define the params of the storage class. */
1600 typedef typename storage_t::Params params_t;
1601 /** Define the bin type. */
1602 typedef typename Bin::Bin<storage_t> bin_t;
1605 /** The bin of this stat. */
1607 /** The parameters for this stat. */
1612 * Retrieve the storage from the bin.
1613 * @return The storage object for this stat.
1615 storage_t *data() { return bin.data(params); }
1617 * Retrieve a const pointer to the storage from the bin.
1618 * @return A const pointer to the storage object for this stat.
1620 const storage_t *data() const
1622 bin_t *_bin = const_cast<bin_t *>(&bin);
1623 params_t *_params = const_cast<params_t *>(¶ms);
1624 return _bin->data(*_params);
1628 // Copying stats is not allowed
1629 /** Copies are not allowed. */
1630 DistBase(const DistBase &stat);
1631 /** Copies are not allowed. */
1632 const DistBase &operator=(const DistBase &);
1638 * Add a value to the distribtion n times. Calls sample on the storage
1640 * @param v The value to add.
1641 * @param n The number of times to add it, defaults to 1.
1643 template <typename U>
1644 void sample(const U& v, int n = 1) { data()->sample(v, n, params); }
1647 * Return the number of entries in this stat.
1648 * @return The number of entries.
1650 size_t size() const { return data()->size(params); }
1652 * Return true if no samples have been added.
1653 * @return True if there haven't been any samples.
1655 bool zero() const { return data()->zero(params); }
1657 void update(DistDataBase *base)
1659 base->data.fancy = storage_t::fancy;
1660 data()->update(&(base->data), base->mode, params);
1663 * @return True is stat is binned.
1665 bool binned() const { return bin_t::binned; }
1667 * Reset stat value to default
1674 bool check() { return bin.initialized(); }
1677 template <typename T, template <typename T> class Storage, class Bin>
1680 template <typename T, template <typename T> class Storage, class Bin>
1681 class VectorDistBase : public DataAccess
1684 typedef Storage<T> storage_t;
1685 typedef typename storage_t::Params params_t;
1688 typedef typename Bin::VectorBin<storage_t> bin_t;
1695 storage_t *data(int index) { return bin.data(index, params); }
1696 const storage_t *data(int index) const
1698 bin_t *_bin = const_cast<bin_t *>(&bin);
1699 params_t *_params = const_cast<params_t *>(¶ms);
1700 return _bin->data(index, *_params);
1704 // Copying stats is not allowed
1705 VectorDistBase(const VectorDistBase &stat);
1706 const VectorDistBase &operator=(const VectorDistBase &);
1711 friend class DistProxy<T, Storage, Bin>;
1712 DistProxy<T, Storage, Bin> operator[](int index);
1713 const DistProxy<T, Storage, Bin> operator[](int index) const;
1715 size_t size() const { return bin.size(); }
1716 bool zero() const { return false; }
1718 * Return true if stat is binned.
1719 *@return True is stat is binned.
1721 bool binned() const { return bin_t::binned; }
1723 * Reset stat value to default
1725 void reset() { bin.reset(); }
1727 bool check() { return bin.initialized(); }
1728 void update(VectorDistDataBase *base)
1730 int size = this->size();
1731 base->data.resize(size);
1732 for (int i = 0; i < size; ++i) {
1733 base->data[i].fancy = storage_t::fancy;
1734 data(i)->update(&(base->data[i]), base->mode, params);
1739 template <typename T, template <typename T> class Storage, class Bin>
1743 typedef Storage<T> storage_t;
1744 typedef typename storage_t::Params params_t;
1745 typedef typename Bin::Bin<storage_t> bin_t;
1746 typedef VectorDistBase<T, Storage, Bin> base_t;
1751 const base_t *cstat;
1756 storage_t *data() { return stat->data(index); }
1757 const storage_t *data() const { return cstat->data(index); }
1760 DistProxy(const VectorDistBase<T, Storage, Bin> &s, int i)
1761 : cstat(&s), index(i) {}
1762 DistProxy(const DistProxy &sp)
1763 : cstat(sp.cstat), index(sp.index) {}
1764 const DistProxy &operator=(const DistProxy &sp) {
1765 cstat = sp.cstat; index = sp.index; return *this;
1769 template <typename U>
1770 void sample(const U& v, int n = 1) { data()->sample(v, n, cstat->params); }
1772 size_t size() const { return 1; }
1773 bool zero() const { return data()->zero(cstat->params); }
1775 * Return true if stat is binned.
1776 *@return false since Proxies are not binned/printed.
1778 bool binned() const { return false; }
1780 * Proxy has no state. Nothing to reset.
1785 template <typename T, template <typename T> class Storage, class Bin>
1786 inline DistProxy<T, Storage, Bin>
1787 VectorDistBase<T, Storage, Bin>::operator[](int index)
1789 assert (index >= 0 && index < size());
1790 return DistProxy<T, Storage, Bin>(*this, index);
1793 template <typename T, template <typename T> class Storage, class Bin>
1794 inline const DistProxy<T, Storage, Bin>
1795 VectorDistBase<T, Storage, Bin>::operator[](int index) const
1797 assert (index >= 0 && index < size());
1798 return DistProxy<T, Storage, Bin>(*this, index);
1802 template <typename T, template <typename T> class Storage, class Bin>
1804 VectorDistBase<T, Storage, Bin>::total(int index) const
1807 for (int i=0; i < x_size(); ++i) {
1808 total += data(i)->val(*params);
1813 //////////////////////////////////////////////////////////////////////
1817 //////////////////////////////////////////////////////////////////////
1820 * Base class for formula statistic node. These nodes are used to build a tree
1821 * that represents the formula.
1823 class Node : public RefCounted
1827 * Return the number of nodes in the subtree starting at this node.
1828 * @return the number of nodes in this subtree.
1830 virtual size_t size() const = 0;
1832 * Return the result vector of this subtree.
1833 * @return The result vector of this subtree.
1835 virtual const rvec_t &val() const = 0;
1837 * Return the total of the result vector.
1838 * @return The total of the result vector.
1840 virtual result_t total() const = 0;
1842 * Return true if stat is binned.
1843 *@return True is stat is binned.
1845 virtual bool binned() const = 0;
1848 /** Reference counting pointer to a function Node. */
1849 typedef RefCountingPtr<Node> NodePtr;
1851 class ScalarStatNode : public Node
1854 const ScalarDataBase *data;
1855 mutable rvec_t result;
1858 ScalarStatNode(const ScalarDataBase *d) : data(d), result(1) {}
1859 virtual const rvec_t &val() const
1861 result[0] = data->val();
1864 virtual result_t total() const { return data->val(); };
1866 virtual size_t size() const { return 1; }
1868 * Return true if stat is binned.
1869 *@return True is stat is binned.
1871 virtual bool binned() const { return data->binned(); }
1874 template <typename T, template <typename T> class Storage, class Bin>
1875 class ScalarProxyNode : public Node
1878 const ScalarProxy<T, Storage, Bin> proxy;
1879 mutable rvec_t result;
1882 ScalarProxyNode(const ScalarProxy<T, Storage, Bin> &p)
1883 : proxy(p), result(1) { }
1884 virtual const rvec_t &val() const
1886 result[0] = proxy.val();
1889 virtual result_t total() const { return proxy.val(); };
1891 virtual size_t size() const { return 1; }
1893 * Return true if stat is binned.
1894 *@return True is stat is binned.
1896 virtual bool binned() const { return proxy.binned(); }
1899 class VectorStatNode : public Node
1902 const VectorDataBase *data;
1905 VectorStatNode(const VectorDataBase *d) : data(d) { }
1906 virtual const rvec_t &val() const { return data->val(); }
1907 virtual result_t total() const { return data->total(); };
1909 virtual size_t size() const { return data->size(); }
1911 * Return true if stat is binned.
1912 *@return True is stat is binned.
1914 virtual bool binned() const { return data->binned(); }
1917 template <typename T>
1918 class ConstNode : public Node
1924 ConstNode(T s) : data(1, (result_t)s) {}
1925 const rvec_t &val() const { return data; }
1926 virtual result_t total() const { return data[0]; };
1928 virtual size_t size() const { return 1; }
1930 * Return true if stat is binned.
1931 *@return False since constants aren't binned.
1933 virtual bool binned() const { return false; }
1936 template <typename T>
1937 class FunctorNode : public Node
1941 mutable rvec_t result;
1944 FunctorNode(T &f) : functor(f) { result.resize(1); }
1945 const rvec_t &val() const {
1946 result[0] = (result_t)functor();
1949 virtual result_t total() const { return (result_t)functor(); };
1951 virtual size_t size() const { return 1; }
1953 * Return true if stat is binned.
1954 *@return False since Functors aren't binned
1956 virtual bool binned() const { return false; }
1959 template <typename T>
1960 class ScalarNode : public Node
1964 mutable rvec_t result;
1967 ScalarNode(T &s) : scalar(s) { result.resize(1); }
1968 const rvec_t &val() const {
1969 result[0] = (result_t)scalar;
1972 virtual result_t total() const { return (result_t)scalar; };
1974 virtual size_t size() const { return 1; }
1976 * Return true if stat is binned.
1977 *@return False since Scalar's aren't binned
1979 virtual bool binned() const { return false; }
1983 class UnaryNode : public Node
1987 mutable rvec_t result;
1990 UnaryNode(NodePtr p) : l(p) {}
1992 const rvec_t &val() const {
1993 const rvec_t &lvec = l->val();
1994 int size = lvec.size();
1998 result.resize(size);
2000 for (int i = 0; i < size; ++i)
2001 result[i] = op(lvec[i]);
2006 result_t total() const {
2008 return op(l->total());
2011 virtual size_t size() const { return l->size(); }
2013 * Return true if child of node is binned.
2014 *@return True if child of node is binned.
2016 virtual bool binned() const { return l->binned(); }
2020 class BinaryNode : public Node
2025 mutable rvec_t result;
2028 BinaryNode(NodePtr a, NodePtr b) : l(a), r(b) {}
2030 const rvec_t &val() const {
2032 const rvec_t &lvec = l->val();
2033 const rvec_t &rvec = r->val();
2035 assert(lvec.size() > 0 && rvec.size() > 0);
2037 if (lvec.size() == 1 && rvec.size() == 1) {
2039 result[0] = op(lvec[0], rvec[0]);
2040 } else if (lvec.size() == 1) {
2041 int size = rvec.size();
2042 result.resize(size);
2043 for (int i = 0; i < size; ++i)
2044 result[i] = op(lvec[0], rvec[i]);
2045 } else if (rvec.size() == 1) {
2046 int size = lvec.size();
2047 result.resize(size);
2048 for (int i = 0; i < size; ++i)
2049 result[i] = op(lvec[i], rvec[0]);
2050 } else if (rvec.size() == lvec.size()) {
2051 int size = rvec.size();
2052 result.resize(size);
2053 for (int i = 0; i < size; ++i)
2054 result[i] = op(lvec[i], rvec[i]);
2060 result_t total() const {
2062 return op(l->total(), r->total());
2065 virtual size_t size() const {
2073 assert(ls == rs && "Node vector sizes are not equal");
2078 * Return true if any children of node are binned
2079 *@return True if either child of node is binned.
2081 virtual bool binned() const { return (l->binned() || r->binned()); }
2085 class SumNode : public Node
2089 mutable rvec_t result;
2092 SumNode(NodePtr p) : l(p), result(1) {}
2094 const rvec_t &val() const {
2095 const rvec_t &lvec = l->val();
2096 int size = lvec.size();
2102 for (int i = 0; i < size; ++i)
2103 result[0] = op(result[0], lvec[i]);
2108 result_t total() const {
2109 const rvec_t &lvec = l->val();
2110 int size = lvec.size();
2113 result_t result = 0.0;
2116 for (int i = 0; i < size; ++i)
2117 result = op(result, lvec[i]);
2122 virtual size_t size() const { return 1; }
2124 * Return true if child of node is binned.
2125 *@return True if child of node is binned.
2127 virtual bool binned() const { return l->binned(); }
2130 //////////////////////////////////////////////////////////////////////
2132 // Binning Interface
2134 //////////////////////////////////////////////////////////////////////
2143 off_t size() const { return memsize; }
2144 char *memory(off_t off);
2147 static MainBin *&curBin()
2149 static MainBin *current = NULL;
2153 static void setCurBin(MainBin *bin) { curBin() = bin; }
2154 static MainBin *current() { assert(curBin()); return curBin(); }
2156 static off_t &offset()
2158 static off_t offset = 0;
2162 static off_t new_offset(size_t size)
2164 size_t mask = sizeof(u_int64_t) - 1;
2165 off_t off = offset();
2167 // That one is for the last trailing flags byte.
2168 offset() += (size + 1 + mask) & ~mask;
2173 MainBin(const std::string &name);
2187 DPRINTF(TCPIP, "activating %s Bin\n", name());
2197 BinBase() : offset(-1) {}
2198 void allocate(size_t size)
2200 offset = new_offset(size);
2204 assert(offset != -1);
2205 return current()->memory(offset);
2209 template <class Storage>
2210 class Bin : public BinBase
2213 typedef typename Storage::Params Params;
2216 enum { binned = true };
2217 Bin() { allocate(sizeof(Storage)); }
2218 bool initialized() const { return true; }
2219 void init(Params ¶ms) { }
2221 int size() const { return 1; }
2224 data(Params ¶ms)
2226 assert(initialized());
2227 char *ptr = access();
2228 char *flags = ptr + sizeof(Storage);
2229 if (!(*flags & 0x1)) {
2231 new (ptr) Storage(params);
2233 return reinterpret_cast<Storage *>(ptr);
2239 char *ptr = access();
2240 char *flags = ptr + size() * sizeof(Storage);
2241 if (!(*flags & 0x1))
2244 Storage *s = reinterpret_cast<Storage *>(ptr);
2249 template <class Storage>
2250 class VectorBin : public BinBase
2253 typedef typename Storage::Params Params;
2259 enum { binned = true };
2260 VectorBin() : _size(0) {}
2262 bool initialized() const { return _size > 0; }
2263 void init(int s, Params ¶ms)
2265 assert(!initialized());
2268 allocate(_size * sizeof(Storage));
2271 int size() const { return _size; }
2273 Storage *data(int index, Params ¶ms)
2275 assert(initialized());
2276 assert(index >= 0 && index < size());
2277 char *ptr = access();
2278 char *flags = ptr + size() * sizeof(Storage);
2279 if (!(*flags & 0x1)) {
2281 for (int i = 0; i < size(); ++i)
2282 new (ptr + i * sizeof(Storage)) Storage(params);
2284 return reinterpret_cast<Storage *>(ptr + index * sizeof(Storage));
2288 char *ptr = access();
2289 char *flags = ptr + size() * sizeof(Storage);
2290 if (!(*flags & 0x1))
2293 for (int i = 0; i < _size; ++i) {
2294 char *p = ptr + i * sizeof(Storage);
2295 Storage *s = reinterpret_cast<Storage *>(p);
2304 template <class Storage>
2308 typedef typename Storage::Params Params;
2309 enum { binned = false };
2312 char ptr[sizeof(Storage)];
2317 reinterpret_cast<Storage *>(ptr)->~Storage();
2320 bool initialized() const { return true; }
2321 void init(Params ¶ms)
2323 new (ptr) Storage(params);
2325 int size() const{ return 1; }
2326 Storage *data(Params ¶ms)
2328 assert(initialized());
2329 return reinterpret_cast<Storage *>(ptr);
2333 Storage *s = reinterpret_cast<Storage *>(ptr);
2338 template <class Storage>
2342 typedef typename Storage::Params Params;
2343 enum { binned = false };
2350 VectorBin() : ptr(NULL) { }
2356 for (int i = 0; i < _size; ++i) {
2357 char *p = ptr + i * sizeof(Storage);
2358 reinterpret_cast<Storage *>(p)->~Storage();
2363 bool initialized() const { return ptr != NULL; }
2364 void init(int s, Params ¶ms)
2366 assert(s > 0 && "size must be positive!");
2367 assert(!initialized());
2369 ptr = new char[_size * sizeof(Storage)];
2370 for (int i = 0; i < _size; ++i)
2371 new (ptr + i * sizeof(Storage)) Storage(params);
2374 int size() const { return _size; }
2376 Storage *data(int index, Params ¶ms)
2378 assert(initialized());
2379 assert(index >= 0 && index < size());
2380 return reinterpret_cast<Storage *>(ptr + index * sizeof(Storage));
2384 for (int i = 0; i < _size; ++i) {
2385 char *p = ptr + i * sizeof(Storage);
2386 Storage *s = reinterpret_cast<Storage *>(p);
2393 //////////////////////////////////////////////////////////////////////
2395 // Visible Statistics Types
2397 //////////////////////////////////////////////////////////////////////
2399 * @defgroup VisibleStats "Statistic Types"
2400 * These are the statistics that are used in the simulator. By default these
2401 * store counters and don't use binning, but are templatized to accept any type
2402 * and any Bin class.
2407 * This is an easy way to assign all your stats to be binned or not
2408 * binned. If the typedef is NoBin, nothing is binned. If it is
2409 * MainBin, then all stats are binned under that Bin.
2412 typedef MainBin DefaultBin;
2414 typedef NoBin DefaultBin;
2418 * This is a simple scalar statistic, like a counter.
2419 * @sa Stat, ScalarBase, StatStor
2421 template <typename T = Counter, class Bin = DefaultBin>
2422 class Scalar : public Wrap<Scalar<T, Bin>, ScalarBase<T, StatStor, Bin>, ScalarData>
2425 /** The base implementation. */
2426 typedef ScalarBase<T, StatStor, Bin> Base;
2434 * Sets the stat equal to the given value. Calls the base implementation
2436 * @param v The new value.
2438 template <typename U>
2439 void operator=(const U& v) { Base::operator=(v); }
2443 * A stat that calculates the per cycle average of a value.
2444 * @sa Stat, ScalarBase, AvgStor
2446 template <typename T = Counter, class Bin = DefaultBin>
2447 class Average : public Wrap<Average<T, Bin>, ScalarBase<T, AvgStor, Bin>, ScalarData>
2450 /** The base implementation. */
2451 typedef ScalarBase<T, AvgStor, Bin> Base;
2459 * Sets the stat equal to the given value. Calls the base implementation
2461 * @param v The new value.
2463 template <typename U>
2464 void operator=(const U& v) { Base::operator=(v); }
2468 * A vector of scalar stats.
2469 * @sa Stat, VectorBase, StatStor
2471 template <typename T = Counter, class Bin = DefaultBin>
2472 class Vector : public WrapVec<Vector<T, Bin>, VectorBase<T, StatStor, Bin>, VectorData>
2476 * Set this vector to have the given size.
2477 * @param size The new size.
2478 * @return A reference to this stat.
2480 Vector &init(size_t size) {
2481 bin.init(size, params);
2489 * A vector of Average stats.
2490 * @sa Stat, VectorBase, AvgStor
2492 template <typename T = Counter, class Bin = DefaultBin>
2493 class AverageVector : public WrapVec<AverageVector<T, Bin>, VectorBase<T, AvgStor, Bin>, VectorData>
2497 * Set this vector to have the given size.
2498 * @param size The new size.
2499 * @return A reference to this stat.
2501 AverageVector &init(size_t size) {
2502 bin.init(size, params);
2510 * A 2-Dimensional vecto of scalar stats.
2511 * @sa Stat, Vector2dBase, StatStor
2513 template <typename T = Counter, class Bin = DefaultBin>
2514 class Vector2d : public WrapVec2d<Vector2d<T, Bin>, Vector2dBase<T, StatStor, Bin>, Vector2dData>
2517 Vector2d &init(size_t _x, size_t _y) {
2518 statData()->x = x = _x;
2519 statData()->y = y = _y;
2520 bin.init(x * y, params);
2528 * A simple distribution stat.
2529 * @sa Stat, DistBase, DistStor
2531 template <typename T = Counter, class Bin = DefaultBin>
2532 class Distribution : public Wrap<Distribution<T, Bin>, DistBase<T, DistStor, Bin>, DistData>
2535 /** Base implementation. */
2536 typedef DistBase<T, DistStor, Bin> Base;
2537 /** The Parameter type. */
2538 typedef typename DistStor<T>::Params Params;
2542 * Set the parameters of this distribution. @sa DistStor::Params
2543 * @param min The minimum value of the distribution.
2544 * @param max The maximum value of the distribution.
2545 * @param bkt The number of values in each bucket.
2546 * @return A reference to this distribution.
2548 Distribution &init(T min, T max, int bkt) {
2551 params.bucket_size = bkt;
2552 params.size = (max - min) / bkt + 1;
2561 * Calculates the mean and variance of all the samples.
2562 * @sa Stat, DistBase, FancyStor
2564 template <typename T = Counter, class Bin = DefaultBin>
2565 class StandardDeviation : public Wrap<StandardDeviation<T, Bin>, DistBase<T, FancyStor, Bin>, DistData>
2568 /** The base implementation */
2569 typedef DistBase<T, DistStor, Bin> Base;
2570 /** The parameter type. */
2571 typedef typename DistStor<T>::Params Params;
2575 * Construct and initialize this distribution.
2577 StandardDeviation() {
2584 * Calculates the per cycle mean and variance of the samples.
2585 * @sa Stat, DistBase, AvgFancy
2587 template <typename T = Counter, class Bin = DefaultBin>
2588 class AverageDeviation : public Wrap<AverageDeviation<T, Bin>, DistBase<T, AvgFancy, Bin>, DistData>
2591 /** The base implementation */
2592 typedef DistBase<T, DistStor, Bin> Base;
2593 /** The parameter type. */
2594 typedef typename DistStor<T>::Params Params;
2598 * Construct and initialize this distribution.
2608 * A vector of distributions.
2609 * @sa Stat, VectorDistBase, DistStor
2611 template <typename T = Counter, class Bin = DefaultBin>
2612 class VectorDistribution : public WrapVec<VectorDistribution<T, Bin>, VectorDistBase<T, DistStor, Bin>, VectorDistData>
2615 /** The base implementation */
2616 typedef VectorDistBase<T, DistStor, Bin> Base;
2617 /** The parameter type. */
2618 typedef typename DistStor<T>::Params Params;
2622 * Initialize storage and parameters for this distribution.
2623 * @param size The size of the vector (the number of distributions).
2624 * @param min The minimum value of the distribution.
2625 * @param max The maximum value of the distribution.
2626 * @param bkt The number of values in each bucket.
2627 * @return A reference to this distribution.
2629 VectorDistribution &init(int size, T min, T max, int bkt) {
2632 params.bucket_size = bkt;
2633 params.size = (max - min) / bkt + 1;
2634 bin.init(size, params);
2642 * This is a vector of StandardDeviation stats.
2643 * @sa Stat, VectorDistBase, FancyStor
2645 template <typename T = Counter, class Bin = DefaultBin>
2646 class VectorStandardDeviation : public WrapVec<VectorStandardDeviation<T, Bin>, VectorDistBase<T, FancyStor, Bin>, VectorDistData>
2649 /** The base implementation */
2650 typedef VectorDistBase<T, FancyStor, Bin> Base;
2651 /** The parameter type. */
2652 typedef typename DistStor<T>::Params Params;
2656 * Initialize storage for this distribution.
2657 * @param size The size of the vector.
2658 * @return A reference to this distribution.
2660 VectorStandardDeviation &init(int size) {
2661 bin.init(size, params);
2669 * This is a vector of AverageDeviation stats.
2670 * @sa Stat, VectorDistBase, AvgFancy
2672 template <typename T = Counter, class Bin = DefaultBin>
2673 class VectorAverageDeviation : public WrapVec<VectorAverageDeviation<T, Bin>, VectorDistBase<T, AvgFancy, Bin>, VectorDistData>
2676 /** The base implementation */
2677 typedef VectorDistBase<T, AvgFancy, Bin> Base;
2678 /** The parameter type. */
2679 typedef typename DistStor<T>::Params Params;
2683 * Initialize storage for this distribution.
2684 * @param size The size of the vector.
2685 * @return A reference to this distribution.
2687 VectorAverageDeviation &init(int size) {
2688 bin.init(size, params);
2696 * A formula for statistics that is calculated when printed. A formula is
2697 * stored as a tree of Nodes that represent the equation to calculate.
2698 * @sa Stat, ScalarStat, VectorStat, Node, Temp
2700 class FormulaBase : public DataAccess
2703 /** The root of the tree which represents the Formula */
2709 * Return the result of the Fomula in a vector. If there were no Vector
2710 * components to the Formula, then the vector is size 1. If there were,
2711 * like x/y with x being a vector of size 3, then the result returned will
2712 * be x[0]/y, x[1]/y, x[2]/y, respectively.
2713 * @return The result vector.
2715 void val(rvec_t &vec) const;
2718 * Return the total Formula result. If there is a Vector
2719 * component to this Formula, then this is the result of the
2720 * Formula if the formula is applied after summing all the
2721 * components of the Vector. For example, if Formula is x/y where
2722 * x is size 3, then total() will return (x[1]+x[2]+x[3])/y. If
2723 * there is no Vector component, total() returns the same value as
2724 * the first entry in the rvec_t val() returns.
2725 * @return The total of the result vector.
2727 result_t total() const;
2730 * Return the number of elements in the tree.
2732 size_t size() const;
2735 * Return true if Formula is binned. i.e. any of its children
2737 * @return True if Formula is binned.
2739 bool binned() const;
2741 bool check() const { return true; }
2744 * Formulas don't need to be reset
2756 void update(StatData *);
2760 class Formula : public WrapVec<Formula, FormulaBase, VectorData>
2764 * Create and initialize thie formula, and register it with the database.
2769 * Create a formula with the given root node, register it with the
2771 * @param r The root of the expression tree.
2776 * Set an unitialized Formula to the given root.
2777 * @param r The root of the expression tree.
2778 * @return a reference to this formula.
2780 const Formula &operator=(Temp r);
2783 * Add the given tree to the existing one.
2784 * @param r The root of the expression tree.
2785 * @return a reference to this formula.
2787 const Formula &operator+=(Temp r);
2790 class FormulaNode : public Node
2793 const Formula &formula;
2797 FormulaNode(const Formula &f) : formula(f) {}
2799 virtual size_t size() const { return formula.size(); }
2800 virtual const rvec_t &val() const { formula.val(vec); return vec; }
2801 virtual result_t total() const { return formula.total(); }
2802 virtual bool binned() const { return formula.binned(); }
2806 * Helper class to construct formula node trees.
2812 * Pointer to a Node object.
2818 * Copy the given pointer to this class.
2819 * @param n A pointer to a Node object to copy.
2821 Temp(NodePtr n) : node(n) { }
2824 * Return the node pointer.
2825 * @return the node pointer.
2827 operator NodePtr() { return node;}
2831 * Create a new ScalarStatNode.
2832 * @param s The ScalarStat to place in a node.
2834 template <typename T, class Bin>
2835 Temp(const Scalar<T, Bin> &s)
2836 : node(new ScalarStatNode(s.statData())) { }
2839 * Create a new ScalarStatNode.
2840 * @param s The ScalarStat to place in a node.
2842 template <typename T, class Bin>
2843 Temp(const Average<T, Bin> &s)
2844 : node(new ScalarStatNode(s.statData())) { }
2847 * Create a new VectorStatNode.
2848 * @param s The VectorStat to place in a node.
2850 template <typename T, class Bin>
2851 Temp(const Vector<T, Bin> &s)
2852 : node(new VectorStatNode(s.statData())) { }
2857 Temp(const Formula &f)
2858 : node(new FormulaNode(f)) { }
2861 * Create a new ScalarProxyNode.
2862 * @param p The ScalarProxy to place in a node.
2864 template <typename T, template <typename T> class Storage, class Bin>
2865 Temp(const ScalarProxy<T, Storage, Bin> &p)
2866 : node(new ScalarProxyNode<T, Storage, Bin>(p)) { }
2869 * Create a ConstNode
2870 * @param value The value of the const node.
2872 Temp(signed char value)
2873 : node(new ConstNode<signed char>(value)) {}
2876 * Create a ConstNode
2877 * @param value The value of the const node.
2879 Temp(unsigned char value)
2880 : node(new ConstNode<unsigned char>(value)) {}
2883 * Create a ConstNode
2884 * @param value The value of the const node.
2886 Temp(signed short value)
2887 : node(new ConstNode<signed short>(value)) {}
2890 * Create a ConstNode
2891 * @param value The value of the const node.
2893 Temp(unsigned short value)
2894 : node(new ConstNode<unsigned short>(value)) {}
2897 * Create a ConstNode
2898 * @param value The value of the const node.
2900 Temp(signed int value)
2901 : node(new ConstNode<signed int>(value)) {}
2904 * Create a ConstNode
2905 * @param value The value of the const node.
2907 Temp(unsigned int value)
2908 : node(new ConstNode<unsigned int>(value)) {}
2911 * Create a ConstNode
2912 * @param value The value of the const node.
2914 Temp(signed long value)
2915 : node(new ConstNode<signed long>(value)) {}
2918 * Create a ConstNode
2919 * @param value The value of the const node.
2921 Temp(unsigned long value)
2922 : node(new ConstNode<unsigned long>(value)) {}
2925 * Create a ConstNode
2926 * @param value The value of the const node.
2928 Temp(signed long long value)
2929 : node(new ConstNode<signed long long>(value)) {}
2932 * Create a ConstNode
2933 * @param value The value of the const node.
2935 Temp(unsigned long long value)
2936 : node(new ConstNode<unsigned long long>(value)) {}
2939 * Create a ConstNode
2940 * @param value The value of the const node.
2943 : node(new ConstNode<float>(value)) {}
2946 * Create a ConstNode
2947 * @param value The value of the const node.
2950 : node(new ConstNode<double>(value)) {}
2959 void dump(std::ostream &stream);
2961 void registerResetCallback(Callback *cb);
2964 operator+(Temp l, Temp r)
2966 return NodePtr(new BinaryNode<std::plus<result_t> >(l, r));
2970 operator-(Temp l, Temp r)
2972 return NodePtr(new BinaryNode<std::minus<result_t> >(l, r));
2976 operator*(Temp l, Temp r)
2978 return NodePtr(new BinaryNode<std::multiplies<result_t> >(l, r));
2982 operator/(Temp l, Temp r)
2984 return NodePtr(new BinaryNode<std::divides<result_t> >(l, r));
2988 operator%(Temp l, Temp r)
2990 return NodePtr(new BinaryNode<std::modulus<result_t> >(l, r));
2996 return NodePtr(new UnaryNode<std::negate<result_t> >(l));
2999 template <typename T>
3003 return NodePtr(new ConstNode<T>(val));
3006 template <typename T>
3010 return NodePtr(new FunctorNode<T>(val));
3013 template <typename T>
3017 return NodePtr(new ScalarNode<T>(val));
3023 return NodePtr(new SumNode<std::plus<result_t> >(val));
3025 extern bool PrintDescriptions;
3027 } // namespace statistics
3029 #endif // __STATISTICS_HH__