statistics.cc revision 2
112853Sgabeblack@google.com/* 212853Sgabeblack@google.com * Copyright (c) 2003 The Regents of The University of Michigan 312853Sgabeblack@google.com * All rights reserved. 412853Sgabeblack@google.com * 512853Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 612853Sgabeblack@google.com * modification, are permitted provided that the following conditions are 712853Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 812853Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 912853Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1012853Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1112853Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1212853Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1312853Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1412853Sgabeblack@google.com * this software without specific prior written permission. 1512853Sgabeblack@google.com * 1612853Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712853Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812853Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912853Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012853Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112853Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212853Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312853Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412853Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512853Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612853Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712853Sgabeblack@google.com */ 2812853Sgabeblack@google.com 2912853Sgabeblack@google.com#include <iomanip> 3012853Sgabeblack@google.com#include <iostream> 3112853Sgabeblack@google.com#include <list> 3212853Sgabeblack@google.com#include <map> 3312853Sgabeblack@google.com#include <string> 3412853Sgabeblack@google.com#include <sstream> 3512853Sgabeblack@google.com 3612853Sgabeblack@google.com#include <math.h> 3712853Sgabeblack@google.com 3812853Sgabeblack@google.com#include "cprintf.hh" 3912853Sgabeblack@google.com#include "intmath.h" 4012853Sgabeblack@google.com#include "misc.hh" 4112853Sgabeblack@google.com#include "statistics.hh" 4212853Sgabeblack@google.com#include "str.hh" 4312853Sgabeblack@google.com#include "universe.hh" 4412853Sgabeblack@google.com 4512853Sgabeblack@google.com#ifdef __M5_NAN 4612853Sgabeblack@google.comfloat 4712853Sgabeblack@google.com__nan() 4812853Sgabeblack@google.com{ 4912853Sgabeblack@google.com union { 5012853Sgabeblack@google.com uint32_t ui; 5112853Sgabeblack@google.com float f; 5212853Sgabeblack@google.com } nan; 5312853Sgabeblack@google.com 5412853Sgabeblack@google.com nan.ui = 0x7fc00000; 5512853Sgabeblack@google.com return nan.f; 5612853Sgabeblack@google.com} 5712853Sgabeblack@google.com#endif 5812853Sgabeblack@google.com 5912853Sgabeblack@google.com#ifdef STAT_DEBUG 6012853Sgabeblack@google.comstatic int total_stats = 0; 6112853Sgabeblack@google.com#endif 6212853Sgabeblack@google.com 6312853Sgabeblack@google.comusing namespace std; 6412853Sgabeblack@google.com 6512853Sgabeblack@google.com// This is a hack to get this parameter from the old stats package. 6612853Sgabeblack@google.comnamespace Statistics { 6712853Sgabeblack@google.combool PrintDescriptions = true; 6812853Sgabeblack@google.com 6912853Sgabeblack@google.comnamespace Detail { 7012853Sgabeblack@google.comstruct SubData 7112853Sgabeblack@google.com{ 7212853Sgabeblack@google.com string name; 7312853Sgabeblack@google.com string desc; 7412853Sgabeblack@google.com}; 7512853Sgabeblack@google.com 7612853Sgabeblack@google.comstruct StatData 7712853Sgabeblack@google.com{ 7812853Sgabeblack@google.com StatData(); 7912853Sgabeblack@google.com ~StatData(); 8012853Sgabeblack@google.com 8112853Sgabeblack@google.com bool init; 8212853Sgabeblack@google.com bool print; 8312853Sgabeblack@google.com string name; 8412853Sgabeblack@google.com vector<SubData> *subdata; 8512853Sgabeblack@google.com string desc; 8612853Sgabeblack@google.com int precision; 8712853Sgabeblack@google.com FormatFlags flags; 8812853Sgabeblack@google.com const Stat *prereq; 8912853Sgabeblack@google.com}; 9012853Sgabeblack@google.com 9112853Sgabeblack@google.comStatData::StatData() 9212853Sgabeblack@google.com : init(false), print(false), subdata(NULL), precision(-1), flags(none), 9312853Sgabeblack@google.com prereq(NULL) 9412853Sgabeblack@google.com{ 9512853Sgabeblack@google.com} 9612853Sgabeblack@google.com 9712853Sgabeblack@google.comStatData::~StatData() 9812853Sgabeblack@google.com{ 9912853Sgabeblack@google.com if (subdata) 10012853Sgabeblack@google.com delete subdata; 10112853Sgabeblack@google.com} 10212853Sgabeblack@google.com 10312853Sgabeblack@google.comclass Database 10412853Sgabeblack@google.com{ 10512853Sgabeblack@google.com private: 10612853Sgabeblack@google.com Database(const Database &) {} 10712853Sgabeblack@google.com 10812853Sgabeblack@google.com private: 10912853Sgabeblack@google.com typedef list<Stat *> list_t; 11012853Sgabeblack@google.com typedef map<const Stat *, StatData *> map_t; 11112853Sgabeblack@google.com 11212853Sgabeblack@google.com list_t allStats; 11312853Sgabeblack@google.com list_t printStats; 11412853Sgabeblack@google.com map_t map; 11512853Sgabeblack@google.com 11612853Sgabeblack@google.com public: 11712853Sgabeblack@google.com Database(); 11812853Sgabeblack@google.com ~Database(); 11912853Sgabeblack@google.com 12012853Sgabeblack@google.com void dump(ostream &stream); 12112853Sgabeblack@google.com 12212853Sgabeblack@google.com StatData *find(const Stat *stat); 12312853Sgabeblack@google.com void check(); 12412853Sgabeblack@google.com void regStat(Stat *stat); 12512853Sgabeblack@google.com StatData *print(Stat *stat); 12612853Sgabeblack@google.com}; 12712853Sgabeblack@google.com 12812853Sgabeblack@google.comDatabase::Database() 12912853Sgabeblack@google.com{} 13012853Sgabeblack@google.com 13112853Sgabeblack@google.comDatabase::~Database() 13212853Sgabeblack@google.com{} 13312853Sgabeblack@google.com 13412853Sgabeblack@google.comvoid 13512853Sgabeblack@google.comDatabase::dump(ostream &stream) 13612853Sgabeblack@google.com{ 13712853Sgabeblack@google.com list_t::iterator i = printStats.begin(); 13812853Sgabeblack@google.com list_t::iterator end = printStats.end(); 13912853Sgabeblack@google.com 14012853Sgabeblack@google.com while (i != end) { 14112853Sgabeblack@google.com Stat *stat = *i; 14212853Sgabeblack@google.com if (stat->dodisplay()) 14312853Sgabeblack@google.com stat->display(stream); 14412853Sgabeblack@google.com ++i; 14512853Sgabeblack@google.com } 14612853Sgabeblack@google.com} 14712853Sgabeblack@google.com 14812853Sgabeblack@google.comStatData * 14912853Sgabeblack@google.comDatabase::find(const Stat *stat) 15012853Sgabeblack@google.com{ 15112853Sgabeblack@google.com map_t::const_iterator i = map.find(stat); 15212853Sgabeblack@google.com 15312853Sgabeblack@google.com if (i == map.end()) 15412853Sgabeblack@google.com return NULL; 15512853Sgabeblack@google.com 15612853Sgabeblack@google.com return (*i).second; 15712853Sgabeblack@google.com} 15812853Sgabeblack@google.com 15912853Sgabeblack@google.comvoid 16012853Sgabeblack@google.comDatabase::check() 16112853Sgabeblack@google.com{ 16212853Sgabeblack@google.com list_t::iterator i = allStats.begin(); 16312853Sgabeblack@google.com list_t::iterator end = allStats.end(); 16412853Sgabeblack@google.com 16512853Sgabeblack@google.com while (i != end) { 16612853Sgabeblack@google.com Stat *stat = *i; 16712853Sgabeblack@google.com StatData *data = find(stat); 16812853Sgabeblack@google.com if (!data || !data->init) { 16912853Sgabeblack@google.com#ifdef STAT_DEBUG 17012853Sgabeblack@google.com cprintf("this is stat number %d\n",(*i)->number); 17112853Sgabeblack@google.com#endif 17212853Sgabeblack@google.com panic("Not all stats have been initialized"); 17312853Sgabeblack@google.com } 17412853Sgabeblack@google.com 17512853Sgabeblack@google.com if (data->print) { 17612853Sgabeblack@google.com if (data->name.empty()) 17712853Sgabeblack@google.com panic("all printable stats must be named"); 17812853Sgabeblack@google.com 17912853Sgabeblack@google.com list_t::iterator j = printStats.insert(printStats.end(), *i); 18012853Sgabeblack@google.com inplace_merge(printStats.begin(), j, 18112853Sgabeblack@google.com printStats.end(), Stat::less); 18212853Sgabeblack@google.com } 18312853Sgabeblack@google.com 18412853Sgabeblack@google.com ++i; 18512853Sgabeblack@google.com } 18612853Sgabeblack@google.com} 18712853Sgabeblack@google.com 18812853Sgabeblack@google.comvoid 18912853Sgabeblack@google.comDatabase::regStat(Stat *stat) 19012853Sgabeblack@google.com{ 19112853Sgabeblack@google.com if (map.find(stat) != map.end()) 19212853Sgabeblack@google.com panic("shouldn't register stat twice!"); 19312853Sgabeblack@google.com 19412853Sgabeblack@google.com allStats.push_back(stat); 19512853Sgabeblack@google.com 19612853Sgabeblack@google.com StatData *data = new StatData; 19712853Sgabeblack@google.com bool success = (map.insert(make_pair(stat, data))).second; 19812853Sgabeblack@google.com assert(map.find(stat) != map.end()); 19912853Sgabeblack@google.com assert(success && "this should never fail"); 20012853Sgabeblack@google.com} 20112853Sgabeblack@google.com 20212853Sgabeblack@google.combool 20312853Sgabeblack@google.comStat::less(Stat *stat1, Stat *stat2) 20412853Sgabeblack@google.com{ 20512853Sgabeblack@google.com const string &name1 = stat1->myname(); 20612853Sgabeblack@google.com const string &name2 = stat2->myname(); 20712853Sgabeblack@google.com 20812853Sgabeblack@google.com vector<string> v1; 209 vector<string> v2; 210 211 tokenize(v1, name1, '.'); 212 tokenize(v2, name2, '.'); 213 214 int last = min(v1.size(), v2.size()) - 1; 215 for (int i = 0; i < last; ++i) 216 if (v1[i] != v2[i]) 217 return v1[i] < v2[i]; 218 219 // Special compare for last element. 220 if (v1[last] == v2[last]) 221 return v1.size() < v2.size(); 222 else 223 return v1[last] < v2[last]; 224 225 return false; 226} 227 228StatData * 229Database::print(Stat *stat) 230{ 231 StatData *data = find(stat); 232 assert(data); 233 234 data->print = true; 235 236 return data; 237} 238 239Database & 240StatDB() 241{ 242 static Database db; 243 return db; 244} 245 246Stat::Stat(bool reg) 247{ 248#if 0 249 // This assert can help you find that pesky stat. 250 assert(this != (void *)0xbffff5c0); 251#endif 252 253 if (reg) 254 StatDB().regStat(this); 255#ifdef STAT_DEBUG 256 number = ++total_stats; 257 cprintf("I'm stat number %d\n",number); 258#endif 259} 260 261void 262Stat::setInit() 263{ mydata()->init = true; } 264 265StatData * 266Stat::mydata() 267{ 268 StatData *data = StatDB().find(this); 269 assert(data); 270 271 return data; 272} 273 274const StatData * 275Stat::mydata() const 276{ 277 StatData *data = StatDB().find(this); 278 assert(data); 279 280 return data; 281} 282 283const SubData * 284Stat::mysubdata(int index) const 285{ 286 assert(index >= 0); 287 if (index >= size()) 288 return NULL; 289 290 const StatData *data = this->mydata(); 291 if (!data->subdata || data->subdata->size() <= index) 292 return NULL; 293 294 return &(*data->subdata)[index]; 295} 296 297SubData * 298Stat::mysubdata_create(int index) 299{ 300 int size = this->size(); 301 assert(index >= 0 && (size == 0 || size > 0 && index < size)); 302 303 StatData *data = this->mydata(); 304 if (!data->subdata) { 305 if (!data->subdata) { 306 if (size == 0) 307 size = index + 1; 308 309 data->subdata = new vector<SubData>(size); 310 } 311 } else if (data->subdata->size() <= index) 312 data->subdata->resize(index + 1); 313 314 SubData *sd = &(*data->subdata)[index]; 315 assert(sd); 316 317 return sd; 318} 319 320string 321Stat::myname() const 322{ return mydata()->name; } 323 324string 325Stat::mysubname(int index) const 326{ 327 const SubData *sd = mysubdata(index); 328 return sd ? sd->name : ""; 329} 330 331string 332Stat::mydesc() const 333{ return mydata()->desc; } 334 335string 336Stat::mysubdesc(int index) const 337{ 338 const SubData *sd = mysubdata(index); 339 return sd ? sd->desc : ""; 340} 341 342int 343Stat::myprecision() const 344{ return mydata()->precision; } 345 346FormatFlags 347Stat::myflags() const 348{ return mydata()->flags; } 349 350bool 351Stat::dodisplay() const 352{ return !mydata()->prereq || !mydata()->prereq->zero(); } 353 354StatData * 355Stat::print() 356{ 357 StatData *data = StatDB().print(this); 358 assert(data && data->init); 359 360 return data; 361} 362 363Stat & 364Stat::name(const string &name) 365{ 366 print()->name = name; 367 return *this; 368} 369 370Stat & 371Stat::desc(const string &desc) 372{ 373 print()->desc = desc; 374 return *this; 375} 376 377Stat & 378Stat::precision(int precision) 379{ 380 print()->precision = precision; 381 return *this; 382} 383 384Stat & 385Stat::flags(FormatFlags flags) 386{ 387 if (flags & __reserved) 388 panic("Cannot set reserved flags!\n"); 389 390 print()->flags |= flags; 391 return *this; 392} 393 394Stat & 395Stat::prereq(const Stat &prereq) 396{ 397 print()->prereq = &prereq; 398 return *this; 399} 400 401Stat & 402Stat::subname(int index, const string &name) 403{ 404 print(); 405 mysubdata_create(index)->name = name; 406 return *this; 407} 408Stat & 409Stat::subdesc(int index, const string &desc) 410{ 411 print(); 412 mysubdata_create(index)->desc = desc; 413 return *this; 414} 415 416bool 417ScalarStat::zero() const 418{ 419 return val() == 0.0; 420} 421 422bool 423VectorStat::zero() const 424{ 425 return val()[0] == 0.0; 426} 427 428string 429ValueToString(result_t value, int precision) 430{ 431 stringstream val; 432 433 if (!isnan(value)) { 434 if (precision != -1) 435 val.precision(precision); 436 else if (value == rint(value)) 437 val.precision(0); 438 439 val.unsetf(ios::showpoint); 440 val.setf(ios::fixed); 441 val << value; 442 } else { 443#ifndef STAT_DISPLAY_COMPAT 444 val << "no value"; 445#else 446 val << "<err: div-0>"; 447#endif 448 } 449 450 return val.str(); 451} 452 453void 454PrintOne(ostream &stream, result_t value, 455 const string &name, const string &desc, int precision, 456 FormatFlags flags, result_t pdf = NAN, result_t cdf = NAN) 457{ 458 if (flags & nozero && value == 0.0 || 459 flags & nonan && isnan(value)) 460 return; 461 462 stringstream pdfstr, cdfstr; 463 464 if (!isnan(pdf)) 465 ccprintf(pdfstr, "%.2f%%", pdf * 100.0); 466 467 if (!isnan(cdf)) 468 ccprintf(cdfstr, "%.2f%%", cdf * 100.0); 469 470#ifdef STAT_DISPLAY_COMPAT 471 if (flags & __substat) { 472 ccprintf(stream, "%32s%12s%10s%10s", name, 473 ValueToString(value, precision), 474 pdfstr, cdfstr); 475 } else 476#endif 477 { 478 ccprintf(stream, "%-40s%12s%10s%10s", name, 479 ValueToString(value, precision), pdfstr, cdfstr); 480 } 481 482 if (PrintDescriptions) { 483 if (!desc.empty()) 484 ccprintf(stream, " # %s", desc); 485 } 486 stream << endl; 487} 488 489void 490ScalarStat::display(ostream &stream) const 491{ 492 PrintOne(stream, val(), myname(), mydesc(), myprecision(), myflags()); 493} 494 495void 496VectorStat::display(ostream &stream) const 497{ 498 bool have_subname = false; 499 bool have_subdesc = false; 500 int size = this->size(); 501 for (int i = 0; i < size; ++i) { 502 if (!mysubname(i).empty()) 503 have_subname = true; 504 if (!mysubdesc(i).empty()) 505 have_subdesc = true; 506 } 507 508 vector<string> *subnames = 0; 509 vector<string> *subdescs = 0; 510 if (have_subname) { 511 subnames = new vector<string>(size); 512 for (int i = 0; i < size; ++i) 513 (*subnames)[i] = mysubname(i); 514 } 515 if (have_subdesc) { 516 subdescs = new vector<string>(size); 517 for (int i = 0; i < size; ++i) 518 (*subdescs)[i] = mysubdesc(i); 519 } 520 521 VectorDisplay(stream, myname(), subnames, mydesc(), subdescs, 522 myprecision(), myflags(), val(), total()); 523} 524 525#ifndef STAT_DISPLAY_COMPAT 526#define NAMESEP "::" 527#else 528#define NAMESEP "_" 529#endif 530 531#ifndef STAT_DISPLAY_COMPAT 532void 533VectorDisplay(std::ostream &stream, 534 const std::string &myname, 535 const std::vector<std::string> *mysubnames, 536 const std::string &mydesc, 537 const std::vector<std::string> *mysubdescs, 538 int myprecision, FormatFlags myflags, 539 const rvec_t &vec, result_t mytotal) 540{ 541 int _size = vec.size(); 542 result_t _total = 0.0; 543 result_t _pdf, _cdf = 0.0; 544 545 if (myflags & (pdf | cdf)) { 546 for (int i = 0; i < _size; ++i) { 547 _total += vec[i]; 548 } 549 } 550 551 if (_size == 1) { 552 PrintOne(stream, vec[0], myname, mydesc, myprecision, myflags); 553 } else { 554 for (int i = 0; i < _size; ++i) { 555 string subname; 556 if (mysubnames) { 557 subname = (*mysubnames)[i]; 558 if (subname.empty()) 559 continue; 560 } else { 561 subname = to_string(i); 562 } 563 564 string name = myname + NAMESEP + subname; 565 if (!(myflags & pdf)) 566 PrintOne(stream, vec[i], name, mydesc, myprecision, myflags); 567 else { 568 _pdf = vec[i] / _total; 569 _cdf += _pdf; 570 PrintOne(stream, vec[i], name, mydesc, myprecision, myflags, 571 _pdf, _cdf); 572 } 573 } 574 575 if (myflags & total) 576 PrintOne(stream, mytotal, myname + NAMESEP + "total", 577 mydesc, myprecision, myflags); 578 } 579} 580#else 581void 582VectorDisplay(std::ostream &stream, 583 const std::string &myname, 584 const std::vector<std::string> *mysubnames, 585 const std::string &mydesc, 586 const std::vector<std::string> *mysubdescs, 587 int myprecision, FormatFlags myflags, 588 const rvec_t &vec, result_t mytotal) 589{ 590 int _size = vec.size(); 591 result_t _total = 0.0; 592 result_t _pdf, _cdf = 0.0; 593 594 if (myflags & (pdf | cdf)) { 595 for (int i = 0; i < _size; ++i) { 596 _total += vec[i]; 597 } 598 } 599 600 if (_size == 1) { 601 PrintOne(stream, vec[0], myname, mydesc, myprecision, myflags); 602 } else { 603 if (myflags & total) 604 PrintOne(stream, mytotal, myname, mydesc, myprecision, myflags); 605 606 if (myflags & dist) { 607 ccprintf(stream, "%s.start_dist\n", myname); 608 for (int i = 0; i < _size; ++i) { 609 string subname, subdesc; 610 subname = to_string(i); 611 if (mysubnames) { 612 if (!subname.empty()) { 613 subname = (*mysubnames)[i]; 614 } 615 } 616 if (mysubdescs) { 617 subdesc = (*mysubdescs)[i]; 618 } 619 if (!(myflags & (pdf | cdf))) { 620 PrintOne(stream, vec[i], subname, subdesc, myprecision, 621 myflags | __substat); 622 } else { 623 if (_total) { 624 _pdf = vec[i] / _total; 625 _cdf += _pdf; 626 } else { 627 _pdf = _cdf = 0.0; 628 } 629 if (!(myflags & cdf)) { 630 PrintOne(stream, vec[i], subname, subdesc, myprecision, 631 myflags | __substat, _pdf); 632 } else { 633 PrintOne(stream, vec[i], subname, subdesc, myprecision, 634 myflags | __substat, _pdf, _cdf); 635 } 636 } 637 } 638 ccprintf(stream, "%s.end_dist\n", myname); 639 } else { 640 for (int i = 0; i < _size; ++i) { 641 string subname; 642 if (mysubnames) { 643 subname = (*mysubnames)[i]; 644 if (subname.empty()) 645 continue; 646 } else { 647 subname = to_string(i); 648 } 649 650 string name = myname + NAMESEP + subname; 651 if (!(myflags & pdf)) { 652 PrintOne(stream, vec[i], name, mydesc, myprecision, 653 myflags); 654 } else { 655 if (_total) { 656 _pdf = vec[i] / _total; 657 _cdf += _pdf; 658 } else { 659 _pdf = _cdf = 0.0; 660 } 661 _pdf = vec[i] / _total; 662 _cdf += _pdf; 663 PrintOne(stream, vec[i], name, mydesc, myprecision, 664 myflags, _pdf, _cdf); 665 } 666 } 667 } 668 } 669} 670#endif 671 672#ifndef STAT_DISPLAY_COMPAT 673void 674DistDisplay(ostream &stream, const string &name, const string &desc, 675 int precision, FormatFlags flags, 676 result_t min_val, result_t max_val, 677 result_t underflow, result_t overflow, 678 const rvec_t &vec, int min, int max, int bucket_size, int size); 679{ 680 assert(size == vec.size()); 681 682 result_t total = 0.0; 683 result_t pdf, cdf = 0.0; 684 685 total += underflow; 686 for (int i = 0; i < size; ++i) 687 total += vec[i]; 688 total += overflow; 689 690 pdf = underflow / total; 691 cdf += pdf; 692 693 PrintOne(stream, underflow, name + NAMESEP + "underflow", desc, 694 precision, myflags, pdf, cdf); 695 696 for (int i = 0; i < size; ++i) { 697 stringstream namestr; 698 namestr << name; 699 700 int low = i * bucket_size + min; 701 int high = ::std::min((i + 1) * bucket_size + min - 1, max); 702 namestr << low; 703 if (low < high) 704 namestr << "-" << high; 705 706 pdf = vec[i] / total; 707 cdf += pdf; 708 PrintOne(stream, vec[i], namestr.str(), desc, precision, myflags, 709 pdf, cdf); 710 } 711 712 pdf = overflow / total; 713 cdf += pdf; 714 PrintOne(stream, overflow, name + NAMESEP + "overflow", desc, 715 precision, myflags, pdf, cdf); 716 PrintOne(stream, total, name + NAMESEP + "total", desc, 717 precision, myflags); 718} 719#else 720void 721DistDisplay(ostream &stream, const string &name, const string &desc, 722 int precision, FormatFlags flags, 723 result_t min_val, result_t max_val, 724 result_t underflow, result_t overflow, 725 const rvec_t &vec, int min, int max, int bucket_size, int size) 726{ 727 assert(size == vec.size()); 728 string blank; 729 730 result_t total = 0.0; 731 732 total += underflow; 733 for (int i = 0; i < size; ++i) 734 total += vec[i]; 735 total += overflow; 736 737 ccprintf(stream, "%-42s", name + ".start_dist"); 738 if (PrintDescriptions && !desc.empty()) 739 ccprintf(stream, " # %s", desc); 740 stream << endl; 741 742 PrintOne(stream, total, name + ".samples", blank, precision, flags); 743 PrintOne(stream, min_val, name + ".min_value", blank, precision, flags); 744 745 if (underflow > 0) 746 PrintOne(stream, min_val, name + ".underflows", blank, precision, 747 flags); 748 749 int _min; 750 result_t _pdf, _cdf, mypdf, mycdf; 751 752 _cdf = 0.0; 753 for (int i = 0; i < size; ++i) { 754 if (flags & nozero && vec[i] == 0.0 || 755 flags & nonan && isnan(vec[i])) 756 return; 757 758 _min = i * bucket_size + min; 759 _pdf = vec[i] / total * 100.0; 760 _cdf += _pdf; 761 762 mypdf = (flags & pdf) ? _pdf : NAN; 763 mycdf = (flags & cdf) ? _cdf : NAN; 764 765 PrintOne(stream, vec[i], ValueToString(_min, 0), blank, precision, 766 flags | __substat, mypdf, mycdf); 767 } 768 769 if (overflow > 0) 770 PrintOne(stream, overflow, name + ".overflows", blank, precision, 771 flags); 772 PrintOne(stream, max_val, name + ".max_value", blank, precision, flags); 773 ccprintf(stream, "%s.end_dist\n\n", name); 774} 775#endif 776 777void 778FancyDisplay(ostream &stream, const string &name, const string &desc, 779 int precision, FormatFlags flags, result_t mean, 780 result_t variance) 781{ 782 result_t stdev = isnan(variance) ? NAN : sqrt(variance); 783 PrintOne(stream, mean, name + NAMESEP + "mean", desc, precision, flags); 784 PrintOne(stream, stdev, name + NAMESEP + "stdev", desc, precision, flags); 785} 786 787BinBase::BinBase(size_t size) 788 : memsize(CeilPow2(size)), mem(NULL) 789{ 790} 791 792BinBase::~BinBase() 793{ 794 if (mem) 795 delete [] mem; 796} 797 798char * 799BinBase::memory() 800{ 801 if (!mem) { 802 mem = new char[memsize]; 803 memset(mem, 0, memsize); 804 } 805 806 return mem; 807} 808 809} // namespace Detail 810 811void 812check() 813{ 814 Detail::StatDB().check(); 815} 816 817void 818dump(ostream &stream) 819{ 820 Detail::StatDB().dump(stream); 821} 822 823} // namespace Statistics 824