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