statistics.hh revision 5889:02e5bc7ca9ba
1/* 2 * Copyright (c) 2003-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 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. 15 * 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. 27 * 28 * Authors: Nathan Binkert 29 */ 30 31/** @file 32 * Declaration of Statistics objects. 33 */ 34 35/** 36* @todo 37* 38* Generalized N-dimensinal vector 39* documentation 40* key stats 41* interval stats 42* -- these both can use the same function that prints out a 43* specific set of stats 44* VectorStandardDeviation totals 45* Document Namespaces 46*/ 47#ifndef __BASE_STATISTICS_HH__ 48#define __BASE_STATISTICS_HH__ 49 50#include <algorithm> 51#include <cassert> 52#ifdef __SUNPRO_CC 53#include <math.h> 54#endif 55#include <cmath> 56#include <functional> 57#include <iosfwd> 58#include <list> 59#include <string> 60#include <vector> 61 62#include "base/cast.hh" 63#include "base/cprintf.hh" 64#include "base/intmath.hh" 65#include "base/refcnt.hh" 66#include "base/str.hh" 67#include "base/stats/flags.hh" 68#include "base/stats/visit.hh" 69#include "base/stats/types.hh" 70#include "sim/host.hh" 71 72class Callback; 73 74/** The current simulated tick. */ 75extern Tick curTick; 76 77/* A namespace for all of the Statistics */ 78namespace Stats { 79 80struct StorageParams 81{ 82 virtual ~StorageParams(); 83}; 84 85////////////////////////////////////////////////////////////////////// 86// 87// Statistics Framework Base classes 88// 89////////////////////////////////////////////////////////////////////// 90class Info 91{ 92 public: 93 /** The name of the stat. */ 94 std::string name; 95 /** The description of the stat. */ 96 std::string desc; 97 /** The formatting flags. */ 98 StatFlags flags; 99 /** The display precision. */ 100 int precision; 101 /** A pointer to a prerequisite Stat. */ 102 const Info *prereq; 103 /** 104 * A unique stat ID for each stat in the simulator. 105 * Can be used externally for lookups as well as for debugging. 106 */ 107 static int id_count; 108 int id; 109 110 public: 111 const StorageParams *storageParams; 112 113 public: 114 Info(); 115 virtual ~Info(); 116 117 /** 118 * Reset the corresponding stat to the default state. 119 */ 120 virtual void reset() = 0; 121 122 /** 123 * @return true if this stat has a value and satisfies its 124 * requirement as a prereq 125 */ 126 virtual bool zero() const = 0; 127 128 /** 129 * Check that this stat has been set up properly and is ready for 130 * use 131 * @return true for success 132 */ 133 virtual bool check() const = 0; 134 bool baseCheck() const; 135 136 /** 137 * Visitor entry for outputing statistics data 138 */ 139 virtual void visit(Visit &visitor) = 0; 140 141 /** 142 * Checks if the first stat's name is alphabetically less than the second. 143 * This function breaks names up at periods and considers each subname 144 * separately. 145 * @param stat1 The first stat. 146 * @param stat2 The second stat. 147 * @return stat1's name is alphabetically before stat2's 148 */ 149 static bool less(Info *stat1, Info *stat2); 150}; 151 152class ScalarInfoBase : public Info 153{ 154 public: 155 virtual Counter value() const = 0; 156 virtual Result result() const = 0; 157 virtual Result total() const = 0; 158 virtual void visit(Visit &visitor) { visitor.visit(*this); } 159}; 160 161template <class Stat> 162class ScalarInfo : public ScalarInfoBase 163{ 164 protected: 165 Stat &s; 166 167 public: 168 ScalarInfo(Stat &stat) : s(stat) {} 169 170 virtual bool check() const { return s.check(); } 171 virtual Counter value() const { return s.value(); } 172 virtual Result result() const { return s.result(); } 173 virtual Result total() const { return s.total(); } 174 virtual void reset() { s.reset(); } 175 virtual bool zero() const { return s.zero(); } 176}; 177 178class VectorInfoBase : public Info 179{ 180 public: 181 /** Names and descriptions of subfields. */ 182 mutable std::vector<std::string> subnames; 183 mutable std::vector<std::string> subdescs; 184 185 public: 186 virtual size_type size() const = 0; 187 virtual const VCounter &value() const = 0; 188 virtual const VResult &result() const = 0; 189 virtual Result total() const = 0; 190 191 void 192 update() 193 { 194 if (!subnames.empty()) { 195 size_type s = size(); 196 if (subnames.size() < s) 197 subnames.resize(s); 198 199 if (subdescs.size() < s) 200 subdescs.resize(s); 201 } 202 } 203}; 204 205template <class Stat> 206class VectorInfo : public VectorInfoBase 207{ 208 protected: 209 Stat &s; 210 mutable VCounter cvec; 211 mutable VResult rvec; 212 213 public: 214 VectorInfo(Stat &stat) : s(stat) {} 215 216 virtual bool check() const { return s.check(); } 217 virtual bool zero() const { return s.zero(); } 218 virtual void reset() { s.reset(); } 219 220 virtual size_type size() const { return s.size(); } 221 222 virtual VCounter & 223 value() const 224 { 225 s.value(cvec); 226 return cvec; 227 } 228 229 virtual const VResult & 230 result() const 231 { 232 s.result(rvec); 233 return rvec; 234 } 235 236 virtual Result total() const { return s.total(); } 237 238 virtual void 239 visit(Visit &visitor) 240 { 241 update(); 242 s.update(this); 243 visitor.visit(*this); 244 } 245}; 246 247struct DistData 248{ 249 Counter min_val; 250 Counter max_val; 251 Counter underflow; 252 Counter overflow; 253 VCounter cvec; 254 Counter sum; 255 Counter squares; 256 Counter samples; 257 258 bool fancy; 259}; 260 261class DistInfoBase : public Info 262{ 263 public: 264 /** Local storage for the entry values, used for printing. */ 265 DistData data; 266}; 267 268template <class Stat> 269class DistInfo : public DistInfoBase 270{ 271 protected: 272 Stat &s; 273 274 public: 275 DistInfo(Stat &stat) : s(stat) {} 276 277 virtual bool check() const { return s.check(); } 278 virtual void reset() { s.reset(); } 279 virtual bool zero() const { return s.zero(); } 280 281 virtual void 282 visit(Visit &visitor) 283 { 284 s.update(this); 285 visitor.visit(*this); 286 } 287}; 288 289class VectorDistInfoBase : public Info 290{ 291 public: 292 std::vector<DistData> data; 293 294 /** Names and descriptions of subfields. */ 295 mutable std::vector<std::string> subnames; 296 mutable std::vector<std::string> subdescs; 297 298 protected: 299 /** Local storage for the entry values, used for printing. */ 300 mutable VResult rvec; 301 302 public: 303 virtual size_type size() const = 0; 304 305 void 306 update() 307 { 308 size_type s = size(); 309 if (subnames.size() < s) 310 subnames.resize(s); 311 312 if (subdescs.size() < s) 313 subdescs.resize(s); 314 } 315}; 316 317template <class Stat> 318class VectorDistInfo : public VectorDistInfoBase 319{ 320 protected: 321 Stat &s; 322 323 public: 324 VectorDistInfo(Stat &stat) : s(stat) {} 325 326 virtual bool check() const { return s.check(); } 327 virtual void reset() { s.reset(); } 328 virtual size_type size() const { return s.size(); } 329 virtual bool zero() const { return s.zero(); } 330 331 virtual void 332 visit(Visit &visitor) 333 { 334 update(); 335 s.update(this); 336 visitor.visit(*this); 337 } 338}; 339 340class Vector2dInfoBase : public Info 341{ 342 public: 343 /** Names and descriptions of subfields. */ 344 std::vector<std::string> subnames; 345 std::vector<std::string> subdescs; 346 std::vector<std::string> y_subnames; 347 348 /** Local storage for the entry values, used for printing. */ 349 mutable VCounter cvec; 350 mutable size_type x; 351 mutable size_type y; 352 353 public: 354 void 355 update() 356 { 357 if (subnames.size() < x) 358 subnames.resize(x); 359 } 360}; 361 362template <class Stat> 363class Vector2dInfo : public Vector2dInfoBase 364{ 365 protected: 366 Stat &s; 367 368 public: 369 Vector2dInfo(Stat &stat) : s(stat) {} 370 371 virtual bool check() const { return s.check(); } 372 virtual void reset() { s.reset(); } 373 virtual bool zero() const { return s.zero(); } 374 375 virtual void 376 visit(Visit &visitor) 377 { 378 update(); 379 s.update(this); 380 visitor.visit(*this); 381 } 382}; 383 384class InfoAccess 385{ 386 protected: 387 /** Set up an info class for this statistic */ 388 void setInfo(Info *info); 389 /** Save Storage class parameters if any */ 390 void setParams(const StorageParams *params); 391 /** Save Storage class parameters if any */ 392 void setInit(); 393 394 /** Grab the information class for this statistic */ 395 Info *info(); 396 /** Grab the information class for this statistic */ 397 const Info *info() const; 398}; 399 400template <class Parent, class Child, template <class> class Info> 401class Wrap : public Child 402{ 403 public: 404 typedef Parent ParentType; 405 typedef Child ChildType; 406 typedef Info<Child> InfoType; 407 408 protected: 409 Parent &self() { return *reinterpret_cast<Parent *>(this); } 410 411 protected: 412 InfoType * 413 info() 414 { 415 return safe_cast<InfoType *>(InfoAccess::info()); 416 } 417 418 public: 419 const InfoType * 420 info() const 421 { 422 return safe_cast<const InfoType *>(InfoAccess::info()); 423 } 424 425 protected: 426 /** 427 * Copy constructor, copies are not allowed. 428 */ 429 Wrap(const Wrap &stat); 430 431 /** 432 * Can't copy stats. 433 */ 434 void operator=(const Wrap &); 435 436 public: 437 Wrap() 438 { 439 this->setInfo(new InfoType(*this)); 440 } 441 442 /** 443 * Set the name and marks this stat to print at the end of simulation. 444 * @param name The new name. 445 * @return A reference to this stat. 446 */ 447 Parent & 448 name(const std::string &_name) 449 { 450 InfoType *info = this->info(); 451 info->name = _name; 452 info->flags |= print; 453 return this->self(); 454 } 455 456 /** 457 * Set the description and marks this stat to print at the end of 458 * simulation. 459 * @param desc The new description. 460 * @return A reference to this stat. 461 */ 462 Parent & 463 desc(const std::string &_desc) 464 { 465 this->info()->desc = _desc; 466 return this->self(); 467 } 468 469 /** 470 * Set the precision and marks this stat to print at the end of simulation. 471 * @param p The new precision 472 * @return A reference to this stat. 473 */ 474 Parent & 475 precision(int _precision) 476 { 477 this->info()->precision = _precision; 478 return this->self(); 479 } 480 481 /** 482 * Set the flags and marks this stat to print at the end of simulation. 483 * @param f The new flags. 484 * @return A reference to this stat. 485 */ 486 Parent & 487 flags(StatFlags _flags) 488 { 489 this->info()->flags |= _flags; 490 return this->self(); 491 } 492 493 /** 494 * Set the prerequisite stat and marks this stat to print at the end of 495 * simulation. 496 * @param prereq The prerequisite stat. 497 * @return A reference to this stat. 498 */ 499 template <class Stat> 500 Parent & 501 prereq(const Stat &prereq) 502 { 503 this->info()->prereq = prereq.info(); 504 return this->self(); 505 } 506}; 507 508template <class Parent, class Child, template <class Child> class Info> 509class WrapVec : public Wrap<Parent, Child, Info> 510{ 511 public: 512 typedef Parent ParentType; 513 typedef Child ChildType; 514 typedef Info<Child> InfoType; 515 516 public: 517 // The following functions are specific to vectors. If you use them 518 // in a non vector context, you will get a nice compiler error! 519 520 /** 521 * Set the subfield name for the given index, and marks this stat to print 522 * at the end of simulation. 523 * @param index The subfield index. 524 * @param name The new name of the subfield. 525 * @return A reference to this stat. 526 */ 527 Parent & 528 subname(off_type index, const std::string &name) 529 { 530 std::vector<std::string> &subn = this->info()->subnames; 531 if (subn.size() <= index) 532 subn.resize(index + 1); 533 subn[index] = name; 534 return this->self(); 535 } 536 537 /** 538 * Set the subfield description for the given index and marks this stat to 539 * print at the end of simulation. 540 * @param index The subfield index. 541 * @param desc The new description of the subfield 542 * @return A reference to this stat. 543 */ 544 Parent & 545 subdesc(off_type index, const std::string &desc) 546 { 547 std::vector<std::string> &subd = this->info()->subdescs; 548 if (subd.size() <= index) 549 subd.resize(index + 1); 550 subd[index] = desc; 551 552 return this->self(); 553 } 554 555}; 556 557template <class Parent, class Child, template <class Child> class Info> 558class WrapVec2d : public WrapVec<Parent, Child, Info> 559{ 560 public: 561 typedef Parent ParentType; 562 typedef Child ChildType; 563 typedef Info<Child> InfoType; 564 565 public: 566 /** 567 * @warning This makes the assumption that if you're gonna subnames a 2d 568 * vector, you're subnaming across all y 569 */ 570 Parent & 571 ysubnames(const char **names) 572 { 573 InfoType *info = this->info(); 574 info->y_subnames.resize(this->y); 575 for (off_type i = 0; i < this->y; ++i) 576 info->y_subnames[i] = names[i]; 577 return this->self(); 578 } 579 580 Parent & 581 ysubname(off_type index, const std::string subname) 582 { 583 InfoType *info = this->info(); 584 assert(index < this->y); 585 info->y_subnames.resize(this->y); 586 info->y_subnames[index] = subname.c_str(); 587 return this->self(); 588 } 589}; 590 591////////////////////////////////////////////////////////////////////// 592// 593// Simple Statistics 594// 595////////////////////////////////////////////////////////////////////// 596 597/** 598 * Templatized storage and interface for a simple scalar stat. 599 */ 600class StatStor 601{ 602 private: 603 /** The statistic value. */ 604 Counter data; 605 606 public: 607 struct Params : public StorageParams {}; 608 609 public: 610 /** 611 * Builds this storage element and calls the base constructor of the 612 * datatype. 613 */ 614 StatStor(Info *info) 615 : data(Counter()) 616 { } 617 618 /** 619 * The the stat to the given value. 620 * @param val The new value. 621 */ 622 void set(Counter val) { data = val; } 623 /** 624 * Increment the stat by the given value. 625 * @param val The new value. 626 */ 627 void inc(Counter val) { data += val; } 628 /** 629 * Decrement the stat by the given value. 630 * @param val The new value. 631 */ 632 void dec(Counter val) { data -= val; } 633 /** 634 * Return the value of this stat as its base type. 635 * @return The value of this stat. 636 */ 637 Counter value() const { return data; } 638 /** 639 * Return the value of this stat as a result type. 640 * @return The value of this stat. 641 */ 642 Result result() const { return (Result)data; } 643 /** 644 * Reset stat value to default 645 */ 646 void reset(Info *info) { data = Counter(); } 647 648 /** 649 * @return true if zero value 650 */ 651 bool zero() const { return data == Counter(); } 652}; 653 654/** 655 * Templatized storage and interface to a per-tick average stat. This keeps 656 * a current count and updates a total (count * ticks) when this count 657 * changes. This allows the quick calculation of a per tick count of the item 658 * being watched. This is good for keeping track of residencies in structures 659 * among other things. 660 */ 661class AvgStor 662{ 663 private: 664 /** The current count. */ 665 Counter current; 666 /** The total count for all tick. */ 667 mutable Result total; 668 /** The tick that current last changed. */ 669 mutable Tick last; 670 671 public: 672 struct Params : public StorageParams {}; 673 674 public: 675 /** 676 * Build and initializes this stat storage. 677 */ 678 AvgStor(Info *info) 679 : current(0), total(0), last(0) 680 { } 681 682 /** 683 * Set the current count to the one provided, update the total and last 684 * set values. 685 * @param val The new count. 686 */ 687 void 688 set(Counter val) 689 { 690 total += current * (curTick - last); 691 last = curTick; 692 current = val; 693 } 694 695 /** 696 * Increment the current count by the provided value, calls set. 697 * @param val The amount to increment. 698 */ 699 void inc(Counter val) { set(current + val); } 700 701 /** 702 * Deccrement the current count by the provided value, calls set. 703 * @param val The amount to decrement. 704 */ 705 void dec(Counter val) { set(current - val); } 706 707 /** 708 * Return the current count. 709 * @return The current count. 710 */ 711 Counter value() const { return current; } 712 713 /** 714 * Return the current average. 715 * @return The current average. 716 */ 717 Result 718 result() const 719 { 720 total += current * (curTick - last); 721 last = curTick; 722 return (Result)(total + current) / (Result)(curTick + 1); 723 } 724 725 /** 726 * Reset stat value to default 727 */ 728 void 729 reset(Info *info) 730 { 731 total = 0; 732 last = curTick; 733 } 734 735 /** 736 * @return true if zero value 737 */ 738 bool zero() const { return total == 0.0; } 739}; 740 741/** 742 * Implementation of a scalar stat. The type of stat is determined by the 743 * Storage template. 744 */ 745template <class Stor> 746class ScalarBase : public InfoAccess 747{ 748 public: 749 typedef Stor Storage; 750 typedef typename Stor::Params Params; 751 752 protected: 753 /** The storage of this stat. */ 754 char storage[sizeof(Storage)] __attribute__ ((aligned (8))); 755 756 protected: 757 /** 758 * Retrieve the storage. 759 * @param index The vector index to access. 760 * @return The storage object at the given index. 761 */ 762 Storage * 763 data() 764 { 765 return reinterpret_cast<Storage *>(storage); 766 } 767 768 /** 769 * Retrieve a const pointer to the storage. 770 * for the given index. 771 * @param index The vector index to access. 772 * @return A const pointer to the storage object at the given index. 773 */ 774 const Storage * 775 data() const 776 { 777 return reinterpret_cast<const Storage *>(storage); 778 } 779 780 void 781 doInit() 782 { 783 new (storage) Storage(info()); 784 setInit(); 785 } 786 787 public: 788 /** 789 * Return the current value of this stat as its base type. 790 * @return The current value. 791 */ 792 Counter value() const { return data()->value(); } 793 794 public: 795 ScalarBase() { } 796 797 public: 798 // Common operators for stats 799 /** 800 * Increment the stat by 1. This calls the associated storage object inc 801 * function. 802 */ 803 void operator++() { data()->inc(1); } 804 /** 805 * Decrement the stat by 1. This calls the associated storage object dec 806 * function. 807 */ 808 void operator--() { data()->dec(1); } 809 810 /** Increment the stat by 1. */ 811 void operator++(int) { ++*this; } 812 /** Decrement the stat by 1. */ 813 void operator--(int) { --*this; } 814 815 /** 816 * Set the data value to the given value. This calls the associated storage 817 * object set function. 818 * @param v The new value. 819 */ 820 template <typename U> 821 void operator=(const U &v) { data()->set(v); } 822 823 /** 824 * Increment the stat by the given value. This calls the associated 825 * storage object inc function. 826 * @param v The value to add. 827 */ 828 template <typename U> 829 void operator+=(const U &v) { data()->inc(v); } 830 831 /** 832 * Decrement the stat by the given value. This calls the associated 833 * storage object dec function. 834 * @param v The value to substract. 835 */ 836 template <typename U> 837 void operator-=(const U &v) { data()->dec(v); } 838 839 /** 840 * Return the number of elements, always 1 for a scalar. 841 * @return 1. 842 */ 843 size_type size() const { return 1; } 844 845 bool check() const { return true; } 846 847 /** 848 * Reset stat value to default 849 */ 850 void reset() { data()->reset(info()); } 851 852 Counter value() { return data()->value(); } 853 854 Result result() { return data()->result(); } 855 856 Result total() { return result(); } 857 858 bool zero() { return result() == 0.0; } 859 860}; 861 862class ProxyInfo : public ScalarInfoBase 863{ 864 public: 865 virtual void visit(Visit &visitor) { visitor.visit(*this); } 866 virtual std::string str() const { return to_string(value()); } 867 virtual size_type size() const { return 1; } 868 virtual bool zero() const { return value() == 0; } 869 virtual bool check() const { return true; } 870 virtual void reset() { } 871}; 872 873template <class T> 874class ValueProxy : public ProxyInfo 875{ 876 private: 877 T *scalar; 878 879 public: 880 ValueProxy(T &val) : scalar(&val) {} 881 virtual Counter value() const { return *scalar; } 882 virtual Result result() const { return *scalar; } 883 virtual Result total() const { return *scalar; } 884}; 885 886template <class T> 887class FunctorProxy : public ProxyInfo 888{ 889 private: 890 T *functor; 891 892 public: 893 FunctorProxy(T &func) : functor(&func) {} 894 virtual Counter value() const { return (*functor)(); } 895 virtual Result result() const { return (*functor)(); } 896 virtual Result total() const { return (*functor)(); } 897}; 898 899class ValueBase : public InfoAccess 900{ 901 private: 902 ProxyInfo *proxy; 903 904 public: 905 ValueBase() : proxy(NULL) { } 906 ~ValueBase() { if (proxy) delete proxy; } 907 908 template <class T> 909 void 910 scalar(T &value) 911 { 912 proxy = new ValueProxy<T>(value); 913 setInit(); 914 } 915 916 template <class T> 917 void 918 functor(T &func) 919 { 920 proxy = new FunctorProxy<T>(func); 921 setInit(); 922 } 923 924 Counter value() { return proxy->value(); } 925 Result result() const { return proxy->result(); } 926 Result total() const { return proxy->total(); }; 927 size_type size() const { return proxy->size(); } 928 929 std::string str() const { return proxy->str(); } 930 bool zero() const { return proxy->zero(); } 931 bool check() const { return proxy != NULL; } 932 void reset() { } 933}; 934 935////////////////////////////////////////////////////////////////////// 936// 937// Vector Statistics 938// 939////////////////////////////////////////////////////////////////////// 940 941/** 942 * A proxy class to access the stat at a given index in a VectorBase stat. 943 * Behaves like a ScalarBase. 944 */ 945template <class Stat> 946class ScalarProxy 947{ 948 private: 949 /** Pointer to the parent Vector. */ 950 Stat *stat; 951 952 /** The index to access in the parent VectorBase. */ 953 off_type index; 954 955 public: 956 /** 957 * Return the current value of this stat as its base type. 958 * @return The current value. 959 */ 960 Counter value() const { return stat->data(index)->value(); } 961 962 /** 963 * Return the current value of this statas a result type. 964 * @return The current value. 965 */ 966 Result result() const { return stat->data(index)->result(); } 967 968 public: 969 /** 970 * Create and initialize this proxy, do not register it with the database. 971 * @param i The index to access. 972 */ 973 ScalarProxy(Stat *s, off_type i) 974 : stat(s), index(i) 975 { 976 assert(stat); 977 } 978 979 /** 980 * Create a copy of the provided ScalarProxy. 981 * @param sp The proxy to copy. 982 */ 983 ScalarProxy(const ScalarProxy &sp) 984 : stat(sp.stat), index(sp.index) 985 {} 986 987 /** 988 * Set this proxy equal to the provided one. 989 * @param sp The proxy to copy. 990 * @return A reference to this proxy. 991 */ 992 const ScalarProxy & 993 operator=(const ScalarProxy &sp) 994 { 995 stat = sp.stat; 996 index = sp.index; 997 return *this; 998 } 999 1000 public: 1001 // Common operators for stats 1002 /** 1003 * Increment the stat by 1. This calls the associated storage object inc 1004 * function. 1005 */ 1006 void operator++() { stat->data(index)->inc(1); } 1007 /** 1008 * Decrement the stat by 1. This calls the associated storage object dec 1009 * function. 1010 */ 1011 void operator--() { stat->data(index)->dec(1); } 1012 1013 /** Increment the stat by 1. */ 1014 void operator++(int) { ++*this; } 1015 /** Decrement the stat by 1. */ 1016 void operator--(int) { --*this; } 1017 1018 /** 1019 * Set the data value to the given value. This calls the associated storage 1020 * object set function. 1021 * @param v The new value. 1022 */ 1023 template <typename U> 1024 void 1025 operator=(const U &v) 1026 { 1027 stat->data(index)->set(v); 1028 } 1029 1030 /** 1031 * Increment the stat by the given value. This calls the associated 1032 * storage object inc function. 1033 * @param v The value to add. 1034 */ 1035 template <typename U> 1036 void 1037 operator+=(const U &v) 1038 { 1039 stat->data(index)->inc(v); 1040 } 1041 1042 /** 1043 * Decrement the stat by the given value. This calls the associated 1044 * storage object dec function. 1045 * @param v The value to substract. 1046 */ 1047 template <typename U> 1048 void 1049 operator-=(const U &v) 1050 { 1051 stat->data(index)->dec(v); 1052 } 1053 1054 /** 1055 * Return the number of elements, always 1 for a scalar. 1056 * @return 1. 1057 */ 1058 size_type size() const { return 1; } 1059 1060 /** 1061 * This stat has no state. Nothing to reset 1062 */ 1063 void reset() { } 1064 1065 public: 1066 std::string 1067 str() const 1068 { 1069 return csprintf("%s[%d]", stat->info()->name, index); 1070 } 1071}; 1072 1073/** 1074 * Implementation of a vector of stats. The type of stat is determined by the 1075 * Storage class. @sa ScalarBase 1076 */ 1077template <class Stor> 1078class VectorBase : public InfoAccess 1079{ 1080 public: 1081 typedef Stor Storage; 1082 typedef typename Stor::Params Params; 1083 1084 /** Proxy type */ 1085 typedef ScalarProxy<VectorBase<Storage> > Proxy; 1086 1087 friend class ScalarProxy<VectorBase<Storage> >; 1088 1089 protected: 1090 /** The storage of this stat. */ 1091 Storage *storage; 1092 size_type _size; 1093 1094 protected: 1095 /** 1096 * Retrieve the storage. 1097 * @param index The vector index to access. 1098 * @return The storage object at the given index. 1099 */ 1100 Storage *data(off_type index) { return &storage[index]; } 1101 1102 /** 1103 * Retrieve a const pointer to the storage. 1104 * @param index The vector index to access. 1105 * @return A const pointer to the storage object at the given index. 1106 */ 1107 const Storage *data(off_type index) const { return &storage[index]; } 1108 1109 void 1110 doInit(size_type s) 1111 { 1112 assert(s > 0 && "size must be positive!"); 1113 assert(!storage && "already initialized"); 1114 _size = s; 1115 1116 char *ptr = new char[_size * sizeof(Storage)]; 1117 storage = reinterpret_cast<Storage *>(ptr); 1118 1119 for (off_type i = 0; i < _size; ++i) 1120 new (&storage[i]) Storage(info()); 1121 1122 setInit(); 1123 } 1124 1125 public: 1126 void 1127 value(VCounter &vec) const 1128 { 1129 vec.resize(size()); 1130 for (off_type i = 0; i < size(); ++i) 1131 vec[i] = data(i)->value(); 1132 } 1133 1134 /** 1135 * Copy the values to a local vector and return a reference to it. 1136 * @return A reference to a vector of the stat values. 1137 */ 1138 void 1139 result(VResult &vec) const 1140 { 1141 vec.resize(size()); 1142 for (off_type i = 0; i < size(); ++i) 1143 vec[i] = data(i)->result(); 1144 } 1145 1146 /** 1147 * Return a total of all entries in this vector. 1148 * @return The total of all vector entries. 1149 */ 1150 Result 1151 total() const 1152 { 1153 Result total = 0.0; 1154 for (off_type i = 0; i < size(); ++i) 1155 total += data(i)->result(); 1156 return total; 1157 } 1158 1159 /** 1160 * @return the number of elements in this vector. 1161 */ 1162 size_type size() const { return _size; } 1163 1164 bool 1165 zero() const 1166 { 1167 for (off_type i = 0; i < size(); ++i) 1168 if (data(i)->zero()) 1169 return false; 1170 return true; 1171 } 1172 1173 bool 1174 check() const 1175 { 1176 return storage != NULL; 1177 } 1178 1179 void 1180 reset() 1181 { 1182 for (off_type i = 0; i < size(); ++i) 1183 data(i)->reset(info()); 1184 } 1185 1186 public: 1187 VectorBase() 1188 : storage(NULL) 1189 {} 1190 1191 ~VectorBase() 1192 { 1193 if (!storage) 1194 return; 1195 1196 for (off_type i = 0; i < _size; ++i) 1197 data(i)->~Storage(); 1198 delete [] reinterpret_cast<char *>(storage); 1199 } 1200 1201 /** 1202 * Return a reference (ScalarProxy) to the stat at the given index. 1203 * @param index The vector index to access. 1204 * @return A reference of the stat. 1205 */ 1206 Proxy 1207 operator[](off_type index) 1208 { 1209 assert (index >= 0 && index < size()); 1210 return Proxy(this, index); 1211 } 1212 1213 void update(Info *data) {} 1214}; 1215 1216template <class Stat> 1217class VectorProxy 1218{ 1219 private: 1220 Stat *stat; 1221 off_type offset; 1222 size_type len; 1223 1224 private: 1225 mutable VResult vec; 1226 1227 typename Stat::Storage * 1228 data(off_type index) 1229 { 1230 assert(index < len); 1231 return stat->data(offset + index); 1232 } 1233 1234 const typename Stat::Storage * 1235 data(off_type index) const 1236 { 1237 assert(index < len); 1238 return const_cast<Stat *>(stat)->data(offset + index); 1239 } 1240 1241 public: 1242 const VResult & 1243 result() const 1244 { 1245 vec.resize(size()); 1246 1247 for (off_type i = 0; i < size(); ++i) 1248 vec[i] = data(i)->result(); 1249 1250 return vec; 1251 } 1252 1253 Result 1254 total() const 1255 { 1256 Result total = 0; 1257 for (off_type i = 0; i < size(); ++i) 1258 total += data(i)->result(); 1259 return total; 1260 } 1261 1262 public: 1263 VectorProxy(Stat *s, off_type o, size_type l) 1264 : stat(s), offset(o), len(l) 1265 { 1266 } 1267 1268 VectorProxy(const VectorProxy &sp) 1269 : stat(sp.stat), offset(sp.offset), len(sp.len) 1270 { 1271 } 1272 1273 const VectorProxy & 1274 operator=(const VectorProxy &sp) 1275 { 1276 stat = sp.stat; 1277 offset = sp.offset; 1278 len = sp.len; 1279 return *this; 1280 } 1281 1282 ScalarProxy<Stat> 1283 operator[](off_type index) 1284 { 1285 assert (index >= 0 && index < size()); 1286 return ScalarProxy<Stat>(stat, offset + index); 1287 } 1288 1289 size_type size() const { return len; } 1290 1291 /** 1292 * This stat has no state. Nothing to reset. 1293 */ 1294 void reset() { } 1295}; 1296 1297template <class Stor> 1298class Vector2dBase : public InfoAccess 1299{ 1300 public: 1301 typedef Stor Storage; 1302 typedef typename Stor::Params Params; 1303 typedef VectorProxy<Vector2dBase<Storage> > Proxy; 1304 friend class ScalarProxy<Vector2dBase<Storage> >; 1305 friend class VectorProxy<Vector2dBase<Storage> >; 1306 1307 protected: 1308 size_type x; 1309 size_type y; 1310 size_type _size; 1311 Storage *storage; 1312 1313 protected: 1314 Storage *data(off_type index) { return &storage[index]; } 1315 const Storage *data(off_type index) const { return &storage[index]; } 1316 1317 void 1318 doInit(size_type _x, size_type _y) 1319 { 1320 assert(_x > 0 && _y > 0 && "sizes must be positive!"); 1321 assert(!storage && "already initialized"); 1322 1323 Vector2dInfoBase *info = safe_cast<Vector2dInfoBase *>(this->info()); 1324 1325 x = _x; 1326 y = _y; 1327 info->x = _x; 1328 info->y = _y; 1329 _size = x * y; 1330 1331 char *ptr = new char[_size * sizeof(Storage)]; 1332 storage = reinterpret_cast<Storage *>(ptr); 1333 1334 for (off_type i = 0; i < _size; ++i) 1335 new (&storage[i]) Storage(info); 1336 1337 setInit(); 1338 } 1339 1340 public: 1341 Vector2dBase() 1342 : storage(NULL) 1343 {} 1344 1345 ~Vector2dBase() 1346 { 1347 if (!storage) 1348 return; 1349 1350 for (off_type i = 0; i < _size; ++i) 1351 data(i)->~Storage(); 1352 delete [] reinterpret_cast<char *>(storage); 1353 } 1354 1355 void 1356 update(Vector2dInfoBase *newinfo) 1357 { 1358 size_type size = this->size(); 1359 newinfo->cvec.resize(size); 1360 for (off_type i = 0; i < size; ++i) 1361 newinfo->cvec[i] = data(i)->value(); 1362 } 1363 1364 std::string ysubname(off_type i) const { return (*this->y_subnames)[i]; } 1365 1366 Proxy 1367 operator[](off_type index) 1368 { 1369 off_type offset = index * y; 1370 assert (index >= 0 && offset + index < size()); 1371 return Proxy(this, offset, y); 1372 } 1373 1374 1375 size_type 1376 size() const 1377 { 1378 return _size; 1379 } 1380 1381 bool 1382 zero() const 1383 { 1384 return data(0)->zero(); 1385#if 0 1386 for (off_type i = 0; i < size(); ++i) 1387 if (!data(i)->zero()) 1388 return false; 1389 return true; 1390#endif 1391 } 1392 1393 /** 1394 * Reset stat value to default 1395 */ 1396 void 1397 reset() 1398 { 1399 for (off_type i = 0; i < size(); ++i) 1400 data(i)->reset(info()); 1401 } 1402 1403 bool 1404 check() 1405 { 1406 return storage != NULL; 1407 } 1408}; 1409 1410////////////////////////////////////////////////////////////////////// 1411// 1412// Non formula statistics 1413// 1414////////////////////////////////////////////////////////////////////// 1415 1416/** 1417 * Templatized storage and interface for a distrbution stat. 1418 */ 1419class DistStor 1420{ 1421 public: 1422 /** The parameters for a distribution stat. */ 1423 struct Params : public StorageParams 1424 { 1425 /** The minimum value to track. */ 1426 Counter min; 1427 /** The maximum value to track. */ 1428 Counter max; 1429 /** The number of entries in each bucket. */ 1430 Counter bucket_size; 1431 /** The number of buckets. Equal to (max-min)/bucket_size. */ 1432 size_type buckets; 1433 }; 1434 enum { fancy = false }; 1435 1436 private: 1437 /** The minimum value to track. */ 1438 Counter min_track; 1439 /** The maximum value to track. */ 1440 Counter max_track; 1441 /** The number of entries in each bucket. */ 1442 Counter bucket_size; 1443 /** The number of buckets. Equal to (max-min)/bucket_size. */ 1444 size_type buckets; 1445 1446 /** The smallest value sampled. */ 1447 Counter min_val; 1448 /** The largest value sampled. */ 1449 Counter max_val; 1450 /** The number of values sampled less than min. */ 1451 Counter underflow; 1452 /** The number of values sampled more than max. */ 1453 Counter overflow; 1454 /** The current sum. */ 1455 Counter sum; 1456 /** The sum of squares. */ 1457 Counter squares; 1458 /** The number of samples. */ 1459 Counter samples; 1460 /** Counter for each bucket. */ 1461 VCounter cvec; 1462 1463 public: 1464 DistStor(Info *info) 1465 : cvec(safe_cast<const Params *>(info->storageParams)->buckets) 1466 { 1467 reset(info); 1468 } 1469 1470 /** 1471 * Add a value to the distribution for the given number of times. 1472 * @param val The value to add. 1473 * @param number The number of times to add the value. 1474 * @param params The paramters of the distribution. 1475 */ 1476 void 1477 sample(Counter val, int number) 1478 { 1479 if (val < min_track) 1480 underflow += number; 1481 else if (val > max_track) 1482 overflow += number; 1483 else { 1484 size_type index = 1485 (size_type)std::floor((val - min_track) / bucket_size); 1486 assert(index < size()); 1487 cvec[index] += number; 1488 } 1489 1490 if (val < min_val) 1491 min_val = val; 1492 1493 if (val > max_val) 1494 max_val = val; 1495 1496 Counter sample = val * number; 1497 sum += sample; 1498 squares += sample * sample; 1499 samples += number; 1500 } 1501 1502 /** 1503 * Return the number of buckets in this distribution. 1504 * @return the number of buckets. 1505 */ 1506 size_type size() const { return cvec.size(); } 1507 1508 /** 1509 * Returns true if any calls to sample have been made. 1510 * @return True if any values have been sampled. 1511 */ 1512 bool 1513 zero() const 1514 { 1515 return samples == Counter(); 1516 } 1517 1518 void 1519 update(Info *info, DistData &data) 1520 { 1521 const Params *params = safe_cast<const Params *>(info->storageParams); 1522 1523 data.min_val = (min_val == CounterLimits::max()) ? 0 : min_val; 1524 data.max_val = (max_val == CounterLimits::min()) ? 0 : max_val; 1525 data.underflow = underflow; 1526 data.overflow = overflow; 1527 1528 int buckets = params->buckets; 1529 data.cvec.resize(buckets); 1530 for (off_type i = 0; i < buckets; ++i) 1531 data.cvec[i] = cvec[i]; 1532 1533 data.sum = sum; 1534 data.squares = squares; 1535 data.samples = samples; 1536 } 1537 1538 /** 1539 * Reset stat value to default 1540 */ 1541 void 1542 reset(Info *info) 1543 { 1544 const Params *params = safe_cast<const Params *>(info->storageParams); 1545 min_track = params->min; 1546 max_track = params->max; 1547 bucket_size = params->bucket_size; 1548 1549 min_val = CounterLimits::max(); 1550 max_val = CounterLimits::min(); 1551 underflow = 0; 1552 overflow = 0; 1553 1554 size_type size = cvec.size(); 1555 for (off_type i = 0; i < size; ++i) 1556 cvec[i] = Counter(); 1557 1558 sum = Counter(); 1559 squares = Counter(); 1560 samples = Counter(); 1561 } 1562}; 1563 1564/** 1565 * Templatized storage and interface for a distribution that calculates mean 1566 * and variance. 1567 */ 1568class FancyStor 1569{ 1570 public: 1571 struct Params : public StorageParams {}; 1572 1573 public: 1574 enum { fancy = true }; 1575 1576 private: 1577 /** The current sum. */ 1578 Counter sum; 1579 /** The sum of squares. */ 1580 Counter squares; 1581 /** The number of samples. */ 1582 Counter samples; 1583 1584 public: 1585 /** 1586 * Create and initialize this storage. 1587 */ 1588 FancyStor(Info *info) 1589 : sum(Counter()), squares(Counter()), samples(Counter()) 1590 { } 1591 1592 /** 1593 * Add a value the given number of times to this running average. 1594 * Update the running sum and sum of squares, increment the number of 1595 * values seen by the given number. 1596 * @param val The value to add. 1597 * @param number The number of times to add the value. 1598 * @param p The parameters of this stat. 1599 */ 1600 void 1601 sample(Counter val, int number) 1602 { 1603 Counter value = val * number; 1604 sum += value; 1605 squares += value * value; 1606 samples += number; 1607 } 1608 1609 void 1610 update(Info *info, DistData &data) 1611 { 1612 data.sum = sum; 1613 data.squares = squares; 1614 data.samples = samples; 1615 } 1616 1617 /** 1618 * Return the number of entries in this stat, 1 1619 * @return 1. 1620 */ 1621 size_type size() const { return 1; } 1622 1623 /** 1624 * Return true if no samples have been added. 1625 * @return True if no samples have been added. 1626 */ 1627 bool zero() const { return samples == Counter(); } 1628 1629 /** 1630 * Reset stat value to default 1631 */ 1632 void 1633 reset(Info *info) 1634 { 1635 sum = Counter(); 1636 squares = Counter(); 1637 samples = Counter(); 1638 } 1639}; 1640 1641/** 1642 * Templatized storage for distribution that calculates per tick mean and 1643 * variance. 1644 */ 1645class AvgFancy 1646{ 1647 public: 1648 struct Params : public StorageParams {}; 1649 1650 public: 1651 enum { fancy = true }; 1652 1653 private: 1654 /** Current total. */ 1655 Counter sum; 1656 /** Current sum of squares. */ 1657 Counter squares; 1658 1659 public: 1660 /** 1661 * Create and initialize this storage. 1662 */ 1663 AvgFancy(Info *info) 1664 : sum(Counter()), squares(Counter()) 1665 {} 1666 1667 /** 1668 * Add a value to the distribution for the given number of times. 1669 * Update the running sum and sum of squares. 1670 * @param val The value to add. 1671 * @param number The number of times to add the value. 1672 */ 1673 void 1674 sample(Counter val, int number) 1675 { 1676 Counter value = val * number; 1677 sum += value; 1678 squares += value * value; 1679 } 1680 1681 void 1682 update(Info *info, DistData &data) 1683 { 1684 data.sum = sum; 1685 data.squares = squares; 1686 data.samples = curTick; 1687 } 1688 1689 /** 1690 * Return the number of entries, in this case 1. 1691 * @return 1. 1692 */ 1693 size_type size() const { return 1; } 1694 1695 /** 1696 * Return true if no samples have been added. 1697 * @return True if the sum is zero. 1698 */ 1699 bool zero() const { return sum == Counter(); } 1700 1701 /** 1702 * Reset stat value to default 1703 */ 1704 void 1705 reset(Info *info) 1706 { 1707 sum = Counter(); 1708 squares = Counter(); 1709 } 1710}; 1711 1712/** 1713 * Implementation of a distribution stat. The type of distribution is 1714 * determined by the Storage template. @sa ScalarBase 1715 */ 1716template <class Stor> 1717class DistBase : public InfoAccess 1718{ 1719 public: 1720 typedef Stor Storage; 1721 typedef typename Stor::Params Params; 1722 1723 protected: 1724 /** The storage for this stat. */ 1725 char storage[sizeof(Storage)] __attribute__ ((aligned (8))); 1726 1727 protected: 1728 /** 1729 * Retrieve the storage. 1730 * @return The storage object for this stat. 1731 */ 1732 Storage * 1733 data() 1734 { 1735 return reinterpret_cast<Storage *>(storage); 1736 } 1737 1738 /** 1739 * Retrieve a const pointer to the storage. 1740 * @return A const pointer to the storage object for this stat. 1741 */ 1742 const Storage * 1743 data() const 1744 { 1745 return reinterpret_cast<const Storage *>(storage); 1746 } 1747 1748 void 1749 doInit() 1750 { 1751 new (storage) Storage(info()); 1752 setInit(); 1753 } 1754 1755 public: 1756 DistBase() { } 1757 1758 /** 1759 * Add a value to the distribtion n times. Calls sample on the storage 1760 * class. 1761 * @param v The value to add. 1762 * @param n The number of times to add it, defaults to 1. 1763 */ 1764 template <typename U> 1765 void sample(const U &v, int n = 1) { data()->sample(v, n); } 1766 1767 /** 1768 * Return the number of entries in this stat. 1769 * @return The number of entries. 1770 */ 1771 size_type size() const { return data()->size(); } 1772 /** 1773 * Return true if no samples have been added. 1774 * @return True if there haven't been any samples. 1775 */ 1776 bool zero() const { return data()->zero(); } 1777 1778 void 1779 update(DistInfoBase *base) 1780 { 1781 base->data.fancy = Storage::fancy; 1782 data()->update(info(), base->data); 1783 } 1784 1785 /** 1786 * Reset stat value to default 1787 */ 1788 void 1789 reset() 1790 { 1791 data()->reset(info()); 1792 } 1793 1794 bool 1795 check() 1796 { 1797 return true; 1798 } 1799}; 1800 1801template <class Stat> 1802class DistProxy; 1803 1804template <class Stor> 1805class VectorDistBase : public InfoAccess 1806{ 1807 public: 1808 typedef Stor Storage; 1809 typedef typename Stor::Params Params; 1810 typedef DistProxy<VectorDistBase<Storage> > Proxy; 1811 friend class DistProxy<VectorDistBase<Storage> >; 1812 1813 protected: 1814 Storage *storage; 1815 size_type _size; 1816 1817 protected: 1818 Storage * 1819 data(off_type index) 1820 { 1821 return &storage[index]; 1822 } 1823 1824 const Storage * 1825 data(off_type index) const 1826 { 1827 return &storage[index]; 1828 } 1829 1830 void 1831 doInit(size_type s) 1832 { 1833 assert(s > 0 && "size must be positive!"); 1834 assert(!storage && "already initialized"); 1835 _size = s; 1836 1837 char *ptr = new char[_size * sizeof(Storage)]; 1838 storage = reinterpret_cast<Storage *>(ptr); 1839 1840 for (off_type i = 0; i < _size; ++i) 1841 new (&storage[i]) Storage(info()); 1842 1843 setInit(); 1844 } 1845 1846 public: 1847 VectorDistBase() 1848 : storage(NULL) 1849 {} 1850 1851 ~VectorDistBase() 1852 { 1853 if (!storage) 1854 return ; 1855 1856 for (off_type i = 0; i < _size; ++i) 1857 data(i)->~Storage(); 1858 delete [] reinterpret_cast<char *>(storage); 1859 } 1860 1861 Proxy operator[](off_type index); 1862 1863 size_type 1864 size() const 1865 { 1866 return _size; 1867 } 1868 1869 bool 1870 zero() const 1871 { 1872 return false; 1873#if 0 1874 for (off_type i = 0; i < size(); ++i) 1875 if (!data(i)->zero()) 1876 return false; 1877 return true; 1878#endif 1879 } 1880 1881 /** 1882 * Reset stat value to default 1883 */ 1884 void 1885 reset() 1886 { 1887 for (off_type i = 0; i < size(); ++i) 1888 data(i)->reset(info()); 1889 } 1890 1891 bool 1892 check() 1893 { 1894 return storage != NULL; 1895 } 1896 1897 void 1898 update(VectorDistInfoBase *base) 1899 { 1900 size_type size = this->size(); 1901 base->data.resize(size); 1902 for (off_type i = 0; i < size; ++i) { 1903 base->data[i].fancy = Storage::fancy; 1904 data(i)->update(info(), base->data[i]); 1905 } 1906 } 1907}; 1908 1909template <class Stat> 1910class DistProxy 1911{ 1912 private: 1913 Stat *stat; 1914 off_type index; 1915 1916 protected: 1917 typename Stat::Storage *data() { return stat->data(index); } 1918 const typename Stat::Storage *data() const { return stat->data(index); } 1919 1920 public: 1921 DistProxy(Stat *s, off_type i) 1922 : stat(s), index(i) 1923 {} 1924 1925 DistProxy(const DistProxy &sp) 1926 : stat(sp.stat), index(sp.index) 1927 {} 1928 1929 const DistProxy & 1930 operator=(const DistProxy &sp) 1931 { 1932 stat = sp.stat; 1933 index = sp.index; 1934 return *this; 1935 } 1936 1937 public: 1938 template <typename U> 1939 void 1940 sample(const U &v, int n = 1) 1941 { 1942 data()->sample(v, n); 1943 } 1944 1945 size_type 1946 size() const 1947 { 1948 return 1; 1949 } 1950 1951 bool 1952 zero() const 1953 { 1954 return data()->zero(); 1955 } 1956 1957 /** 1958 * Proxy has no state. Nothing to reset. 1959 */ 1960 void reset() { } 1961}; 1962 1963template <class Storage> 1964inline typename VectorDistBase<Storage>::Proxy 1965VectorDistBase<Storage>::operator[](off_type index) 1966{ 1967 assert (index >= 0 && index < size()); 1968 return typename VectorDistBase<Storage>::Proxy(this, index); 1969} 1970 1971#if 0 1972template <class Storage> 1973Result 1974VectorDistBase<Storage>::total(off_type index) const 1975{ 1976 Result total = 0; 1977 for (off_type i = 0; i < x_size(); ++i) 1978 total += data(i)->result(); 1979} 1980#endif 1981 1982////////////////////////////////////////////////////////////////////// 1983// 1984// Formula Details 1985// 1986////////////////////////////////////////////////////////////////////// 1987 1988/** 1989 * Base class for formula statistic node. These nodes are used to build a tree 1990 * that represents the formula. 1991 */ 1992class Node : public RefCounted 1993{ 1994 public: 1995 /** 1996 * Return the number of nodes in the subtree starting at this node. 1997 * @return the number of nodes in this subtree. 1998 */ 1999 virtual size_type size() const = 0; 2000 /** 2001 * Return the result vector of this subtree. 2002 * @return The result vector of this subtree. 2003 */ 2004 virtual const VResult &result() const = 0; 2005 /** 2006 * Return the total of the result vector. 2007 * @return The total of the result vector. 2008 */ 2009 virtual Result total() const = 0; 2010 2011 /** 2012 * 2013 */ 2014 virtual std::string str() const = 0; 2015}; 2016 2017/** Reference counting pointer to a function Node. */ 2018typedef RefCountingPtr<Node> NodePtr; 2019 2020class ScalarStatNode : public Node 2021{ 2022 private: 2023 const ScalarInfoBase *data; 2024 mutable VResult vresult; 2025 2026 public: 2027 ScalarStatNode(const ScalarInfoBase *d) : data(d), vresult(1) {} 2028 2029 virtual const VResult & 2030 result() const 2031 { 2032 vresult[0] = data->result(); 2033 return vresult; 2034 } 2035 2036 virtual Result total() const { return data->result(); }; 2037 2038 virtual size_type size() const { return 1; } 2039 2040 /** 2041 * 2042 */ 2043 virtual std::string str() const { return data->name; } 2044}; 2045 2046template <class Stat> 2047class ScalarProxyNode : public Node 2048{ 2049 private: 2050 const ScalarProxy<Stat> proxy; 2051 mutable VResult vresult; 2052 2053 public: 2054 ScalarProxyNode(const ScalarProxy<Stat> &p) 2055 : proxy(p), vresult(1) 2056 { } 2057 2058 virtual const VResult & 2059 result() const 2060 { 2061 vresult[0] = proxy.result(); 2062 return vresult; 2063 } 2064 2065 virtual Result 2066 total() const 2067 { 2068 return proxy.result(); 2069 } 2070 2071 virtual size_type 2072 size() const 2073 { 2074 return 1; 2075 } 2076 2077 /** 2078 * 2079 */ 2080 virtual std::string 2081 str() const 2082 { 2083 return proxy.str(); 2084 } 2085}; 2086 2087class VectorStatNode : public Node 2088{ 2089 private: 2090 const VectorInfoBase *data; 2091 2092 public: 2093 VectorStatNode(const VectorInfoBase *d) : data(d) { } 2094 virtual const VResult &result() const { return data->result(); } 2095 virtual Result total() const { return data->total(); }; 2096 2097 virtual size_type size() const { return data->size(); } 2098 2099 virtual std::string str() const { return data->name; } 2100}; 2101 2102template <class T> 2103class ConstNode : public Node 2104{ 2105 private: 2106 VResult vresult; 2107 2108 public: 2109 ConstNode(T s) : vresult(1, (Result)s) {} 2110 const VResult &result() const { return vresult; } 2111 virtual Result total() const { return vresult[0]; }; 2112 virtual size_type size() const { return 1; } 2113 virtual std::string str() const { return to_string(vresult[0]); } 2114}; 2115 2116template <class T> 2117class ConstVectorNode : public Node 2118{ 2119 private: 2120 VResult vresult; 2121 2122 public: 2123 ConstVectorNode(const T &s) : vresult(s.begin(), s.end()) {} 2124 const VResult &result() const { return vresult; } 2125 2126 virtual Result 2127 total() const 2128 { 2129 size_type size = this->size(); 2130 Result tmp = 0; 2131 for (off_type i = 0; i < size; i++) 2132 tmp += vresult[i]; 2133 return tmp; 2134 } 2135 2136 virtual size_type size() const { return vresult.size(); } 2137 virtual std::string 2138 str() const 2139 { 2140 size_type size = this->size(); 2141 std::string tmp = "("; 2142 for (off_type i = 0; i < size; i++) 2143 tmp += csprintf("%s ",to_string(vresult[i])); 2144 tmp += ")"; 2145 return tmp; 2146 } 2147}; 2148 2149template <class Op> 2150struct OpString; 2151 2152template<> 2153struct OpString<std::plus<Result> > 2154{ 2155 static std::string str() { return "+"; } 2156}; 2157 2158template<> 2159struct OpString<std::minus<Result> > 2160{ 2161 static std::string str() { return "-"; } 2162}; 2163 2164template<> 2165struct OpString<std::multiplies<Result> > 2166{ 2167 static std::string str() { return "*"; } 2168}; 2169 2170template<> 2171struct OpString<std::divides<Result> > 2172{ 2173 static std::string str() { return "/"; } 2174}; 2175 2176template<> 2177struct OpString<std::modulus<Result> > 2178{ 2179 static std::string str() { return "%"; } 2180}; 2181 2182template<> 2183struct OpString<std::negate<Result> > 2184{ 2185 static std::string str() { return "-"; } 2186}; 2187 2188template <class Op> 2189class UnaryNode : public Node 2190{ 2191 public: 2192 NodePtr l; 2193 mutable VResult vresult; 2194 2195 public: 2196 UnaryNode(NodePtr &p) : l(p) {} 2197 2198 const VResult & 2199 result() const 2200 { 2201 const VResult &lvec = l->result(); 2202 size_type size = lvec.size(); 2203 2204 assert(size > 0); 2205 2206 vresult.resize(size); 2207 Op op; 2208 for (off_type i = 0; i < size; ++i) 2209 vresult[i] = op(lvec[i]); 2210 2211 return vresult; 2212 } 2213 2214 Result 2215 total() const 2216 { 2217 const VResult &vec = this->result(); 2218 Result total = 0; 2219 for (off_type i = 0; i < size(); i++) 2220 total += vec[i]; 2221 return total; 2222 } 2223 2224 virtual size_type size() const { return l->size(); } 2225 2226 virtual std::string 2227 str() const 2228 { 2229 return OpString<Op>::str() + l->str(); 2230 } 2231}; 2232 2233template <class Op> 2234class BinaryNode : public Node 2235{ 2236 public: 2237 NodePtr l; 2238 NodePtr r; 2239 mutable VResult vresult; 2240 2241 public: 2242 BinaryNode(NodePtr &a, NodePtr &b) : l(a), r(b) {} 2243 2244 const VResult & 2245 result() const 2246 { 2247 Op op; 2248 const VResult &lvec = l->result(); 2249 const VResult &rvec = r->result(); 2250 2251 assert(lvec.size() > 0 && rvec.size() > 0); 2252 2253 if (lvec.size() == 1 && rvec.size() == 1) { 2254 vresult.resize(1); 2255 vresult[0] = op(lvec[0], rvec[0]); 2256 } else if (lvec.size() == 1) { 2257 size_type size = rvec.size(); 2258 vresult.resize(size); 2259 for (off_type i = 0; i < size; ++i) 2260 vresult[i] = op(lvec[0], rvec[i]); 2261 } else if (rvec.size() == 1) { 2262 size_type size = lvec.size(); 2263 vresult.resize(size); 2264 for (off_type i = 0; i < size; ++i) 2265 vresult[i] = op(lvec[i], rvec[0]); 2266 } else if (rvec.size() == lvec.size()) { 2267 size_type size = rvec.size(); 2268 vresult.resize(size); 2269 for (off_type i = 0; i < size; ++i) 2270 vresult[i] = op(lvec[i], rvec[i]); 2271 } 2272 2273 return vresult; 2274 } 2275 2276 Result 2277 total() const 2278 { 2279 const VResult &vec = this->result(); 2280 Result total = 0; 2281 for (off_type i = 0; i < size(); i++) 2282 total += vec[i]; 2283 return total; 2284 } 2285 2286 virtual size_type 2287 size() const 2288 { 2289 size_type ls = l->size(); 2290 size_type rs = r->size(); 2291 if (ls == 1) { 2292 return rs; 2293 } else if (rs == 1) { 2294 return ls; 2295 } else { 2296 assert(ls == rs && "Node vector sizes are not equal"); 2297 return ls; 2298 } 2299 } 2300 2301 virtual std::string 2302 str() const 2303 { 2304 return csprintf("(%s %s %s)", l->str(), OpString<Op>::str(), r->str()); 2305 } 2306}; 2307 2308template <class Op> 2309class SumNode : public Node 2310{ 2311 public: 2312 NodePtr l; 2313 mutable VResult vresult; 2314 2315 public: 2316 SumNode(NodePtr &p) : l(p), vresult(1) {} 2317 2318 const VResult & 2319 result() const 2320 { 2321 const VResult &lvec = l->result(); 2322 size_type size = lvec.size(); 2323 assert(size > 0); 2324 2325 vresult[0] = 0.0; 2326 2327 Op op; 2328 for (off_type i = 0; i < size; ++i) 2329 vresult[0] = op(vresult[0], lvec[i]); 2330 2331 return vresult; 2332 } 2333 2334 Result 2335 total() const 2336 { 2337 const VResult &lvec = l->result(); 2338 size_type size = lvec.size(); 2339 assert(size > 0); 2340 2341 Result vresult = 0.0; 2342 2343 Op op; 2344 for (off_type i = 0; i < size; ++i) 2345 vresult = op(vresult, lvec[i]); 2346 2347 return vresult; 2348 } 2349 2350 virtual size_type size() const { return 1; } 2351 2352 virtual std::string 2353 str() const 2354 { 2355 return csprintf("total(%s)", l->str()); 2356 } 2357}; 2358 2359 2360////////////////////////////////////////////////////////////////////// 2361// 2362// Visible Statistics Types 2363// 2364////////////////////////////////////////////////////////////////////// 2365/** 2366 * @defgroup VisibleStats "Statistic Types" 2367 * These are the statistics that are used in the simulator. 2368 * @{ 2369 */ 2370 2371/** 2372 * This is a simple scalar statistic, like a counter. 2373 * @sa Stat, ScalarBase, StatStor 2374 */ 2375template<int N = 0> 2376class Scalar : public Wrap<Scalar<N>, ScalarBase<StatStor>, ScalarInfo> 2377{ 2378 public: 2379 /** The base implementation. */ 2380 typedef ScalarBase<StatStor> Base; 2381 2382 Scalar() 2383 { 2384 this->doInit(); 2385 } 2386 2387 /** 2388 * Sets the stat equal to the given value. Calls the base implementation 2389 * of operator= 2390 * @param v The new value. 2391 */ 2392 template <typename U> 2393 void operator=(const U &v) { Base::operator=(v); } 2394}; 2395 2396class Value : public Wrap<Value, ValueBase, ScalarInfo> 2397{ 2398 public: 2399 /** The base implementation. */ 2400 typedef ValueBase Base; 2401 2402 template <class T> 2403 Value & 2404 scalar(T &value) 2405 { 2406 Base::scalar(value); 2407 return *this; 2408 } 2409 2410 template <class T> 2411 Value & 2412 functor(T &func) 2413 { 2414 Base::functor(func); 2415 return *this; 2416 } 2417}; 2418 2419/** 2420 * A stat that calculates the per tick average of a value. 2421 * @sa Stat, ScalarBase, AvgStor 2422 */ 2423template<int N = 0> 2424class Average : public Wrap<Average<N>, ScalarBase<AvgStor>, ScalarInfo> 2425{ 2426 public: 2427 /** The base implementation. */ 2428 typedef ScalarBase<AvgStor> Base; 2429 2430 Average() 2431 { 2432 this->doInit(); 2433 } 2434 2435 /** 2436 * Sets the stat equal to the given value. Calls the base implementation 2437 * of operator= 2438 * @param v The new value. 2439 */ 2440 template <typename U> 2441 void 2442 operator=(const U &v) 2443 { 2444 Base::operator=(v); 2445 } 2446}; 2447 2448/** 2449 * A vector of scalar stats. 2450 * @sa Stat, VectorBase, StatStor 2451 */ 2452template<int N = 0> 2453class Vector : public WrapVec<Vector<N>, VectorBase<StatStor>, VectorInfo> 2454{ 2455 public: 2456 /** The base implementation. */ 2457 typedef ScalarBase<StatStor> Base; 2458 2459 /** 2460 * Set this vector to have the given size. 2461 * @param size The new size. 2462 * @return A reference to this stat. 2463 */ 2464 Vector & 2465 init(size_type size) 2466 { 2467 this->doInit(size); 2468 return *this; 2469 } 2470}; 2471 2472/** 2473 * A vector of Average stats. 2474 * @sa Stat, VectorBase, AvgStor 2475 */ 2476template<int N = 0> 2477class AverageVector 2478 : public WrapVec<AverageVector<N>, VectorBase<AvgStor>, VectorInfo> 2479{ 2480 public: 2481 /** 2482 * Set this vector to have the given size. 2483 * @param size The new size. 2484 * @return A reference to this stat. 2485 */ 2486 AverageVector & 2487 init(size_type size) 2488 { 2489 this->doInit(size); 2490 return *this; 2491 } 2492}; 2493 2494/** 2495 * A 2-Dimensional vecto of scalar stats. 2496 * @sa Stat, Vector2dBase, StatStor 2497 */ 2498template<int N = 0> 2499class Vector2d 2500 : public WrapVec2d<Vector2d<N>, Vector2dBase<StatStor>, Vector2dInfo> 2501{ 2502 public: 2503 Vector2d & 2504 init(size_type x, size_type y) 2505 { 2506 this->doInit(x, y); 2507 return *this; 2508 } 2509}; 2510 2511/** 2512 * A simple distribution stat. 2513 * @sa Stat, DistBase, DistStor 2514 */ 2515template<int N = 0> 2516class Distribution 2517 : public Wrap<Distribution<N>, DistBase<DistStor>, DistInfo> 2518{ 2519 public: 2520 /** Base implementation. */ 2521 typedef DistBase<DistStor> Base; 2522 2523 public: 2524 /** 2525 * Set the parameters of this distribution. @sa DistStor::Params 2526 * @param min The minimum value of the distribution. 2527 * @param max The maximum value of the distribution. 2528 * @param bkt The number of values in each bucket. 2529 * @return A reference to this distribution. 2530 */ 2531 Distribution & 2532 init(Counter min, Counter max, Counter bkt) 2533 { 2534 DistStor::Params *params = new DistStor::Params; 2535 params->min = min; 2536 params->max = max; 2537 params->bucket_size = bkt; 2538 params->buckets = (size_type)rint((max - min) / bkt + 1.0); 2539 this->setParams(params); 2540 this->doInit(); 2541 return *this; 2542 } 2543}; 2544 2545/** 2546 * Calculates the mean and variance of all the samples. 2547 * @sa Stat, DistBase, FancyStor 2548 */ 2549template<int N = 0> 2550class StandardDeviation 2551 : public Wrap<StandardDeviation<N>, DistBase<FancyStor>, DistInfo> 2552{ 2553 public: 2554 /** The base implementation */ 2555 typedef DistBase<DistStor> Base; 2556 2557 public: 2558 /** 2559 * Construct and initialize this distribution. 2560 */ 2561 StandardDeviation() 2562 { 2563 this->doInit(); 2564 } 2565}; 2566 2567/** 2568 * Calculates the per tick mean and variance of the samples. 2569 * @sa Stat, DistBase, AvgFancy 2570 */ 2571template<int N = 0> 2572class AverageDeviation 2573 : public Wrap<AverageDeviation<N>, DistBase<AvgFancy>, DistInfo> 2574{ 2575 public: 2576 /** The base implementation */ 2577 typedef DistBase<DistStor> Base; 2578 2579 public: 2580 /** 2581 * Construct and initialize this distribution. 2582 */ 2583 AverageDeviation() 2584 { 2585 this->doInit(); 2586 } 2587}; 2588 2589/** 2590 * A vector of distributions. 2591 * @sa Stat, VectorDistBase, DistStor 2592 */ 2593template<int N = 0> 2594class VectorDistribution 2595 : public WrapVec<VectorDistribution<N>, 2596 VectorDistBase<DistStor>, 2597 VectorDistInfo> 2598{ 2599 public: 2600 /** The base implementation */ 2601 typedef VectorDistBase<DistStor> Base; 2602 2603 public: 2604 /** 2605 * Initialize storage and parameters for this distribution. 2606 * @param size The size of the vector (the number of distributions). 2607 * @param min The minimum value of the distribution. 2608 * @param max The maximum value of the distribution. 2609 * @param bkt The number of values in each bucket. 2610 * @return A reference to this distribution. 2611 */ 2612 VectorDistribution & 2613 init(size_type size, Counter min, Counter max, Counter bkt) 2614 { 2615 DistStor::Params *params = new DistStor::Params; 2616 params->min = min; 2617 params->max = max; 2618 params->bucket_size = bkt; 2619 params->buckets = rint((max - min) / bkt + 1.0); 2620 this->setParams(params); 2621 this->doInit(size); 2622 return *this; 2623 } 2624}; 2625 2626/** 2627 * This is a vector of StandardDeviation stats. 2628 * @sa Stat, VectorDistBase, FancyStor 2629 */ 2630template<int N = 0> 2631class VectorStandardDeviation 2632 : public WrapVec<VectorStandardDeviation<N>, 2633 VectorDistBase<FancyStor>, 2634 VectorDistInfo> 2635{ 2636 public: 2637 /** The base implementation */ 2638 typedef VectorDistBase<FancyStor> Base; 2639 2640 public: 2641 /** 2642 * Initialize storage for this distribution. 2643 * @param size The size of the vector. 2644 * @return A reference to this distribution. 2645 */ 2646 VectorStandardDeviation & 2647 init(size_type size) 2648 { 2649 this->doInit(size); 2650 return *this; 2651 } 2652}; 2653 2654/** 2655 * This is a vector of AverageDeviation stats. 2656 * @sa Stat, VectorDistBase, AvgFancy 2657 */ 2658template<int N = 0> 2659class VectorAverageDeviation 2660 : public WrapVec<VectorAverageDeviation<N>, 2661 VectorDistBase<AvgFancy>, 2662 VectorDistInfo> 2663{ 2664 public: 2665 /** The base implementation */ 2666 typedef VectorDistBase<AvgFancy> Base; 2667 2668 public: 2669 /** 2670 * Initialize storage for this distribution. 2671 * @param size The size of the vector. 2672 * @return A reference to this distribution. 2673 */ 2674 VectorAverageDeviation & 2675 init(size_type size) 2676 { 2677 this->doInit(size); 2678 return *this; 2679 } 2680}; 2681 2682/** 2683 * A formula for statistics that is calculated when printed. A formula is 2684 * stored as a tree of Nodes that represent the equation to calculate. 2685 * @sa Stat, ScalarStat, VectorStat, Node, Temp 2686 */ 2687class FormulaBase : public InfoAccess 2688{ 2689 protected: 2690 /** The root of the tree which represents the Formula */ 2691 NodePtr root; 2692 friend class Temp; 2693 2694 public: 2695 /** 2696 * Return the result of the Fomula in a vector. If there were no Vector 2697 * components to the Formula, then the vector is size 1. If there were, 2698 * like x/y with x being a vector of size 3, then the result returned will 2699 * be x[0]/y, x[1]/y, x[2]/y, respectively. 2700 * @return The result vector. 2701 */ 2702 void result(VResult &vec) const; 2703 2704 /** 2705 * Return the total Formula result. If there is a Vector 2706 * component to this Formula, then this is the result of the 2707 * Formula if the formula is applied after summing all the 2708 * components of the Vector. For example, if Formula is x/y where 2709 * x is size 3, then total() will return (x[1]+x[2]+x[3])/y. If 2710 * there is no Vector component, total() returns the same value as 2711 * the first entry in the VResult val() returns. 2712 * @return The total of the result vector. 2713 */ 2714 Result total() const; 2715 2716 /** 2717 * Return the number of elements in the tree. 2718 */ 2719 size_type size() const; 2720 2721 bool check() const { return true; } 2722 2723 /** 2724 * Formulas don't need to be reset 2725 */ 2726 void reset(); 2727 2728 /** 2729 * 2730 */ 2731 bool zero() const; 2732 2733 /** 2734 * 2735 */ 2736 void update(Info *); 2737 2738 std::string str() const; 2739}; 2740 2741class FormulaInfoBase : public VectorInfoBase 2742{ 2743 public: 2744 virtual std::string str() const = 0; 2745 virtual bool check() const { return true; } 2746}; 2747 2748template <class Stat> 2749class FormulaInfo : public FormulaInfoBase 2750{ 2751 protected: 2752 Stat &s; 2753 mutable VResult vec; 2754 mutable VCounter cvec; 2755 2756 public: 2757 FormulaInfo(Stat &stat) : s(stat) {} 2758 2759 virtual bool zero() const { return s.zero(); } 2760 virtual void reset() { s.reset(); } 2761 2762 virtual size_type size() const { return s.size(); } 2763 2764 virtual const VResult & 2765 result() const 2766 { 2767 s.result(vec); 2768 return vec; 2769 } 2770 virtual Result total() const { return s.total(); } 2771 virtual VCounter &value() const { return cvec; } 2772 2773 virtual void 2774 visit(Visit &visitor) 2775 { 2776 update(); 2777 s.update(this); 2778 visitor.visit(*this); 2779 } 2780 2781 virtual std::string str() const { return s.str(); } 2782}; 2783 2784class Temp; 2785class Formula 2786 : public WrapVec<Formula, 2787 FormulaBase, 2788 FormulaInfo> 2789{ 2790 public: 2791 /** 2792 * Create and initialize thie formula, and register it with the database. 2793 */ 2794 Formula(); 2795 2796 /** 2797 * Create a formula with the given root node, register it with the 2798 * database. 2799 * @param r The root of the expression tree. 2800 */ 2801 Formula(Temp r); 2802 2803 /** 2804 * Set an unitialized Formula to the given root. 2805 * @param r The root of the expression tree. 2806 * @return a reference to this formula. 2807 */ 2808 const Formula &operator=(Temp r); 2809 2810 /** 2811 * Add the given tree to the existing one. 2812 * @param r The root of the expression tree. 2813 * @return a reference to this formula. 2814 */ 2815 const Formula &operator+=(Temp r); 2816}; 2817 2818class FormulaNode : public Node 2819{ 2820 private: 2821 const Formula &formula; 2822 mutable VResult vec; 2823 2824 public: 2825 FormulaNode(const Formula &f) : formula(f) {} 2826 2827 virtual size_type size() const { return formula.size(); } 2828 virtual const VResult &result() const { formula.result(vec); return vec; } 2829 virtual Result total() const { return formula.total(); } 2830 2831 virtual std::string str() const { return formula.str(); } 2832}; 2833 2834/** 2835 * Helper class to construct formula node trees. 2836 */ 2837class Temp 2838{ 2839 protected: 2840 /** 2841 * Pointer to a Node object. 2842 */ 2843 NodePtr node; 2844 2845 public: 2846 /** 2847 * Copy the given pointer to this class. 2848 * @param n A pointer to a Node object to copy. 2849 */ 2850 Temp(NodePtr n) : node(n) { } 2851 2852 /** 2853 * Return the node pointer. 2854 * @return the node pointer. 2855 */ 2856 operator NodePtr&() { return node;} 2857 2858 public: 2859 /** 2860 * Create a new ScalarStatNode. 2861 * @param s The ScalarStat to place in a node. 2862 */ 2863 template <int N> 2864 Temp(const Scalar<N> &s) 2865 : node(new ScalarStatNode(s.info())) 2866 { } 2867 2868 /** 2869 * Create a new ScalarStatNode. 2870 * @param s The ScalarStat to place in a node. 2871 */ 2872 Temp(const Value &s) 2873 : node(new ScalarStatNode(s.info())) 2874 { } 2875 2876 /** 2877 * Create a new ScalarStatNode. 2878 * @param s The ScalarStat to place in a node. 2879 */ 2880 template <int N> 2881 Temp(const Average<N> &s) 2882 : node(new ScalarStatNode(s.info())) 2883 { } 2884 2885 /** 2886 * Create a new VectorStatNode. 2887 * @param s The VectorStat to place in a node. 2888 */ 2889 template <int N> 2890 Temp(const Vector<N> &s) 2891 : node(new VectorStatNode(s.info())) 2892 { } 2893 2894 /** 2895 * 2896 */ 2897 Temp(const Formula &f) 2898 : node(new FormulaNode(f)) 2899 { } 2900 2901 /** 2902 * Create a new ScalarProxyNode. 2903 * @param p The ScalarProxy to place in a node. 2904 */ 2905 template <class Stat> 2906 Temp(const ScalarProxy<Stat> &p) 2907 : node(new ScalarProxyNode<Stat>(p)) 2908 { } 2909 2910 /** 2911 * Create a ConstNode 2912 * @param value The value of the const node. 2913 */ 2914 Temp(signed char value) 2915 : node(new ConstNode<signed char>(value)) 2916 { } 2917 2918 /** 2919 * Create a ConstNode 2920 * @param value The value of the const node. 2921 */ 2922 Temp(unsigned char value) 2923 : node(new ConstNode<unsigned char>(value)) 2924 { } 2925 2926 /** 2927 * Create a ConstNode 2928 * @param value The value of the const node. 2929 */ 2930 Temp(signed short value) 2931 : node(new ConstNode<signed short>(value)) 2932 { } 2933 2934 /** 2935 * Create a ConstNode 2936 * @param value The value of the const node. 2937 */ 2938 Temp(unsigned short value) 2939 : node(new ConstNode<unsigned short>(value)) 2940 { } 2941 2942 /** 2943 * Create a ConstNode 2944 * @param value The value of the const node. 2945 */ 2946 Temp(signed int value) 2947 : node(new ConstNode<signed int>(value)) 2948 { } 2949 2950 /** 2951 * Create a ConstNode 2952 * @param value The value of the const node. 2953 */ 2954 Temp(unsigned int value) 2955 : node(new ConstNode<unsigned int>(value)) 2956 { } 2957 2958 /** 2959 * Create a ConstNode 2960 * @param value The value of the const node. 2961 */ 2962 Temp(signed long value) 2963 : node(new ConstNode<signed long>(value)) 2964 { } 2965 2966 /** 2967 * Create a ConstNode 2968 * @param value The value of the const node. 2969 */ 2970 Temp(unsigned long value) 2971 : node(new ConstNode<unsigned long>(value)) 2972 { } 2973 2974 /** 2975 * Create a ConstNode 2976 * @param value The value of the const node. 2977 */ 2978 Temp(signed long long value) 2979 : node(new ConstNode<signed long long>(value)) 2980 { } 2981 2982 /** 2983 * Create a ConstNode 2984 * @param value The value of the const node. 2985 */ 2986 Temp(unsigned long long value) 2987 : node(new ConstNode<unsigned long long>(value)) 2988 { } 2989 2990 /** 2991 * Create a ConstNode 2992 * @param value The value of the const node. 2993 */ 2994 Temp(float value) 2995 : node(new ConstNode<float>(value)) 2996 { } 2997 2998 /** 2999 * Create a ConstNode 3000 * @param value The value of the const node. 3001 */ 3002 Temp(double value) 3003 : node(new ConstNode<double>(value)) 3004 { } 3005}; 3006 3007 3008/** 3009 * @} 3010 */ 3011 3012void check(); 3013void dump(); 3014void reset(); 3015void registerResetCallback(Callback *cb); 3016 3017inline Temp 3018operator+(Temp l, Temp r) 3019{ 3020 return NodePtr(new BinaryNode<std::plus<Result> >(l, r)); 3021} 3022 3023inline Temp 3024operator-(Temp l, Temp r) 3025{ 3026 return NodePtr(new BinaryNode<std::minus<Result> >(l, r)); 3027} 3028 3029inline Temp 3030operator*(Temp l, Temp r) 3031{ 3032 return NodePtr(new BinaryNode<std::multiplies<Result> >(l, r)); 3033} 3034 3035inline Temp 3036operator/(Temp l, Temp r) 3037{ 3038 return NodePtr(new BinaryNode<std::divides<Result> >(l, r)); 3039} 3040 3041inline Temp 3042operator-(Temp l) 3043{ 3044 return NodePtr(new UnaryNode<std::negate<Result> >(l)); 3045} 3046 3047template <typename T> 3048inline Temp 3049constant(T val) 3050{ 3051 return NodePtr(new ConstNode<T>(val)); 3052} 3053 3054template <typename T> 3055inline Temp 3056constantVector(T val) 3057{ 3058 return NodePtr(new ConstVectorNode<T>(val)); 3059} 3060 3061inline Temp 3062sum(Temp val) 3063{ 3064 return NodePtr(new SumNode<std::plus<Result> >(val)); 3065} 3066 3067std::list<Info *> &statsList(); 3068 3069/* namespace Stats */ } 3070 3071#endif // __BASE_STATISTICS_HH__ 3072