statistics.cc revision 6001
12SN/A/* 21762SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert 292SN/A */ 302SN/A 312SN/A#include <iomanip> 32456SN/A#include <fstream> 332SN/A#include <list> 342SN/A#include <map> 356001Snate@binkert.org#include <set> 362SN/A#include <string> 372SN/A 38148SN/A#include "base/callback.hh" 3956SN/A#include "base/cprintf.hh" 405889Snate@binkert.org#include "base/debug.hh" 41441SN/A#include "base/hostinfo.hh" 4256SN/A#include "base/misc.hh" 4356SN/A#include "base/statistics.hh" 4456SN/A#include "base/str.hh" 45441SN/A#include "base/time.hh" 46433SN/A#include "base/trace.hh" 472SN/A 482SN/Ausing namespace std; 492SN/A 50729SN/Anamespace Stats { 51388SN/A 525887Snate@binkert.orgtypedef map<const void *, Info *> MapType; 535887Snate@binkert.org 545887Snate@binkert.org// We wrap these in a function to make sure they're built in time. 555887Snate@binkert.orglist<Info *> & 565887Snate@binkert.orgstatsList() 57388SN/A{ 585887Snate@binkert.org static list<Info *> the_list; 595887Snate@binkert.org return the_list; 60388SN/A} 61388SN/A 625887Snate@binkert.orgMapType & 635887Snate@binkert.orgstatsMap() 64441SN/A{ 655887Snate@binkert.org static MapType the_map; 665887Snate@binkert.org return the_map; 67441SN/A} 68441SN/A 69388SN/Avoid 705886Snate@binkert.orgInfoAccess::setInfo(Info *info) 71388SN/A{ 725887Snate@binkert.org if (statsMap().find(this) != statsMap().end()) 735887Snate@binkert.org panic("shouldn't register stat twice!"); 745887Snate@binkert.org 755887Snate@binkert.org statsList().push_back(info); 765887Snate@binkert.org 775887Snate@binkert.org#ifndef NDEBUG 785887Snate@binkert.org pair<MapType::iterator, bool> result = 795887Snate@binkert.org#endif 805887Snate@binkert.org statsMap().insert(make_pair(this, info)); 815887Snate@binkert.org assert(result.second && "this should never fail"); 825887Snate@binkert.org assert(statsMap().find(this) != statsMap().end()); 83388SN/A} 84388SN/A 85388SN/Avoid 865889Snate@binkert.orgInfoAccess::setParams(const StorageParams *params) 875889Snate@binkert.org{ 885889Snate@binkert.org info()->storageParams = params; 895889Snate@binkert.org} 905889Snate@binkert.org 915889Snate@binkert.orgvoid 925886Snate@binkert.orgInfoAccess::setInit() 93388SN/A{ 945886Snate@binkert.org info()->flags |= init; 95388SN/A} 96388SN/A 975886Snate@binkert.orgInfo * 985886Snate@binkert.orgInfoAccess::info() 99388SN/A{ 1005887Snate@binkert.org MapType::const_iterator i = statsMap().find(this); 1015887Snate@binkert.org assert(i != statsMap().end()); 1025887Snate@binkert.org return (*i).second; 103388SN/A} 104388SN/A 1055886Snate@binkert.orgconst Info * 1065886Snate@binkert.orgInfoAccess::info() const 1075886Snate@binkert.org{ 1085887Snate@binkert.org MapType::const_iterator i = statsMap().find(this); 1095887Snate@binkert.org assert(i != statsMap().end()); 1105887Snate@binkert.org return (*i).second; 1115886Snate@binkert.org} 1125886Snate@binkert.org 1135889Snate@binkert.orgStorageParams::~StorageParams() 1145889Snate@binkert.org{ 1155889Snate@binkert.org} 1165889Snate@binkert.org 1175889Snate@binkert.orgint Info::id_count = 0; 1185889Snate@binkert.org 1195889Snate@binkert.orgint debug_break_id = -1; 1205889Snate@binkert.org 1215886Snate@binkert.orgInfo::Info() 1225889Snate@binkert.org : flags(none), precision(-1), prereq(0), storageParams(NULL) 123582SN/A{ 1245889Snate@binkert.org id = id_count++; 1255889Snate@binkert.org if (debug_break_id >= 0 and debug_break_id == id) 1265889Snate@binkert.org debug_break(); 127582SN/A} 128582SN/A 1295886Snate@binkert.orgInfo::~Info() 130388SN/A{ 131388SN/A} 132388SN/A 1332SN/Abool 1345886Snate@binkert.orgInfo::less(Info *stat1, Info *stat2) 1352SN/A{ 136388SN/A const string &name1 = stat1->name; 137388SN/A const string &name2 = stat2->name; 1382SN/A 1392SN/A vector<string> v1; 1402SN/A vector<string> v2; 1412SN/A 1422SN/A tokenize(v1, name1, '.'); 1432SN/A tokenize(v2, name2, '.'); 1442SN/A 1455599Snate@binkert.org size_type last = min(v1.size(), v2.size()) - 1; 1465599Snate@binkert.org for (off_type i = 0; i < last; ++i) 1472SN/A if (v1[i] != v2[i]) 1482SN/A return v1[i] < v2[i]; 1492SN/A 1502SN/A // Special compare for last element. 1512SN/A if (v1[last] == v2[last]) 1522SN/A return v1.size() < v2.size(); 1532SN/A else 1542SN/A return v1[last] < v2[last]; 1552SN/A 1562SN/A return false; 1572SN/A} 1582SN/A 159388SN/Abool 1605886Snate@binkert.orgInfo::baseCheck() const 1612SN/A{ 1626000Snate@binkert.org if (!(flags & Stats::init)) { 163582SN/A#ifdef DEBUG 164695SN/A cprintf("this is stat number %d\n", id); 165388SN/A#endif 166388SN/A panic("Not all stats have been initialized"); 167388SN/A return false; 168388SN/A } 1692SN/A 170434SN/A if ((flags & print) && name.empty()) { 171388SN/A panic("all printable stats must be named"); 172388SN/A return false; 173388SN/A } 1742SN/A 175388SN/A return true; 1762SN/A} 1772SN/A 1786001Snate@binkert.orgvoid 1796001Snate@binkert.orgInfo::enable() 1806001Snate@binkert.org{ 1816001Snate@binkert.org} 1826001Snate@binkert.org 1836001Snate@binkert.orgvoid 1846001Snate@binkert.orgVectorInfoBase::enable() 1856001Snate@binkert.org{ 1866001Snate@binkert.org size_type s = size(); 1876001Snate@binkert.org if (subnames.size() < s) 1886001Snate@binkert.org subnames.resize(s); 1896001Snate@binkert.org if (subdescs.size() < s) 1906001Snate@binkert.org subdescs.resize(s); 1916001Snate@binkert.org} 1926001Snate@binkert.org 1936001Snate@binkert.orgvoid 1946001Snate@binkert.orgVectorDistInfoBase::enable() 1956001Snate@binkert.org{ 1966001Snate@binkert.org size_type s = size(); 1976001Snate@binkert.org if (subnames.size() < s) 1986001Snate@binkert.org subnames.resize(s); 1996001Snate@binkert.org if (subdescs.size() < s) 2006001Snate@binkert.org subdescs.resize(s); 2016001Snate@binkert.org} 2026001Snate@binkert.org 2036001Snate@binkert.orgvoid 2046001Snate@binkert.orgVector2dInfoBase::enable() 2056001Snate@binkert.org{ 2066001Snate@binkert.org if (subnames.size() < x) 2076001Snate@binkert.org subnames.resize(x); 2086001Snate@binkert.org if (subdescs.size() < x) 2096001Snate@binkert.org subdescs.resize(x); 2106001Snate@binkert.org if (y_subnames.size() < y) 2116001Snate@binkert.org y_subnames.resize(y); 2126001Snate@binkert.org} 213695SN/A 214388SN/AFormula::Formula() 215388SN/A{ 216388SN/A setInit(); 217388SN/A} 218388SN/A 219388SN/AFormula::Formula(Temp r) 220388SN/A{ 221388SN/A root = r; 222388SN/A assert(size()); 223388SN/A} 224388SN/A 225388SN/Aconst Formula & 226388SN/AFormula::operator=(Temp r) 227388SN/A{ 228388SN/A assert(!root && "Can't change formulas"); 229388SN/A root = r; 230388SN/A assert(size()); 231388SN/A return *this; 232388SN/A} 233388SN/A 234388SN/Aconst Formula & 235388SN/AFormula::operator+=(Temp r) 236388SN/A{ 237388SN/A if (root) 238695SN/A root = NodePtr(new BinaryNode<std::plus<Result> >(root, r)); 239388SN/A else 240388SN/A root = r; 241388SN/A assert(size()); 242388SN/A return *this; 243388SN/A} 244388SN/A 245142SN/Avoid 2466000Snate@binkert.orgFormula::result(VResult &vec) const 2476000Snate@binkert.org{ 2486000Snate@binkert.org if (root) 2496000Snate@binkert.org vec = root->result(); 2506000Snate@binkert.org} 2516000Snate@binkert.org 2526000Snate@binkert.orgResult 2536000Snate@binkert.orgFormula::total() const 2546000Snate@binkert.org{ 2556000Snate@binkert.org return root ? root->total() : 0.0; 2566000Snate@binkert.org} 2576000Snate@binkert.org 2586000Snate@binkert.orgsize_type 2596000Snate@binkert.orgFormula::size() const 2606000Snate@binkert.org{ 2616000Snate@binkert.org if (!root) 2626000Snate@binkert.org return 0; 2636000Snate@binkert.org else 2646000Snate@binkert.org return root->size(); 2656000Snate@binkert.org} 2666000Snate@binkert.org 2676000Snate@binkert.orgvoid 2686000Snate@binkert.orgFormula::reset() 2696000Snate@binkert.org{ 2706000Snate@binkert.org} 2716000Snate@binkert.org 2726000Snate@binkert.orgbool 2736000Snate@binkert.orgFormula::zero() const 2746000Snate@binkert.org{ 2756000Snate@binkert.org VResult vec; 2766000Snate@binkert.org result(vec); 2776000Snate@binkert.org for (off_t i = 0; i < vec.size(); ++i) 2786000Snate@binkert.org if (vec[i] != 0.0) 2796000Snate@binkert.org return false; 2806000Snate@binkert.org return true; 2816000Snate@binkert.org} 2826000Snate@binkert.org 2836000Snate@binkert.orgstring 2846000Snate@binkert.orgFormula::str() const 2856000Snate@binkert.org{ 2866000Snate@binkert.org return root ? root->str() : ""; 2876000Snate@binkert.org} 2886000Snate@binkert.org 2896000Snate@binkert.orgvoid 2906001Snate@binkert.orgenable() 2912SN/A{ 2925887Snate@binkert.org typedef list<Info *>::iterator iter_t; 293695SN/A 2945887Snate@binkert.org iter_t i, end = statsList().end(); 2955887Snate@binkert.org for (i = statsList().begin(); i != end; ++i) { 2965886Snate@binkert.org Info *info = *i; 2975886Snate@binkert.org assert(info); 2985886Snate@binkert.org if (!info->check() || !info->baseCheck()) 2995889Snate@binkert.org panic("stat check failed for '%s' %d\n", info->name, info->id); 300695SN/A } 301695SN/A 3025599Snate@binkert.org off_t j = 0; 3035887Snate@binkert.org for (i = statsList().begin(); i != end; ++i) { 3045886Snate@binkert.org Info *info = *i; 3055886Snate@binkert.org if (!(info->flags & print)) 3065886Snate@binkert.org info->name = "__Stat" + to_string(j++); 307695SN/A } 308695SN/A 3095887Snate@binkert.org statsList().sort(Info::less); 310695SN/A 3116001Snate@binkert.org for (i = statsList().begin(); i != end; ++i) { 3126001Snate@binkert.org Info *info = *i; 3136001Snate@binkert.org info->enable(); 3146001Snate@binkert.org } 3156001Snate@binkert.org} 316695SN/A 3176001Snate@binkert.orgvoid 3186001Snate@binkert.orgprepare() 3196001Snate@binkert.org{ 3206001Snate@binkert.org list<Info *>::iterator i = statsList().begin(); 3216001Snate@binkert.org list<Info *>::iterator end = statsList().end(); 3226001Snate@binkert.org while (i != end) { 3236001Snate@binkert.org Info *info = *i; 3246001Snate@binkert.org info->prepare(); 3256001Snate@binkert.org ++i; 326695SN/A } 3272SN/A} 3282SN/A 329695SN/ACallbackQueue resetQueue; 3302SN/A 331456SN/Avoid 332695SN/Areset() 333456SN/A{ 3345887Snate@binkert.org list<Info *>::iterator i = statsList().begin(); 3355887Snate@binkert.org list<Info *>::iterator end = statsList().end(); 336695SN/A while (i != end) { 3375886Snate@binkert.org Info *info = *i; 3385886Snate@binkert.org info->reset(); 339695SN/A ++i; 340695SN/A } 341695SN/A 342695SN/A resetQueue.process(); 343456SN/A} 344456SN/A 345456SN/Avoid 346394SN/AregisterResetCallback(Callback *cb) 347148SN/A{ 348148SN/A resetQueue.add(cb); 349148SN/A} 350148SN/A 351729SN/A/* namespace Stats */ } 352