statistics.cc revision 388
12817Sksewell@umich.edu/* 22817Sksewell@umich.edu * Copyright (c) 2003 The Regents of The University of Michigan 32817Sksewell@umich.edu * All rights reserved. 42817Sksewell@umich.edu * 52817Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without 62817Sksewell@umich.edu * modification, are permitted provided that the following conditions are 72817Sksewell@umich.edu * met: redistributions of source code must retain the above copyright 82817Sksewell@umich.edu * notice, this list of conditions and the following disclaimer; 92817Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright 102817Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the 112817Sksewell@umich.edu * documentation and/or other materials provided with the distribution; 122817Sksewell@umich.edu * neither the name of the copyright holders nor the names of its 132817Sksewell@umich.edu * contributors may be used to endorse or promote products derived from 142817Sksewell@umich.edu * this software without specific prior written permission. 152817Sksewell@umich.edu * 162817Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172817Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182817Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192817Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202817Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212817Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222817Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232817Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242817Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252817Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262817Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272817Sksewell@umich.edu */ 282817Sksewell@umich.edu 292817Sksewell@umich.edu#include <iomanip> 302817Sksewell@umich.edu#include <iostream> 312817Sksewell@umich.edu#include <list> 322817Sksewell@umich.edu#include <map> 332817Sksewell@umich.edu#include <string> 342935Sksewell@umich.edu#include <sstream> 352817Sksewell@umich.edu 362817Sksewell@umich.edu#include "base/callback.hh" 372834Sksewell@umich.edu#include "base/cprintf.hh" 382834Sksewell@umich.edu#include "base/misc.hh" 392834Sksewell@umich.edu#include "base/statistics.hh" 402834Sksewell@umich.edu#include "base/str.hh" 412834Sksewell@umich.edu#include "sim/universe.hh" 422834Sksewell@umich.edu 432834Sksewell@umich.edu#ifdef __M5_NAN 442817Sksewell@umich.edufloat 452817Sksewell@umich.edu__nan() 462817Sksewell@umich.edu{ 472817Sksewell@umich.edu union { 482817Sksewell@umich.edu uint32_t ui; 492817Sksewell@umich.edu float f; 502817Sksewell@umich.edu } nan; 512817Sksewell@umich.edu 522817Sksewell@umich.edu nan.ui = 0x7fc00000; 532817Sksewell@umich.edu return nan.f; 542817Sksewell@umich.edu} 552817Sksewell@umich.edu#endif 562817Sksewell@umich.edu 572817Sksewell@umich.edu#ifdef STAT_DEBUG 582817Sksewell@umich.edustatic int total_stats = 0; 592817Sksewell@umich.edu#endif 602817Sksewell@umich.edu 612817Sksewell@umich.eduusing namespace std; 622817Sksewell@umich.edu 632817Sksewell@umich.edu// This is a hack to get this parameter from the old stats package. 642817Sksewell@umich.edunamespace Statistics { 652817Sksewell@umich.edubool PrintDescriptions = true; 662817Sksewell@umich.eduDisplayMode default_mode = mode_simplescalar; 672817Sksewell@umich.edu 682817Sksewell@umich.edunamespace Database 693784Sgblack@eecs.umich.edu{ 703789Sgblack@eecs.umich.edu class Data 713784Sgblack@eecs.umich.edu { 723784Sgblack@eecs.umich.edu private: 733789Sgblack@eecs.umich.edu typedef list<StatData *> list_t; 743784Sgblack@eecs.umich.edu typedef map<void *, StatData *> map_t; 752817Sksewell@umich.edu 762817Sksewell@umich.edu list<MainBin *> bins; 772817Sksewell@umich.edu map<const MainBin *, string > bin_names; 782817Sksewell@umich.edu list_t binnedStats; 795712Shsul@eecs.umich.edu 802817Sksewell@umich.edu list_t allStats; 815714Shsul@eecs.umich.edu list_t printStats; 825714Shsul@eecs.umich.edu map_t statMap; 835714Shsul@eecs.umich.edu 845714Shsul@eecs.umich.edu public: 852817Sksewell@umich.edu void dump(ostream &stream); 862817Sksewell@umich.edu 872817Sksewell@umich.edu StatData *find(void *stat); 882817Sksewell@umich.edu void mapStat(void *stat, StatData *data); 892817Sksewell@umich.edu 902817Sksewell@umich.edu void check(); 912817Sksewell@umich.edu void reset(); 922817Sksewell@umich.edu void regBin(MainBin *bin, string name); 933548Sgblack@eecs.umich.edu void regPrint(void *stat); 942817Sksewell@umich.edu }; 952817Sksewell@umich.edu 962817Sksewell@umich.edu 972817Sksewell@umich.eduvoid 985499Ssaidi@eecs.umich.eduData::dump(ostream &stream) 993675Sktlim@umich.edu{ 1005497Ssaidi@eecs.umich.edu#ifndef FS_MEASURE 1012817Sksewell@umich.edu list_t::iterator i = printStats.begin(); 1022817Sksewell@umich.edu list_t::iterator end = printStats.end(); 1032817Sksewell@umich.edu while (i != end) { 1042817Sksewell@umich.edu StatData *stat = *i; 1052817Sksewell@umich.edu if (stat->binned()) 1062817Sksewell@umich.edu binnedStats.push_back(stat); 1072817Sksewell@umich.edu ++i; 1082817Sksewell@umich.edu } 1092817Sksewell@umich.edu#endif //FS_MEASURE 1102817Sksewell@umich.edu 1112817Sksewell@umich.edu list<MainBin *>::iterator j = bins.begin(); 1122817Sksewell@umich.edu list<MainBin *>::iterator bins_end=bins.end(); 1132817Sksewell@umich.edu 1142817Sksewell@umich.edu if (!bins.empty()) { 1152817Sksewell@umich.edu ccprintf(stream, "PRINTING BINNED STATS\n"); 1162817Sksewell@umich.edu while (j != bins_end) { 1172817Sksewell@umich.edu (*j)->activate(); 1182817Sksewell@umich.edu map<const MainBin *, string>::const_iterator iter; 1195250Sksewell@umich.edu iter = bin_names.find(*j); 1202817Sksewell@umich.edu if (iter == bin_names.end()) 1212817Sksewell@umich.edu panic("a binned stat not found in names map!"); 1222875Sksewell@umich.edu ccprintf(stream,"---%s Bin------------\n", (*iter).second); 1232817Sksewell@umich.edu 1242817Sksewell@umich.edu#ifdef FS_MEASURE 1255250Sksewell@umich.edu list_t::iterator i = printStats.begin(); 1262817Sksewell@umich.edu list_t::iterator end = printStats.end(); 1272817Sksewell@umich.edu#else 1282817Sksewell@umich.edu list_t::iterator i = binnedStats.begin(); 1292817Sksewell@umich.edu list_t::iterator end = binnedStats.end(); 1302817Sksewell@umich.edu#endif 1312817Sksewell@umich.edu while (i != end) { 1322817Sksewell@umich.edu StatData *stat = *i; 1332817Sksewell@umich.edu if (stat->dodisplay()) 1342817Sksewell@umich.edu stat->display(stream); 1352817Sksewell@umich.edu ++i; 1362817Sksewell@umich.edu } 1372817Sksewell@umich.edu ++j; 1382817Sksewell@umich.edu ccprintf(stream, "---------------------------------\n"); 1392817Sksewell@umich.edu } 1402817Sksewell@umich.edu#ifndef FS_MEASURE 1412817Sksewell@umich.edu ccprintf(stream, "**************ALL STATS************\n"); 1422817Sksewell@umich.edu#endif 1432817Sksewell@umich.edu } 1442817Sksewell@umich.edu 1452817Sksewell@umich.edu/** 1462817Sksewell@umich.edu * get bin totals working, then print the stat here (as total), even if 1472817Sksewell@umich.edu * its' binned. (this is only for the case you selectively bin a few stats 1482817Sksewell@umich.edu */ 1492817Sksewell@umich.edu#ifndef FS_MEASURE 1502817Sksewell@umich.edu list_t::iterator k = printStats.begin(); 1512817Sksewell@umich.edu list_t::iterator endprint = printStats.end(); 1522817Sksewell@umich.edu while (k != endprint) { 1532817Sksewell@umich.edu StatData *stat = *k; 1542817Sksewell@umich.edu if (stat->dodisplay() /*&& !stat->binned()*/) 1552817Sksewell@umich.edu stat->display(stream); 1562817Sksewell@umich.edu ++k; 1572817Sksewell@umich.edu } 1582817Sksewell@umich.edu#endif 1592817Sksewell@umich.edu} 1602817Sksewell@umich.edu 1612817Sksewell@umich.eduStatData * 1622817Sksewell@umich.eduData::find(void *stat) 1632817Sksewell@umich.edu{ 1642817Sksewell@umich.edu map_t::const_iterator i = statMap.find(stat); 1652817Sksewell@umich.edu 1662817Sksewell@umich.edu if (i == statMap.end()) 1672817Sksewell@umich.edu return NULL; 1682817Sksewell@umich.edu 1692817Sksewell@umich.edu return (*i).second; 1702817Sksewell@umich.edu} 1712817Sksewell@umich.edu 1722817Sksewell@umich.eduvoid 1732817Sksewell@umich.eduData::check() 1742817Sksewell@umich.edu{ 1752817Sksewell@umich.edu list_t::iterator i = allStats.begin(); 1762817Sksewell@umich.edu list_t::iterator end = allStats.end(); 1772817Sksewell@umich.edu 1782817Sksewell@umich.edu while (i != end) { 1792817Sksewell@umich.edu StatData *stat = *i; 1802817Sksewell@umich.edu assert(stat); 1812817Sksewell@umich.edu stat->check(); 1822817Sksewell@umich.edu ++i; 1832817Sksewell@umich.edu } 1842817Sksewell@umich.edu} 1852817Sksewell@umich.edu 1862817Sksewell@umich.eduvoid 1872817Sksewell@umich.eduData::reset() 1882817Sksewell@umich.edu{ 1892817Sksewell@umich.edu list_t::iterator i = allStats.begin(); 1902817Sksewell@umich.edu list_t::iterator end = allStats.end(); 1912817Sksewell@umich.edu while (i != end) { 1922817Sksewell@umich.edu StatData *stat = *i; 1932817Sksewell@umich.edu stat->reset(); 1942817Sksewell@umich.edu ++i; 1952817Sksewell@umich.edu } 1962817Sksewell@umich.edu 1972817Sksewell@umich.edu MainBin *orig = MainBin::curBin(); 1982817Sksewell@umich.edu 1992817Sksewell@umich.edu list<MainBin *>::iterator bi = bins.begin(); 2002817Sksewell@umich.edu list<MainBin *>::iterator be = bins.end(); 2012817Sksewell@umich.edu while (bi != be) { 2022817Sksewell@umich.edu MainBin *bin = *bi; 2032817Sksewell@umich.edu bin->activate(); 2042817Sksewell@umich.edu 2055259Sksewell@umich.edu i = allStats.begin(); 2065259Sksewell@umich.edu while (i != end) { 2075259Sksewell@umich.edu StatData *stat = *i; 2085259Sksewell@umich.edu stat->reset(); 2095259Sksewell@umich.edu ++i; 2105259Sksewell@umich.edu } 2115259Sksewell@umich.edu ++bi; 2125259Sksewell@umich.edu } 2135259Sksewell@umich.edu 2145259Sksewell@umich.edu if (orig) 2152817Sksewell@umich.edu orig->activate(); 2164172Ssaidi@eecs.umich.edu} 2174172Ssaidi@eecs.umich.edu 2184172Ssaidi@eecs.umich.eduvoid 2194172Ssaidi@eecs.umich.eduData::mapStat(void *stat, StatData *data) 2204172Ssaidi@eecs.umich.edu{ 2212817Sksewell@umich.edu if (statMap.find(stat) != statMap.end()) 2222817Sksewell@umich.edu panic("shouldn't register stat twice!"); 2232817Sksewell@umich.edu 2242817Sksewell@umich.edu allStats.push_back(data); 2254172Ssaidi@eecs.umich.edu 2262817Sksewell@umich.edu bool success = (statMap.insert(make_pair(stat, data))).second; 2272817Sksewell@umich.edu assert(statMap.find(stat) != statMap.end()); 2282817Sksewell@umich.edu assert(success && "this should never fail"); 2294172Ssaidi@eecs.umich.edu} 2302817Sksewell@umich.edu 2312817Sksewell@umich.eduvoid 2322817Sksewell@umich.eduData::regBin(MainBin *bin, string name) 2332817Sksewell@umich.edu{ 2342817Sksewell@umich.edu if (bin_names.find(bin) != bin_names.end()) 2352817Sksewell@umich.edu panic("shouldn't register bin twice"); 2362817Sksewell@umich.edu 2372817Sksewell@umich.edu bins.push_back(bin); 2382817Sksewell@umich.edu 2392817Sksewell@umich.edu bool success = (bin_names.insert(make_pair(bin,name))).second; 2402817Sksewell@umich.edu assert(bin_names.find(bin) != bin_names.end()); 2412817Sksewell@umich.edu assert(success && "this should not fail"); 2422817Sksewell@umich.edu 2432817Sksewell@umich.edu cprintf("registering %s\n", name); 2442817Sksewell@umich.edu} 2452817Sksewell@umich.edu 2462817Sksewell@umich.eduvoid 2472817Sksewell@umich.eduData::regPrint(void *stat) 2482817Sksewell@umich.edu{ 2492817Sksewell@umich.edu StatData *data = find(stat); 2502817Sksewell@umich.edu 2512817Sksewell@umich.edu if (!data->print) { 2522817Sksewell@umich.edu data->print = true; 2532817Sksewell@umich.edu 2542817Sksewell@umich.edu list_t::iterator j = printStats.insert(printStats.end(), data); 2552817Sksewell@umich.edu inplace_merge(printStats.begin(), j, 2562817Sksewell@umich.edu printStats.end(), StatData::less); 2572817Sksewell@umich.edu } 2582817Sksewell@umich.edu 2592817Sksewell@umich.edu} 2602817Sksewell@umich.edu 2612817Sksewell@umich.eduData & 2622817Sksewell@umich.eduStatDB() 2632817Sksewell@umich.edu{ 2645595Sgblack@eecs.umich.edu static Data db; 2655595Sgblack@eecs.umich.edu return db; 2665595Sgblack@eecs.umich.edu} 2675595Sgblack@eecs.umich.edu 2685595Sgblack@eecs.umich.edu} 2695595Sgblack@eecs.umich.edu 2702817Sksewell@umich.eduStatData * 2715595Sgblack@eecs.umich.eduDataAccess::find() const 2725595Sgblack@eecs.umich.edu{ 2735595Sgblack@eecs.umich.edu return Database::StatDB().find(const_cast<void *>((const void *)this)); 2745595Sgblack@eecs.umich.edu} 2755595Sgblack@eecs.umich.edu 2765595Sgblack@eecs.umich.eduvoid 2775595Sgblack@eecs.umich.eduDataAccess::map(StatData *data) 2785595Sgblack@eecs.umich.edu{ 2795595Sgblack@eecs.umich.edu Database::StatDB().mapStat(this, data); 2805595Sgblack@eecs.umich.edu} 2815595Sgblack@eecs.umich.edu 2825595Sgblack@eecs.umich.eduStatData * 2835595Sgblack@eecs.umich.eduDataAccess::statData() 2845595Sgblack@eecs.umich.edu{ 2855595Sgblack@eecs.umich.edu StatData *ptr = find(); 2865595Sgblack@eecs.umich.edu assert(ptr); 2875595Sgblack@eecs.umich.edu return ptr; 2885595Sgblack@eecs.umich.edu} 2895595Sgblack@eecs.umich.edu 2905595Sgblack@eecs.umich.educonst StatData * 2915595Sgblack@eecs.umich.eduDataAccess::statData() const 2925595Sgblack@eecs.umich.edu{ 2935595Sgblack@eecs.umich.edu const StatData *ptr = find(); 2945595Sgblack@eecs.umich.edu assert(ptr); 2955595Sgblack@eecs.umich.edu return ptr; 2965595Sgblack@eecs.umich.edu} 2975595Sgblack@eecs.umich.edu 2985595Sgblack@eecs.umich.eduvoid 2995595Sgblack@eecs.umich.eduDataAccess::setInit() 3002817Sksewell@umich.edu{ 3012817Sksewell@umich.edu statData()->init = true; 3022817Sksewell@umich.edu} 303 304void 305DataAccess::setPrint() 306{ 307 Database::StatDB().regPrint(this); 308} 309 310StatData::~StatData() 311{ 312} 313 314bool 315StatData::less(StatData *stat1, StatData *stat2) 316{ 317 const string &name1 = stat1->name; 318 const string &name2 = stat2->name; 319 320 vector<string> v1; 321 vector<string> v2; 322 323 tokenize(v1, name1, '.'); 324 tokenize(v2, name2, '.'); 325 326 int last = min(v1.size(), v2.size()) - 1; 327 for (int i = 0; i < last; ++i) 328 if (v1[i] != v2[i]) 329 return v1[i] < v2[i]; 330 331 // Special compare for last element. 332 if (v1[last] == v2[last]) 333 return v1.size() < v2.size(); 334 else 335 return v1[last] < v2[last]; 336 337 return false; 338} 339 340bool 341StatData::check() const 342{ 343 if (!init) { 344#ifdef STAT_DEBUG 345 cprintf("this is stat number %d\n",(*i)->number); 346#endif 347 panic("Not all stats have been initialized"); 348 return false; 349 } 350 351 if (print && name.empty()) { 352 panic("all printable stats must be named"); 353 return false; 354 } 355 356 return true; 357} 358 359string 360ValueToString(result_t value, DisplayMode mode, int precision) 361{ 362 stringstream val; 363 364 if (!isnan(value)) { 365 if (precision != -1) 366 val.precision(precision); 367 else if (value == rint(value)) 368 val.precision(0); 369 370 val.unsetf(ios::showpoint); 371 val.setf(ios::fixed); 372 val << value; 373 } else { 374 val << (mode == mode_m5 ? "no value" : "<err: div-0>"); 375 } 376 377 return val.str(); 378} 379 380struct ScalarPrint 381{ 382 result_t value; 383 string name; 384 string desc; 385 int precision; 386 DisplayMode mode; 387 FormatFlags flags; 388 result_t pdf; 389 result_t cdf; 390 391 ScalarPrint() 392 : value(0.0), precision(0), mode(default_mode), flags(0), 393 pdf(NAN), cdf(NAN) 394 {} 395 396 void operator()(ostream &stream) const; 397}; 398 399void 400ScalarPrint::operator()(ostream &stream) const 401{ 402 if (flags & nozero && value == 0.0 || 403 flags & nonan && isnan(value)) 404 return; 405 406 stringstream pdfstr, cdfstr; 407 408 if (!isnan(pdf)) 409 ccprintf(pdfstr, "%.2f%%", pdf * 100.0); 410 411 if (!isnan(cdf)) 412 ccprintf(cdfstr, "%.2f%%", cdf * 100.0); 413 414 if (mode == mode_simplescalar && flags & __substat) { 415 ccprintf(stream, "%32s %12s %10s %10s", name, 416 ValueToString(value, mode, precision), 417 pdfstr, cdfstr); 418 } else { 419 ccprintf(stream, "%-40s %12s %10s %10s", name, 420 ValueToString(value, mode, precision), pdfstr, cdfstr); 421 } 422 423 if (PrintDescriptions) { 424 if (!desc.empty()) 425 ccprintf(stream, " # %s", desc); 426 } 427 stream << endl; 428} 429 430struct VectorPrint 431{ 432 string name; 433 string desc; 434 vector<string> subnames; 435 vector<string> subdescs; 436 int precision; 437 DisplayMode mode; 438 FormatFlags flags; 439 rvec_t vec; 440 result_t total; 441 442 VectorPrint() 443 : subnames(0), subdescs(0), precision(-1), mode(default_mode), 444 flags(0), total(NAN) 445 {} 446 447 void operator()(ostream &stream) const; 448}; 449 450void 451VectorPrint::operator()(std::ostream &stream) const 452{ 453 int _size = vec.size(); 454 result_t _total = 0.0; 455 456 if (flags & (pdf | cdf)) { 457 for (int i = 0; i < _size; ++i) { 458 _total += vec[i]; 459 } 460 } 461 462 string base = name + ((mode == mode_simplescalar) ? "_" : "::"); 463 464 ScalarPrint print; 465 print.name = name; 466 print.desc = desc; 467 print.precision = precision; 468 print.flags = flags; 469 470 bool havesub = !subnames.empty(); 471 472 if (_size == 1) { 473 print.value = vec[0]; 474 print(stream); 475 } else if (mode == mode_m5) { 476 for (int i = 0; i < _size; ++i) { 477 if (havesub && (i >= subnames.size() || subnames[i].empty())) 478 continue; 479 480 print.name = base + (havesub ? subnames[i] : to_string(i)); 481 print.desc = subdescs.empty() ? desc : subdescs[i]; 482 print.value = vec[i]; 483 484 if (_total && (flags & pdf)) { 485 print.pdf = vec[i] / _total; 486 print.cdf += print.pdf; 487 } 488 489 print(stream); 490 } 491 492 if (flags & ::Statistics::total) { 493 print.name = base + "total"; 494 print.desc = desc; 495 print.value = total; 496 print(stream); 497 } 498 } else { 499 if (flags & ::Statistics::total) { 500 print.value = total; 501 print(stream); 502 } 503 504 result_t _pdf = 0.0; 505 result_t _cdf = 0.0; 506 if (flags & dist) { 507 ccprintf(stream, "%s.start_dist\n", name); 508 for (int i = 0; i < _size; ++i) { 509 print.name = havesub ? subnames[i] : to_string(i); 510 print.desc = subdescs.empty() ? desc : subdescs[i]; 511 print.flags |= __substat; 512 print.value = vec[i]; 513 514 if (_total) { 515 _pdf = vec[i] / _total; 516 _cdf += _pdf; 517 } 518 519 if (flags & pdf) 520 print.pdf = _pdf; 521 if (flags & cdf) 522 print.cdf = _cdf; 523 524 print(stream); 525 } 526 ccprintf(stream, "%s.end_dist\n", name); 527 } else { 528 for (int i = 0; i < _size; ++i) { 529 if (havesub && subnames[i].empty()) 530 continue; 531 532 print.name = base; 533 print.name += havesub ? subnames[i] : to_string(i); 534 print.desc = subdescs.empty() ? desc : subdescs[i]; 535 print.value = vec[i]; 536 537 if (_total) { 538 _pdf = vec[i] / _total; 539 _cdf += _pdf; 540 } else { 541 _pdf = _cdf = NAN; 542 } 543 544 if (flags & pdf) { 545 print.pdf = _pdf; 546 print.cdf = _cdf; 547 } 548 549 print(stream); 550 } 551 } 552 } 553} 554 555struct DistPrint 556{ 557 string name; 558 string desc; 559 int precision; 560 DisplayMode mode; 561 FormatFlags flags; 562 563 result_t min_val; 564 result_t max_val; 565 result_t underflow; 566 result_t overflow; 567 rvec_t vec; 568 result_t sum; 569 result_t squares; 570 result_t samples; 571 572 int min; 573 int max; 574 int bucket_size; 575 int size; 576 bool fancy; 577 578 void operator()(ostream &stream) const; 579}; 580 581void 582DistPrint::operator()(ostream &stream) const 583{ 584 if (fancy) { 585 ScalarPrint print; 586 string base = name + ((mode == mode_m5) ? "::" : "_"); 587 588 print.precision = precision; 589 print.flags = flags; 590 print.desc = desc; 591 592 print.name = base + "mean"; 593 print.value = samples ? sum / samples : NAN; 594 print(stream); 595 596 print.name = base + "stdev"; 597 print.value = samples ? sqrt((samples * squares - sum * sum) / 598 (samples * (samples - 1.0))) : NAN; 599 print(stream); 600 601 print.name = "**Ignore: " + base + "TOT"; 602 print.value = samples; 603 print(stream); 604 return; 605 } 606 607 assert(size == vec.size()); 608 609 result_t total = 0.0; 610 611 total += underflow; 612 for (int i = 0; i < size; ++i) 613 total += vec[i]; 614 total += overflow; 615 616 string base = name + (mode == mode_m5 ? "::" : "."); 617 618 ScalarPrint print; 619 print.desc = (mode == mode_m5) ? desc : ""; 620 print.precision = precision; 621 print.mode = mode; 622 print.flags = flags; 623 624 if (mode == mode_simplescalar) { 625 ccprintf(stream, "%-42s", base + "start_dist"); 626 if (PrintDescriptions && !desc.empty()) 627 ccprintf(stream, " # %s", desc); 628 stream << endl; 629 } 630 631 print.name = base + "samples"; 632 print.value = samples; 633 print(stream); 634 635 print.name = base + "min_value"; 636 print.value = min_val; 637 print(stream); 638 639 if (mode == mode_m5 || underflow > 0.0) { 640 print.name = base + "underflows"; 641 print.value = underflow; 642 if (mode == mode_m5 && total) { 643 print.pdf = underflow / total; 644 print.cdf += print.pdf; 645 } 646 print(stream); 647 } 648 649 650 if (mode == mode_m5) { 651 for (int i = 0; i < size; ++i) { 652 stringstream namestr; 653 namestr << name; 654 655 int low = i * bucket_size + min; 656 int high = ::min((i + 1) * bucket_size + min - 1, max); 657 namestr << low; 658 if (low < high) 659 namestr << "-" << high; 660 661 print.name = namestr.str(); 662 print.value = vec[i]; 663 if (total) { 664 print.pdf = vec[i] / total; 665 print.cdf += print.pdf; 666 } 667 print(stream); 668 } 669 670 } else { 671 int _min; 672 result_t _pdf; 673 result_t _cdf = 0.0; 674 675 print.flags = flags | __substat; 676 677 for (int i = 0; i < size; ++i) { 678 if (flags & nozero && vec[i] == 0.0 || 679 flags & nonan && isnan(vec[i])) 680 continue; 681 682 _min = i * bucket_size + min; 683 _pdf = vec[i] / total * 100.0; 684 _cdf += _pdf; 685 686 687 print.name = ValueToString(_min, mode, 0); 688 print.value = vec[i]; 689 print.pdf = (flags & pdf) ? _pdf : NAN; 690 print.cdf = (flags & cdf) ? _cdf : NAN; 691 print(stream); 692 } 693 694 print.flags = flags; 695 if (flags & (pdf || cdf)) { 696 print.pdf = NAN; 697 print.cdf = NAN; 698 } 699 } 700 701 if (mode == mode_m5 || overflow > 0.0) { 702 print.name = base + "overflows"; 703 print.value = overflow; 704 if (mode == mode_m5 && total) { 705 print.pdf = overflow / total; 706 print.cdf += print.pdf; 707 } 708 print(stream); 709 } 710 711 print.pdf = NAN; 712 print.cdf = NAN; 713 714 if (mode != mode_simplescalar) { 715 print.name = base + "total"; 716 print.value = total; 717 print(stream); 718 } 719 720 print.name = base + "max_value"; 721 print.value = max_val; 722 print(stream); 723 724 if (mode != mode_simplescalar && samples != 0) { 725 print.name = base + "mean"; 726 print.value = sum / samples; 727 print(stream); 728 729 print.name = base + "stdev"; 730 print.value = sqrt((samples * squares - sum * sum) / 731 (samples * (samples - 1.0))); 732 print(stream); 733 } 734 735 if (mode == mode_simplescalar) 736 ccprintf(stream, "%send_dist\n\n", base); 737} 738 739void 740ScalarDataBase::display(ostream &stream) const 741{ 742 ScalarPrint print; 743 print.value = val(); 744 print.name = name; 745 print.desc = desc; 746 print.precision = precision; 747 print.flags = flags; 748 749 print(stream); 750} 751 752void 753VectorDataBase::display(ostream &stream) const 754{ 755 int size = this->size(); 756 const_cast<VectorDataBase *>(this)->update(); 757 758 VectorPrint print; 759 760 print.name = name; 761 print.desc = desc; 762 print.mode = mode; 763 print.flags = flags; 764 print.precision = precision; 765 print.vec = val(); 766 print.total = total(); 767 768 for (int i = 0; i < size; ++i) { 769 if (!subnames[i].empty()) { 770 print.subnames = subnames; 771 print.subnames.resize(size); 772 for (int i = 0; i < size; ++i) { 773 if (!subnames[i].empty() && !subdescs[i].empty()) { 774 print.subdescs = subdescs; 775 print.subdescs.resize(size); 776 break; 777 } 778 } 779 break; 780 } 781 } 782 783 784 print(stream); 785} 786 787void 788Vector2dDataBase::display(ostream &stream) const 789{ 790 const_cast<Vector2dDataBase *>(this)->update(); 791 792 bool havesub = false; 793 VectorPrint print; 794 795 print.subnames = y_subnames; 796 print.mode = mode; 797 print.flags = flags; 798 print.precision = precision; 799 800 if (!subnames.empty()) { 801 for (int i = 0; i < x; ++i) 802 if (!subnames[i].empty()) 803 havesub = true; 804 } 805 806 rvec_t tot_vec(y); 807 result_t super_total = 0.0; 808 for (int i = 0; i < x; ++i) { 809 if (havesub && (i >= subnames.size() || subnames[i].empty())) 810 continue; 811 812 int iy = i * y; 813 rvec_t yvec(y); 814 815 result_t total = 0.0; 816 for (int j = 0; j < y; ++j) { 817 yvec[j] = vec[iy + j]; 818 tot_vec[j] += yvec[j]; 819 total += yvec[j]; 820 super_total += yvec[j]; 821 } 822 823 print.name = name + "_" + (havesub ? subnames[i] : to_string(i)); 824 print.desc = desc; 825 print.vec = yvec; 826 print.total = total; 827 print(stream); 828 } 829 830 if ((flags & ::Statistics::total) && (x > 1)) { 831 print.name = name; 832 print.desc = desc; 833 print.vec = tot_vec; 834 print.total = super_total; 835 print(stream); 836 } 837} 838 839void 840DistDataBase::display(ostream &stream) const 841{ 842 const_cast<DistDataBase *>(this)->update(); 843 844 DistPrint print; 845 846 print.name = name; 847 print.desc = desc; 848 print.precision = precision; 849 print.mode = mode; 850 print.flags = flags; 851 852 print.min_val = data.min_val; 853 print.max_val = data.max_val; 854 print.underflow = data.underflow; 855 print.overflow = data.overflow; 856 print.vec = data.vec; 857 print.sum = data.sum; 858 print.squares = data.squares; 859 print.samples = data.samples; 860 861 print.min = data.min; 862 print.max = data.max; 863 print.bucket_size = data.bucket_size; 864 print.size = data.size; 865 print.fancy = data.fancy; 866 867 print(stream); 868} 869 870void 871VectorDistDataBase::display(ostream &stream) const 872{ 873 const_cast<VectorDistDataBase *>(this)->update(); 874 875 for (int i = 0; i < size(); ++i) { 876 DistPrint print; 877 878 print.name = name + 879 (subnames[i].empty() ? ("_" + to_string(i)) : subnames[i]); 880 print.desc = subdescs[i].empty() ? desc : subdescs[i]; 881 print.precision = precision; 882 print.mode = mode; 883 print.flags = flags; 884 885 print.min_val = data[i].min_val; 886 print.max_val = data[i].max_val; 887 print.underflow = data[i].underflow; 888 print.overflow = data[i].overflow; 889 print.vec = data[i].vec; 890 print.sum = data[i].sum; 891 print.squares = data[i].squares; 892 print.samples = data[i].samples; 893 894 print.min = data[i].min; 895 print.max = data[i].max; 896 print.bucket_size = data[i].bucket_size; 897 print.size = data[i].size; 898 print.fancy = data[i].fancy; 899 900 print(stream); 901 } 902} 903 904void 905FormulaBase::val(rvec_t &vec) const 906{ 907 vec = root->val(); 908} 909 910result_t 911FormulaBase::total() const 912{ 913 return root->total(); 914} 915 916size_t 917FormulaBase::size() const 918{ 919 if (!root) 920 return 0; 921 else 922 return root->size(); 923} 924 925bool 926FormulaBase::binned() const 927{ 928 return root->binned(); 929} 930 931void 932FormulaBase::reset() 933{ 934} 935 936bool 937FormulaBase::zero() const 938{ 939 rvec_t vec; 940 val(vec); 941 for (int i = 0; i < vec.size(); ++i) 942 if (vec[i] != 0.0) 943 return false; 944 return true; 945} 946 947void 948FormulaBase::update(StatData *) 949{ 950} 951 952Formula::Formula() 953{ 954 setInit(); 955} 956 957Formula::Formula(Temp r) 958{ 959 root = r; 960 assert(size()); 961} 962 963const Formula & 964Formula::operator=(Temp r) 965{ 966 assert(!root && "Can't change formulas"); 967 root = r; 968 assert(size()); 969 return *this; 970} 971 972const Formula & 973Formula::operator+=(Temp r) 974{ 975 if (root) 976 root = NodePtr(new BinaryNode<std::plus<result_t> >(root, r)); 977 else 978 root = r; 979 assert(size()); 980 return *this; 981} 982 983MainBin::MainBin(const string &name) 984 : _name(name), mem(NULL), memsize(-1) 985{ 986 Database::StatDB().regBin(this, name); 987} 988 989MainBin::~MainBin() 990{ 991 if (mem) 992 delete [] mem; 993} 994 995char * 996MainBin::memory(off_t off) 997{ 998 if (memsize == -1) 999 memsize = CeilPow2((size_t) offset()); 1000 1001 if (!mem) { 1002 mem = new char[memsize]; 1003 memset(mem, 0, memsize); 1004 } 1005 1006 assert(offset() <= size()); 1007 return mem + off; 1008} 1009 1010void 1011check() 1012{ 1013 Database::StatDB().check(); 1014} 1015 1016void 1017dump(ostream &stream) 1018{ 1019 Database::StatDB().dump(stream); 1020} 1021 1022CallbackQueue resetQueue; 1023 1024void 1025RegResetCallback(Callback *cb) 1026{ 1027 resetQueue.add(cb); 1028} 1029 1030void 1031reset() 1032{ 1033 Database::StatDB().reset(); 1034 resetQueue.process(); 1035} 1036 1037} // namespace Statistics 1038