statistics.hh revision 5994:19131d568007
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 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 bool check() const { return s.check(); } 171 Counter value() const { return s.value(); } 172 Result result() const { return s.result(); } 173 Result total() const { return s.total(); } 174 void reset() { s.reset(); } 175 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 bool check() const { return s.check(); } 217 bool zero() const { return s.zero(); } 218 void reset() { s.reset(); } 219 220 size_type size() const { return s.size(); } 221 222 VCounter & 223 value() const 224 { 225 s.value(cvec); 226 return cvec; 227 } 228 229 const VResult & 230 result() const 231 { 232 s.result(rvec); 233 return rvec; 234 } 235 236 Result total() const { return s.total(); } 237 238 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 bool check() const { return s.check(); } 278 void reset() { s.reset(); } 279 bool zero() const { return s.zero(); } 280 281 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 bool check() const { return s.check(); } 327 void reset() { s.reset(); } 328 size_type size() const { return s.size(); } 329 bool zero() const { return s.zero(); } 330 331 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 bool check() const { return s.check(); } 372 void reset() { s.reset(); } 373 bool zero() const { return s.zero(); } 374 375 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 _precision 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.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 void visit(Visit &visitor) { visitor.visit(*this); } 866 std::string str() const { return to_string(value()); } 867 size_type size() const { return 1; } 868 bool zero() const { return value() == 0; } 869 bool check() const { return true; } 870 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 Counter value() const { return *scalar; } 882 Result result() const { return *scalar; } 883 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 Counter value() const { return (*functor)(); } 895 Result result() const { return (*functor)(); } 896 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.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 */ 1475 void 1476 sample(Counter val, int number) 1477 { 1478 if (val < min_track) 1479 underflow += number; 1480 else if (val > max_track) 1481 overflow += number; 1482 else { 1483 size_type index = 1484 (size_type)std::floor((val - min_track) / bucket_size); 1485 assert(index < size()); 1486 cvec[index] += number; 1487 } 1488 1489 if (val < min_val) 1490 min_val = val; 1491 1492 if (val > max_val) 1493 max_val = val; 1494 1495 Counter sample = val * number; 1496 sum += sample; 1497 squares += sample * sample; 1498 samples += number; 1499 } 1500 1501 /** 1502 * Return the number of buckets in this distribution. 1503 * @return the number of buckets. 1504 */ 1505 size_type size() const { return cvec.size(); } 1506 1507 /** 1508 * Returns true if any calls to sample have been made. 1509 * @return True if any values have been sampled. 1510 */ 1511 bool 1512 zero() const 1513 { 1514 return samples == Counter(); 1515 } 1516 1517 void 1518 update(Info *info, DistData &data) 1519 { 1520 const Params *params = safe_cast<const Params *>(info->storageParams); 1521 1522 data.min_val = (min_val == CounterLimits::max()) ? 0 : min_val; 1523 data.max_val = (max_val == CounterLimits::min()) ? 0 : max_val; 1524 data.underflow = underflow; 1525 data.overflow = overflow; 1526 1527 int buckets = params->buckets; 1528 data.cvec.resize(buckets); 1529 for (off_type i = 0; i < buckets; ++i) 1530 data.cvec[i] = cvec[i]; 1531 1532 data.sum = sum; 1533 data.squares = squares; 1534 data.samples = samples; 1535 } 1536 1537 /** 1538 * Reset stat value to default 1539 */ 1540 void 1541 reset(Info *info) 1542 { 1543 const Params *params = safe_cast<const Params *>(info->storageParams); 1544 min_track = params->min; 1545 max_track = params->max; 1546 bucket_size = params->bucket_size; 1547 1548 min_val = CounterLimits::max(); 1549 max_val = CounterLimits::min(); 1550 underflow = 0; 1551 overflow = 0; 1552 1553 size_type size = cvec.size(); 1554 for (off_type i = 0; i < size; ++i) 1555 cvec[i] = Counter(); 1556 1557 sum = Counter(); 1558 squares = Counter(); 1559 samples = Counter(); 1560 } 1561}; 1562 1563/** 1564 * Templatized storage and interface for a distribution that calculates mean 1565 * and variance. 1566 */ 1567class FancyStor 1568{ 1569 public: 1570 struct Params : public StorageParams {}; 1571 1572 public: 1573 enum { fancy = true }; 1574 1575 private: 1576 /** The current sum. */ 1577 Counter sum; 1578 /** The sum of squares. */ 1579 Counter squares; 1580 /** The number of samples. */ 1581 Counter samples; 1582 1583 public: 1584 /** 1585 * Create and initialize this storage. 1586 */ 1587 FancyStor(Info *info) 1588 : sum(Counter()), squares(Counter()), samples(Counter()) 1589 { } 1590 1591 /** 1592 * Add a value the given number of times to this running average. 1593 * Update the running sum and sum of squares, increment the number of 1594 * values seen by the given number. 1595 * @param val The value to add. 1596 * @param number The number of times to add the value. 1597 */ 1598 void 1599 sample(Counter val, int number) 1600 { 1601 Counter value = val * number; 1602 sum += value; 1603 squares += value * value; 1604 samples += number; 1605 } 1606 1607 void 1608 update(Info *info, DistData &data) 1609 { 1610 data.sum = sum; 1611 data.squares = squares; 1612 data.samples = samples; 1613 } 1614 1615 /** 1616 * Return the number of entries in this stat, 1 1617 * @return 1. 1618 */ 1619 size_type size() const { return 1; } 1620 1621 /** 1622 * Return true if no samples have been added. 1623 * @return True if no samples have been added. 1624 */ 1625 bool zero() const { return samples == Counter(); } 1626 1627 /** 1628 * Reset stat value to default 1629 */ 1630 void 1631 reset(Info *info) 1632 { 1633 sum = Counter(); 1634 squares = Counter(); 1635 samples = Counter(); 1636 } 1637}; 1638 1639/** 1640 * Templatized storage for distribution that calculates per tick mean and 1641 * variance. 1642 */ 1643class AvgFancy 1644{ 1645 public: 1646 struct Params : public StorageParams {}; 1647 1648 public: 1649 enum { fancy = true }; 1650 1651 private: 1652 /** Current total. */ 1653 Counter sum; 1654 /** Current sum of squares. */ 1655 Counter squares; 1656 1657 public: 1658 /** 1659 * Create and initialize this storage. 1660 */ 1661 AvgFancy(Info *info) 1662 : sum(Counter()), squares(Counter()) 1663 {} 1664 1665 /** 1666 * Add a value to the distribution for the given number of times. 1667 * Update the running sum and sum of squares. 1668 * @param val The value to add. 1669 * @param number The number of times to add the value. 1670 */ 1671 void 1672 sample(Counter val, int number) 1673 { 1674 Counter value = val * number; 1675 sum += value; 1676 squares += value * value; 1677 } 1678 1679 void 1680 update(Info *info, DistData &data) 1681 { 1682 data.sum = sum; 1683 data.squares = squares; 1684 data.samples = curTick; 1685 } 1686 1687 /** 1688 * Return the number of entries, in this case 1. 1689 * @return 1. 1690 */ 1691 size_type size() const { return 1; } 1692 1693 /** 1694 * Return true if no samples have been added. 1695 * @return True if the sum is zero. 1696 */ 1697 bool zero() const { return sum == Counter(); } 1698 1699 /** 1700 * Reset stat value to default 1701 */ 1702 void 1703 reset(Info *info) 1704 { 1705 sum = Counter(); 1706 squares = Counter(); 1707 } 1708}; 1709 1710/** 1711 * Implementation of a distribution stat. The type of distribution is 1712 * determined by the Storage template. @sa ScalarBase 1713 */ 1714template <class Stor> 1715class DistBase : public InfoAccess 1716{ 1717 public: 1718 typedef Stor Storage; 1719 typedef typename Stor::Params Params; 1720 1721 protected: 1722 /** The storage for this stat. */ 1723 char storage[sizeof(Storage)] __attribute__ ((aligned (8))); 1724 1725 protected: 1726 /** 1727 * Retrieve the storage. 1728 * @return The storage object for this stat. 1729 */ 1730 Storage * 1731 data() 1732 { 1733 return reinterpret_cast<Storage *>(storage); 1734 } 1735 1736 /** 1737 * Retrieve a const pointer to the storage. 1738 * @return A const pointer to the storage object for this stat. 1739 */ 1740 const Storage * 1741 data() const 1742 { 1743 return reinterpret_cast<const Storage *>(storage); 1744 } 1745 1746 void 1747 doInit() 1748 { 1749 new (storage) Storage(info()); 1750 setInit(); 1751 } 1752 1753 public: 1754 DistBase() { } 1755 1756 /** 1757 * Add a value to the distribtion n times. Calls sample on the storage 1758 * class. 1759 * @param v The value to add. 1760 * @param n The number of times to add it, defaults to 1. 1761 */ 1762 template <typename U> 1763 void sample(const U &v, int n = 1) { data()->sample(v, n); } 1764 1765 /** 1766 * Return the number of entries in this stat. 1767 * @return The number of entries. 1768 */ 1769 size_type size() const { return data()->size(); } 1770 /** 1771 * Return true if no samples have been added. 1772 * @return True if there haven't been any samples. 1773 */ 1774 bool zero() const { return data()->zero(); } 1775 1776 void 1777 update(DistInfoBase *base) 1778 { 1779 base->data.fancy = Storage::fancy; 1780 data()->update(info(), base->data); 1781 } 1782 1783 /** 1784 * Reset stat value to default 1785 */ 1786 void 1787 reset() 1788 { 1789 data()->reset(info()); 1790 } 1791 1792 bool 1793 check() 1794 { 1795 return true; 1796 } 1797}; 1798 1799template <class Stat> 1800class DistProxy; 1801 1802template <class Stor> 1803class VectorDistBase : public InfoAccess 1804{ 1805 public: 1806 typedef Stor Storage; 1807 typedef typename Stor::Params Params; 1808 typedef DistProxy<VectorDistBase<Storage> > Proxy; 1809 friend class DistProxy<VectorDistBase<Storage> >; 1810 1811 protected: 1812 Storage *storage; 1813 size_type _size; 1814 1815 protected: 1816 Storage * 1817 data(off_type index) 1818 { 1819 return &storage[index]; 1820 } 1821 1822 const Storage * 1823 data(off_type index) const 1824 { 1825 return &storage[index]; 1826 } 1827 1828 void 1829 doInit(size_type s) 1830 { 1831 assert(s > 0 && "size must be positive!"); 1832 assert(!storage && "already initialized"); 1833 _size = s; 1834 1835 char *ptr = new char[_size * sizeof(Storage)]; 1836 storage = reinterpret_cast<Storage *>(ptr); 1837 1838 for (off_type i = 0; i < _size; ++i) 1839 new (&storage[i]) Storage(info()); 1840 1841 setInit(); 1842 } 1843 1844 public: 1845 VectorDistBase() 1846 : storage(NULL) 1847 {} 1848 1849 ~VectorDistBase() 1850 { 1851 if (!storage) 1852 return ; 1853 1854 for (off_type i = 0; i < _size; ++i) 1855 data(i)->~Storage(); 1856 delete [] reinterpret_cast<char *>(storage); 1857 } 1858 1859 Proxy operator[](off_type index); 1860 1861 size_type 1862 size() const 1863 { 1864 return _size; 1865 } 1866 1867 bool 1868 zero() const 1869 { 1870 return false; 1871#if 0 1872 for (off_type i = 0; i < size(); ++i) 1873 if (!data(i)->zero()) 1874 return false; 1875 return true; 1876#endif 1877 } 1878 1879 /** 1880 * Reset stat value to default 1881 */ 1882 void 1883 reset() 1884 { 1885 for (off_type i = 0; i < size(); ++i) 1886 data(i)->reset(info()); 1887 } 1888 1889 bool 1890 check() 1891 { 1892 return storage != NULL; 1893 } 1894 1895 void 1896 update(VectorDistInfoBase *base) 1897 { 1898 size_type size = this->size(); 1899 base->data.resize(size); 1900 for (off_type i = 0; i < size; ++i) { 1901 base->data[i].fancy = Storage::fancy; 1902 data(i)->update(info(), base->data[i]); 1903 } 1904 } 1905}; 1906 1907template <class Stat> 1908class DistProxy 1909{ 1910 private: 1911 Stat *stat; 1912 off_type index; 1913 1914 protected: 1915 typename Stat::Storage *data() { return stat->data(index); } 1916 const typename Stat::Storage *data() const { return stat->data(index); } 1917 1918 public: 1919 DistProxy(Stat *s, off_type i) 1920 : stat(s), index(i) 1921 {} 1922 1923 DistProxy(const DistProxy &sp) 1924 : stat(sp.stat), index(sp.index) 1925 {} 1926 1927 const DistProxy & 1928 operator=(const DistProxy &sp) 1929 { 1930 stat = sp.stat; 1931 index = sp.index; 1932 return *this; 1933 } 1934 1935 public: 1936 template <typename U> 1937 void 1938 sample(const U &v, int n = 1) 1939 { 1940 data()->sample(v, n); 1941 } 1942 1943 size_type 1944 size() const 1945 { 1946 return 1; 1947 } 1948 1949 bool 1950 zero() const 1951 { 1952 return data()->zero(); 1953 } 1954 1955 /** 1956 * Proxy has no state. Nothing to reset. 1957 */ 1958 void reset() { } 1959}; 1960 1961template <class Storage> 1962inline typename VectorDistBase<Storage>::Proxy 1963VectorDistBase<Storage>::operator[](off_type index) 1964{ 1965 assert (index >= 0 && index < size()); 1966 return typename VectorDistBase<Storage>::Proxy(this, index); 1967} 1968 1969#if 0 1970template <class Storage> 1971Result 1972VectorDistBase<Storage>::total(off_type index) const 1973{ 1974 Result total = 0.0; 1975 for (off_type i = 0; i < x_size(); ++i) 1976 total += data(i)->result(); 1977} 1978#endif 1979 1980////////////////////////////////////////////////////////////////////// 1981// 1982// Formula Details 1983// 1984////////////////////////////////////////////////////////////////////// 1985 1986/** 1987 * Base class for formula statistic node. These nodes are used to build a tree 1988 * that represents the formula. 1989 */ 1990class Node : public RefCounted 1991{ 1992 public: 1993 /** 1994 * Return the number of nodes in the subtree starting at this node. 1995 * @return the number of nodes in this subtree. 1996 */ 1997 virtual size_type size() const = 0; 1998 /** 1999 * Return the result vector of this subtree. 2000 * @return The result vector of this subtree. 2001 */ 2002 virtual const VResult &result() const = 0; 2003 /** 2004 * Return the total of the result vector. 2005 * @return The total of the result vector. 2006 */ 2007 virtual Result total() const = 0; 2008 2009 /** 2010 * 2011 */ 2012 virtual std::string str() const = 0; 2013}; 2014 2015/** Reference counting pointer to a function Node. */ 2016typedef RefCountingPtr<Node> NodePtr; 2017 2018class ScalarStatNode : public Node 2019{ 2020 private: 2021 const ScalarInfoBase *data; 2022 mutable VResult vresult; 2023 2024 public: 2025 ScalarStatNode(const ScalarInfoBase *d) : data(d), vresult(1) {} 2026 2027 const VResult & 2028 result() const 2029 { 2030 vresult[0] = data->result(); 2031 return vresult; 2032 } 2033 2034 Result total() const { return data->result(); }; 2035 2036 size_type size() const { return 1; } 2037 2038 /** 2039 * 2040 */ 2041 std::string str() const { return data->name; } 2042}; 2043 2044template <class Stat> 2045class ScalarProxyNode : public Node 2046{ 2047 private: 2048 const ScalarProxy<Stat> proxy; 2049 mutable VResult vresult; 2050 2051 public: 2052 ScalarProxyNode(const ScalarProxy<Stat> &p) 2053 : proxy(p), vresult(1) 2054 { } 2055 2056 const VResult & 2057 result() const 2058 { 2059 vresult[0] = proxy.result(); 2060 return vresult; 2061 } 2062 2063 Result 2064 total() const 2065 { 2066 return proxy.result(); 2067 } 2068 2069 size_type 2070 size() const 2071 { 2072 return 1; 2073 } 2074 2075 /** 2076 * 2077 */ 2078 std::string 2079 str() const 2080 { 2081 return proxy.str(); 2082 } 2083}; 2084 2085class VectorStatNode : public Node 2086{ 2087 private: 2088 const VectorInfoBase *data; 2089 2090 public: 2091 VectorStatNode(const VectorInfoBase *d) : data(d) { } 2092 const VResult &result() const { return data->result(); } 2093 Result total() const { return data->total(); }; 2094 2095 size_type size() const { return data->size(); } 2096 2097 std::string str() const { return data->name; } 2098}; 2099 2100template <class T> 2101class ConstNode : public Node 2102{ 2103 private: 2104 VResult vresult; 2105 2106 public: 2107 ConstNode(T s) : vresult(1, (Result)s) {} 2108 const VResult &result() const { return vresult; } 2109 Result total() const { return vresult[0]; }; 2110 size_type size() const { return 1; } 2111 std::string str() const { return to_string(vresult[0]); } 2112}; 2113 2114template <class T> 2115class ConstVectorNode : public Node 2116{ 2117 private: 2118 VResult vresult; 2119 2120 public: 2121 ConstVectorNode(const T &s) : vresult(s.begin(), s.end()) {} 2122 const VResult &result() const { return vresult; } 2123 2124 Result 2125 total() const 2126 { 2127 size_type size = this->size(); 2128 Result tmp = 0; 2129 for (off_type i = 0; i < size; i++) 2130 tmp += vresult[i]; 2131 return tmp; 2132 } 2133 2134 size_type size() const { return vresult.size(); } 2135 std::string 2136 str() const 2137 { 2138 size_type size = this->size(); 2139 std::string tmp = "("; 2140 for (off_type i = 0; i < size; i++) 2141 tmp += csprintf("%s ",to_string(vresult[i])); 2142 tmp += ")"; 2143 return tmp; 2144 } 2145}; 2146 2147template <class Op> 2148struct OpString; 2149 2150template<> 2151struct OpString<std::plus<Result> > 2152{ 2153 static std::string str() { return "+"; } 2154}; 2155 2156template<> 2157struct OpString<std::minus<Result> > 2158{ 2159 static std::string str() { return "-"; } 2160}; 2161 2162template<> 2163struct OpString<std::multiplies<Result> > 2164{ 2165 static std::string str() { return "*"; } 2166}; 2167 2168template<> 2169struct OpString<std::divides<Result> > 2170{ 2171 static std::string str() { return "/"; } 2172}; 2173 2174template<> 2175struct OpString<std::modulus<Result> > 2176{ 2177 static std::string str() { return "%"; } 2178}; 2179 2180template<> 2181struct OpString<std::negate<Result> > 2182{ 2183 static std::string str() { return "-"; } 2184}; 2185 2186template <class Op> 2187class UnaryNode : public Node 2188{ 2189 public: 2190 NodePtr l; 2191 mutable VResult vresult; 2192 2193 public: 2194 UnaryNode(NodePtr &p) : l(p) {} 2195 2196 const VResult & 2197 result() const 2198 { 2199 const VResult &lvec = l->result(); 2200 size_type size = lvec.size(); 2201 2202 assert(size > 0); 2203 2204 vresult.resize(size); 2205 Op op; 2206 for (off_type i = 0; i < size; ++i) 2207 vresult[i] = op(lvec[i]); 2208 2209 return vresult; 2210 } 2211 2212 Result 2213 total() const 2214 { 2215 const VResult &vec = this->result(); 2216 Result total = 0.0; 2217 for (off_type i = 0; i < size(); i++) 2218 total += vec[i]; 2219 return total; 2220 } 2221 2222 size_type size() const { return l->size(); } 2223 2224 std::string 2225 str() const 2226 { 2227 return OpString<Op>::str() + l->str(); 2228 } 2229}; 2230 2231template <class Op> 2232class BinaryNode : public Node 2233{ 2234 public: 2235 NodePtr l; 2236 NodePtr r; 2237 mutable VResult vresult; 2238 2239 public: 2240 BinaryNode(NodePtr &a, NodePtr &b) : l(a), r(b) {} 2241 2242 const VResult & 2243 result() const 2244 { 2245 Op op; 2246 const VResult &lvec = l->result(); 2247 const VResult &rvec = r->result(); 2248 2249 assert(lvec.size() > 0 && rvec.size() > 0); 2250 2251 if (lvec.size() == 1 && rvec.size() == 1) { 2252 vresult.resize(1); 2253 vresult[0] = op(lvec[0], rvec[0]); 2254 } else if (lvec.size() == 1) { 2255 size_type size = rvec.size(); 2256 vresult.resize(size); 2257 for (off_type i = 0; i < size; ++i) 2258 vresult[i] = op(lvec[0], rvec[i]); 2259 } else if (rvec.size() == 1) { 2260 size_type size = lvec.size(); 2261 vresult.resize(size); 2262 for (off_type i = 0; i < size; ++i) 2263 vresult[i] = op(lvec[i], rvec[0]); 2264 } else if (rvec.size() == lvec.size()) { 2265 size_type size = rvec.size(); 2266 vresult.resize(size); 2267 for (off_type i = 0; i < size; ++i) 2268 vresult[i] = op(lvec[i], rvec[i]); 2269 } 2270 2271 return vresult; 2272 } 2273 2274 Result 2275 total() const 2276 { 2277 const VResult &vec = this->result(); 2278 Result total = 0.0; 2279 for (off_type i = 0; i < size(); i++) 2280 total += vec[i]; 2281 return total; 2282 } 2283 2284 size_type 2285 size() const 2286 { 2287 size_type ls = l->size(); 2288 size_type rs = r->size(); 2289 if (ls == 1) { 2290 return rs; 2291 } else if (rs == 1) { 2292 return ls; 2293 } else { 2294 assert(ls == rs && "Node vector sizes are not equal"); 2295 return ls; 2296 } 2297 } 2298 2299 std::string 2300 str() const 2301 { 2302 return csprintf("(%s %s %s)", l->str(), OpString<Op>::str(), r->str()); 2303 } 2304}; 2305 2306template <class Op> 2307class SumNode : public Node 2308{ 2309 public: 2310 NodePtr l; 2311 mutable VResult vresult; 2312 2313 public: 2314 SumNode(NodePtr &p) : l(p), vresult(1) {} 2315 2316 const VResult & 2317 result() const 2318 { 2319 const VResult &lvec = l->result(); 2320 size_type size = lvec.size(); 2321 assert(size > 0); 2322 2323 vresult[0] = 0.0; 2324 2325 Op op; 2326 for (off_type i = 0; i < size; ++i) 2327 vresult[0] = op(vresult[0], lvec[i]); 2328 2329 return vresult; 2330 } 2331 2332 Result 2333 total() const 2334 { 2335 const VResult &lvec = l->result(); 2336 size_type size = lvec.size(); 2337 assert(size > 0); 2338 2339 Result vresult = 0.0; 2340 2341 Op op; 2342 for (off_type i = 0; i < size; ++i) 2343 vresult = op(vresult, lvec[i]); 2344 2345 return vresult; 2346 } 2347 2348 size_type size() const { return 1; } 2349 2350 std::string 2351 str() const 2352 { 2353 return csprintf("total(%s)", l->str()); 2354 } 2355}; 2356 2357 2358////////////////////////////////////////////////////////////////////// 2359// 2360// Visible Statistics Types 2361// 2362////////////////////////////////////////////////////////////////////// 2363/** 2364 * @defgroup VisibleStats "Statistic Types" 2365 * These are the statistics that are used in the simulator. 2366 * @{ 2367 */ 2368 2369/** 2370 * This is a simple scalar statistic, like a counter. 2371 * @sa Stat, ScalarBase, StatStor 2372 */ 2373template<int N = 0> 2374class Scalar : public Wrap<Scalar<N>, ScalarBase<StatStor>, ScalarInfo> 2375{ 2376 public: 2377 /** The base implementation. */ 2378 typedef ScalarBase<StatStor> Base; 2379 2380 Scalar() 2381 { 2382 this->doInit(); 2383 } 2384 2385 /** 2386 * Sets the stat equal to the given value. Calls the base implementation 2387 * of operator= 2388 * @param v The new value. 2389 */ 2390 template <typename U> 2391 void operator=(const U &v) { Base::operator=(v); } 2392}; 2393 2394class Value : public Wrap<Value, ValueBase, ScalarInfo> 2395{ 2396 public: 2397 /** The base implementation. */ 2398 typedef ValueBase Base; 2399 2400 template <class T> 2401 Value & 2402 scalar(T &value) 2403 { 2404 Base::scalar(value); 2405 return *this; 2406 } 2407 2408 template <class T> 2409 Value & 2410 functor(T &func) 2411 { 2412 Base::functor(func); 2413 return *this; 2414 } 2415}; 2416 2417/** 2418 * A stat that calculates the per tick average of a value. 2419 * @sa Stat, ScalarBase, AvgStor 2420 */ 2421template<int N = 0> 2422class Average : public Wrap<Average<N>, ScalarBase<AvgStor>, ScalarInfo> 2423{ 2424 public: 2425 /** The base implementation. */ 2426 typedef ScalarBase<AvgStor> Base; 2427 2428 Average() 2429 { 2430 this->doInit(); 2431 } 2432 2433 /** 2434 * Sets the stat equal to the given value. Calls the base implementation 2435 * of operator= 2436 * @param v The new value. 2437 */ 2438 template <typename U> 2439 void 2440 operator=(const U &v) 2441 { 2442 Base::operator=(v); 2443 } 2444}; 2445 2446/** 2447 * A vector of scalar stats. 2448 * @sa Stat, VectorBase, StatStor 2449 */ 2450template<int N = 0> 2451class Vector : public WrapVec<Vector<N>, VectorBase<StatStor>, VectorInfo> 2452{ 2453 public: 2454 /** The base implementation. */ 2455 typedef ScalarBase<StatStor> Base; 2456 2457 /** 2458 * Set this vector to have the given size. 2459 * @param size The new size. 2460 * @return A reference to this stat. 2461 */ 2462 Vector & 2463 init(size_type size) 2464 { 2465 this->doInit(size); 2466 return *this; 2467 } 2468}; 2469 2470/** 2471 * A vector of Average stats. 2472 * @sa Stat, VectorBase, AvgStor 2473 */ 2474template<int N = 0> 2475class AverageVector 2476 : public WrapVec<AverageVector<N>, VectorBase<AvgStor>, VectorInfo> 2477{ 2478 public: 2479 /** 2480 * Set this vector to have the given size. 2481 * @param size The new size. 2482 * @return A reference to this stat. 2483 */ 2484 AverageVector & 2485 init(size_type size) 2486 { 2487 this->doInit(size); 2488 return *this; 2489 } 2490}; 2491 2492/** 2493 * A 2-Dimensional vecto of scalar stats. 2494 * @sa Stat, Vector2dBase, StatStor 2495 */ 2496template<int N = 0> 2497class Vector2d 2498 : public WrapVec2d<Vector2d<N>, Vector2dBase<StatStor>, Vector2dInfo> 2499{ 2500 public: 2501 Vector2d & 2502 init(size_type x, size_type y) 2503 { 2504 this->doInit(x, y); 2505 return *this; 2506 } 2507}; 2508 2509/** 2510 * A simple distribution stat. 2511 * @sa Stat, DistBase, DistStor 2512 */ 2513template<int N = 0> 2514class Distribution 2515 : public Wrap<Distribution<N>, DistBase<DistStor>, DistInfo> 2516{ 2517 public: 2518 /** Base implementation. */ 2519 typedef DistBase<DistStor> Base; 2520 2521 public: 2522 /** 2523 * Set the parameters of this distribution. @sa DistStor::Params 2524 * @param min The minimum value of the distribution. 2525 * @param max The maximum value of the distribution. 2526 * @param bkt The number of values in each bucket. 2527 * @return A reference to this distribution. 2528 */ 2529 Distribution & 2530 init(Counter min, Counter max, Counter bkt) 2531 { 2532 DistStor::Params *params = new DistStor::Params; 2533 params->min = min; 2534 params->max = max; 2535 params->bucket_size = bkt; 2536 params->buckets = (size_type)rint((max - min) / bkt + 1.0); 2537 this->setParams(params); 2538 this->doInit(); 2539 return *this; 2540 } 2541}; 2542 2543/** 2544 * Calculates the mean and variance of all the samples. 2545 * @sa Stat, DistBase, FancyStor 2546 */ 2547template<int N = 0> 2548class StandardDeviation 2549 : public Wrap<StandardDeviation<N>, DistBase<FancyStor>, DistInfo> 2550{ 2551 public: 2552 /** The base implementation */ 2553 typedef DistBase<DistStor> Base; 2554 2555 public: 2556 /** 2557 * Construct and initialize this distribution. 2558 */ 2559 StandardDeviation() 2560 { 2561 this->doInit(); 2562 } 2563}; 2564 2565/** 2566 * Calculates the per tick mean and variance of the samples. 2567 * @sa Stat, DistBase, AvgFancy 2568 */ 2569template<int N = 0> 2570class AverageDeviation 2571 : public Wrap<AverageDeviation<N>, DistBase<AvgFancy>, DistInfo> 2572{ 2573 public: 2574 /** The base implementation */ 2575 typedef DistBase<DistStor> Base; 2576 2577 public: 2578 /** 2579 * Construct and initialize this distribution. 2580 */ 2581 AverageDeviation() 2582 { 2583 this->doInit(); 2584 } 2585}; 2586 2587/** 2588 * A vector of distributions. 2589 * @sa Stat, VectorDistBase, DistStor 2590 */ 2591template<int N = 0> 2592class VectorDistribution 2593 : public WrapVec<VectorDistribution<N>, 2594 VectorDistBase<DistStor>, 2595 VectorDistInfo> 2596{ 2597 public: 2598 /** The base implementation */ 2599 typedef VectorDistBase<DistStor> Base; 2600 2601 public: 2602 /** 2603 * Initialize storage and parameters for this distribution. 2604 * @param size The size of the vector (the number of distributions). 2605 * @param min The minimum value of the distribution. 2606 * @param max The maximum value of the distribution. 2607 * @param bkt The number of values in each bucket. 2608 * @return A reference to this distribution. 2609 */ 2610 VectorDistribution & 2611 init(size_type size, Counter min, Counter max, Counter bkt) 2612 { 2613 DistStor::Params *params = new DistStor::Params; 2614 params->min = min; 2615 params->max = max; 2616 params->bucket_size = bkt; 2617 params->buckets = rint((max - min) / bkt + 1.0); 2618 this->setParams(params); 2619 this->doInit(size); 2620 return *this; 2621 } 2622}; 2623 2624/** 2625 * This is a vector of StandardDeviation stats. 2626 * @sa Stat, VectorDistBase, FancyStor 2627 */ 2628template<int N = 0> 2629class VectorStandardDeviation 2630 : public WrapVec<VectorStandardDeviation<N>, 2631 VectorDistBase<FancyStor>, 2632 VectorDistInfo> 2633{ 2634 public: 2635 /** The base implementation */ 2636 typedef VectorDistBase<FancyStor> Base; 2637 2638 public: 2639 /** 2640 * Initialize storage for this distribution. 2641 * @param size The size of the vector. 2642 * @return A reference to this distribution. 2643 */ 2644 VectorStandardDeviation & 2645 init(size_type size) 2646 { 2647 this->doInit(size); 2648 return *this; 2649 } 2650}; 2651 2652/** 2653 * This is a vector of AverageDeviation stats. 2654 * @sa Stat, VectorDistBase, AvgFancy 2655 */ 2656template<int N = 0> 2657class VectorAverageDeviation 2658 : public WrapVec<VectorAverageDeviation<N>, 2659 VectorDistBase<AvgFancy>, 2660 VectorDistInfo> 2661{ 2662 public: 2663 /** The base implementation */ 2664 typedef VectorDistBase<AvgFancy> Base; 2665 2666 public: 2667 /** 2668 * Initialize storage for this distribution. 2669 * @param size The size of the vector. 2670 * @return A reference to this distribution. 2671 */ 2672 VectorAverageDeviation & 2673 init(size_type size) 2674 { 2675 this->doInit(size); 2676 return *this; 2677 } 2678}; 2679 2680/** 2681 * A formula for statistics that is calculated when printed. A formula is 2682 * stored as a tree of Nodes that represent the equation to calculate. 2683 * @sa Stat, ScalarStat, VectorStat, Node, Temp 2684 */ 2685class FormulaBase : public InfoAccess 2686{ 2687 protected: 2688 /** The root of the tree which represents the Formula */ 2689 NodePtr root; 2690 friend class Temp; 2691 2692 public: 2693 /** 2694 * Return the result of the Fomula in a vector. If there were no Vector 2695 * components to the Formula, then the vector is size 1. If there were, 2696 * like x/y with x being a vector of size 3, then the result returned will 2697 * be x[0]/y, x[1]/y, x[2]/y, respectively. 2698 * @return The result vector. 2699 */ 2700 void result(VResult &vec) const; 2701 2702 /** 2703 * Return the total Formula result. If there is a Vector 2704 * component to this Formula, then this is the result of the 2705 * Formula if the formula is applied after summing all the 2706 * components of the Vector. For example, if Formula is x/y where 2707 * x is size 3, then total() will return (x[1]+x[2]+x[3])/y. If 2708 * there is no Vector component, total() returns the same value as 2709 * the first entry in the VResult val() returns. 2710 * @return The total of the result vector. 2711 */ 2712 Result total() const; 2713 2714 /** 2715 * Return the number of elements in the tree. 2716 */ 2717 size_type size() const; 2718 2719 bool check() const { return true; } 2720 2721 /** 2722 * Formulas don't need to be reset 2723 */ 2724 void reset(); 2725 2726 /** 2727 * 2728 */ 2729 bool zero() const; 2730 2731 /** 2732 * 2733 */ 2734 void update(Info *); 2735 2736 std::string str() const; 2737}; 2738 2739class FormulaInfoBase : public VectorInfoBase 2740{ 2741 public: 2742 virtual std::string str() const = 0; 2743 bool check() const { return true; } 2744}; 2745 2746template <class Stat> 2747class FormulaInfo : public FormulaInfoBase 2748{ 2749 protected: 2750 Stat &s; 2751 mutable VResult vec; 2752 mutable VCounter cvec; 2753 2754 public: 2755 FormulaInfo(Stat &stat) : s(stat) {} 2756 2757 bool zero() const { return s.zero(); } 2758 void reset() { s.reset(); } 2759 2760 size_type size() const { return s.size(); } 2761 2762 const VResult & 2763 result() const 2764 { 2765 s.result(vec); 2766 return vec; 2767 } 2768 Result total() const { return s.total(); } 2769 VCounter &value() const { return cvec; } 2770 2771 void 2772 visit(Visit &visitor) 2773 { 2774 update(); 2775 s.update(this); 2776 visitor.visit(*this); 2777 } 2778 2779 std::string str() const { return s.str(); } 2780}; 2781 2782class Temp; 2783class Formula 2784 : public WrapVec<Formula, 2785 FormulaBase, 2786 FormulaInfo> 2787{ 2788 public: 2789 /** 2790 * Create and initialize thie formula, and register it with the database. 2791 */ 2792 Formula(); 2793 2794 /** 2795 * Create a formula with the given root node, register it with the 2796 * database. 2797 * @param r The root of the expression tree. 2798 */ 2799 Formula(Temp r); 2800 2801 /** 2802 * Set an unitialized Formula to the given root. 2803 * @param r The root of the expression tree. 2804 * @return a reference to this formula. 2805 */ 2806 const Formula &operator=(Temp r); 2807 2808 /** 2809 * Add the given tree to the existing one. 2810 * @param r The root of the expression tree. 2811 * @return a reference to this formula. 2812 */ 2813 const Formula &operator+=(Temp r); 2814}; 2815 2816class FormulaNode : public Node 2817{ 2818 private: 2819 const Formula &formula; 2820 mutable VResult vec; 2821 2822 public: 2823 FormulaNode(const Formula &f) : formula(f) {} 2824 2825 size_type size() const { return formula.size(); } 2826 const VResult &result() const { formula.result(vec); return vec; } 2827 Result total() const { return formula.total(); } 2828 2829 std::string str() const { return formula.str(); } 2830}; 2831 2832/** 2833 * Helper class to construct formula node trees. 2834 */ 2835class Temp 2836{ 2837 protected: 2838 /** 2839 * Pointer to a Node object. 2840 */ 2841 NodePtr node; 2842 2843 public: 2844 /** 2845 * Copy the given pointer to this class. 2846 * @param n A pointer to a Node object to copy. 2847 */ 2848 Temp(NodePtr n) : node(n) { } 2849 2850 /** 2851 * Return the node pointer. 2852 * @return the node pointer. 2853 */ 2854 operator NodePtr&() { return node; } 2855 2856 public: 2857 /** 2858 * Create a new ScalarStatNode. 2859 * @param s The ScalarStat to place in a node. 2860 */ 2861 template <int N> 2862 Temp(const Scalar<N> &s) 2863 : node(new ScalarStatNode(s.info())) 2864 { } 2865 2866 /** 2867 * Create a new ScalarStatNode. 2868 * @param s The ScalarStat to place in a node. 2869 */ 2870 Temp(const Value &s) 2871 : node(new ScalarStatNode(s.info())) 2872 { } 2873 2874 /** 2875 * Create a new ScalarStatNode. 2876 * @param s The ScalarStat to place in a node. 2877 */ 2878 template <int N> 2879 Temp(const Average<N> &s) 2880 : node(new ScalarStatNode(s.info())) 2881 { } 2882 2883 /** 2884 * Create a new VectorStatNode. 2885 * @param s The VectorStat to place in a node. 2886 */ 2887 template <int N> 2888 Temp(const Vector<N> &s) 2889 : node(new VectorStatNode(s.info())) 2890 { } 2891 2892 /** 2893 * 2894 */ 2895 Temp(const Formula &f) 2896 : node(new FormulaNode(f)) 2897 { } 2898 2899 /** 2900 * Create a new ScalarProxyNode. 2901 * @param p The ScalarProxy to place in a node. 2902 */ 2903 template <class Stat> 2904 Temp(const ScalarProxy<Stat> &p) 2905 : node(new ScalarProxyNode<Stat>(p)) 2906 { } 2907 2908 /** 2909 * Create a ConstNode 2910 * @param value The value of the const node. 2911 */ 2912 Temp(signed char value) 2913 : node(new ConstNode<signed char>(value)) 2914 { } 2915 2916 /** 2917 * Create a ConstNode 2918 * @param value The value of the const node. 2919 */ 2920 Temp(unsigned char value) 2921 : node(new ConstNode<unsigned char>(value)) 2922 { } 2923 2924 /** 2925 * Create a ConstNode 2926 * @param value The value of the const node. 2927 */ 2928 Temp(signed short value) 2929 : node(new ConstNode<signed short>(value)) 2930 { } 2931 2932 /** 2933 * Create a ConstNode 2934 * @param value The value of the const node. 2935 */ 2936 Temp(unsigned short value) 2937 : node(new ConstNode<unsigned short>(value)) 2938 { } 2939 2940 /** 2941 * Create a ConstNode 2942 * @param value The value of the const node. 2943 */ 2944 Temp(signed int value) 2945 : node(new ConstNode<signed int>(value)) 2946 { } 2947 2948 /** 2949 * Create a ConstNode 2950 * @param value The value of the const node. 2951 */ 2952 Temp(unsigned int value) 2953 : node(new ConstNode<unsigned int>(value)) 2954 { } 2955 2956 /** 2957 * Create a ConstNode 2958 * @param value The value of the const node. 2959 */ 2960 Temp(signed long value) 2961 : node(new ConstNode<signed long>(value)) 2962 { } 2963 2964 /** 2965 * Create a ConstNode 2966 * @param value The value of the const node. 2967 */ 2968 Temp(unsigned long value) 2969 : node(new ConstNode<unsigned long>(value)) 2970 { } 2971 2972 /** 2973 * Create a ConstNode 2974 * @param value The value of the const node. 2975 */ 2976 Temp(signed long long value) 2977 : node(new ConstNode<signed long long>(value)) 2978 { } 2979 2980 /** 2981 * Create a ConstNode 2982 * @param value The value of the const node. 2983 */ 2984 Temp(unsigned long long value) 2985 : node(new ConstNode<unsigned long long>(value)) 2986 { } 2987 2988 /** 2989 * Create a ConstNode 2990 * @param value The value of the const node. 2991 */ 2992 Temp(float value) 2993 : node(new ConstNode<float>(value)) 2994 { } 2995 2996 /** 2997 * Create a ConstNode 2998 * @param value The value of the const node. 2999 */ 3000 Temp(double value) 3001 : node(new ConstNode<double>(value)) 3002 { } 3003}; 3004 3005 3006/** 3007 * @} 3008 */ 3009 3010void check(); 3011void dump(); 3012void reset(); 3013void registerResetCallback(Callback *cb); 3014 3015inline Temp 3016operator+(Temp l, Temp r) 3017{ 3018 return NodePtr(new BinaryNode<std::plus<Result> >(l, r)); 3019} 3020 3021inline Temp 3022operator-(Temp l, Temp r) 3023{ 3024 return NodePtr(new BinaryNode<std::minus<Result> >(l, r)); 3025} 3026 3027inline Temp 3028operator*(Temp l, Temp r) 3029{ 3030 return NodePtr(new BinaryNode<std::multiplies<Result> >(l, r)); 3031} 3032 3033inline Temp 3034operator/(Temp l, Temp r) 3035{ 3036 return NodePtr(new BinaryNode<std::divides<Result> >(l, r)); 3037} 3038 3039inline Temp 3040operator-(Temp l) 3041{ 3042 return NodePtr(new UnaryNode<std::negate<Result> >(l)); 3043} 3044 3045template <typename T> 3046inline Temp 3047constant(T val) 3048{ 3049 return NodePtr(new ConstNode<T>(val)); 3050} 3051 3052template <typename T> 3053inline Temp 3054constantVector(T val) 3055{ 3056 return NodePtr(new ConstVectorNode<T>(val)); 3057} 3058 3059inline Temp 3060sum(Temp val) 3061{ 3062 return NodePtr(new SumNode<std::plus<Result> >(val)); 3063} 3064 3065std::list<Info *> &statsList(); 3066 3067/* namespace Stats */ } 3068 3069#endif // __BASE_STATISTICS_HH__ 3070