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