statistics.cc revision 7831
1360SN/A/* 21458SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 3360SN/A * All rights reserved. 4360SN/A * 5360SN/A * Redistribution and use in source and binary forms, with or without 6360SN/A * modification, are permitted provided that the following conditions are 7360SN/A * met: redistributions of source code must retain the above copyright 8360SN/A * notice, this list of conditions and the following disclaimer; 9360SN/A * redistributions in binary form must reproduce the above copyright 10360SN/A * notice, this list of conditions and the following disclaimer in the 11360SN/A * documentation and/or other materials provided with the distribution; 12360SN/A * neither the name of the copyright holders nor the names of its 13360SN/A * contributors may be used to endorse or promote products derived from 14360SN/A * this software without specific prior written permission. 15360SN/A * 16360SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17360SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18360SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19360SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20360SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21360SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22360SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23360SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24360SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25360SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26360SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert 292665Ssaidi@eecs.umich.edu */ 30360SN/A 31360SN/A#include <iomanip> 322093SN/A#include <fstream> 33360SN/A#include <list> 34360SN/A#include <map> 356712Snate@binkert.org#include <string> 366712Snate@binkert.org 37360SN/A#include "base/callback.hh" 38360SN/A#include "base/cprintf.hh" 397680Sgblack@eecs.umich.edu#include "base/debug.hh" 402474SN/A#include "base/hostinfo.hh" 41360SN/A#include "base/misc.hh" 426658Snate@binkert.org#include "base/statistics.hh" 438229Snate@binkert.org#include "base/str.hh" 442680Sktlim@umich.edu#include "base/time.hh" 458232Snate@binkert.org#include "base/trace.hh" 462474SN/A 47360SN/Ausing namespace std; 488229Snate@binkert.org 498229Snate@binkert.orgnamespace Stats { 506029Ssteve.reinhardt@amd.com 51360SN/Atypedef map<const void *, Info *> MapType; 52360SN/A 532107SN/A// We wrap these in a function to make sure they're built in time. 54360SN/Alist<Info *> & 55360SN/AstatsList() 563114Sgblack@eecs.umich.edu{ 57360SN/A static list<Info *> the_list; 586702Sgblack@eecs.umich.edu return the_list; 596701Sgblack@eecs.umich.edu} 606702Sgblack@eecs.umich.edu 616111Ssteve.reinhardt@amd.comMapType & 626111Ssteve.reinhardt@amd.comstatsMap() 637823Ssteve.reinhardt@amd.com{ 646701Sgblack@eecs.umich.edu static MapType the_map; 656701Sgblack@eecs.umich.edu return the_map; 666701Sgblack@eecs.umich.edu} 676701Sgblack@eecs.umich.edu 68360SN/Avoid 692680Sktlim@umich.eduInfoAccess::setInfo(Info *info) 70360SN/A{ 712495SN/A if (statsMap().find(this) != statsMap().end()) 7210223Ssteve.reinhardt@amd.com panic("shouldn't register stat twice!"); 73360SN/A 741450SN/A statsList().push_back(info); 755958Sgblack@eecs.umich.edu 76360SN/A#ifndef NDEBUG 77360SN/A pair<MapType::iterator, bool> result = 78360SN/A#endif 791450SN/A statsMap().insert(make_pair(this, info)); 803114Sgblack@eecs.umich.edu assert(result.second && "this should never fail"); 812680Sktlim@umich.edu assert(statsMap().find(this) != statsMap().end()); 82360SN/A} 831969SN/A 842484SN/Avoid 852484SN/AInfoAccess::setParams(const StorageParams *params) 86360SN/A{ 87360SN/A info()->storageParams = params; 88360SN/A} 891450SN/A 903114Sgblack@eecs.umich.eduvoid 912680Sktlim@umich.eduInfoAccess::setInit() 92360SN/A{ 936701Sgblack@eecs.umich.edu info()->flags.set(init); 941969SN/A} 956701Sgblack@eecs.umich.edu 96360SN/AInfo * 971458SN/AInfoAccess::info() 98360SN/A{ 99360SN/A MapType::const_iterator i = statsMap().find(this); 100360SN/A assert(i != statsMap().end()); 1011450SN/A return (*i).second; 1028149SChris.Emmons@ARM.com} 1038149SChris.Emmons@ARM.com 1048149SChris.Emmons@ARM.comconst Info * 1058149SChris.Emmons@ARM.comInfoAccess::info() const 1068149SChris.Emmons@ARM.com{ 1078149SChris.Emmons@ARM.com MapType::const_iterator i = statsMap().find(this); 1088149SChris.Emmons@ARM.com assert(i != statsMap().end()); 1098149SChris.Emmons@ARM.com return (*i).second; 1108149SChris.Emmons@ARM.com} 1118149SChris.Emmons@ARM.com 1128149SChris.Emmons@ARM.comStorageParams::~StorageParams() 1138149SChris.Emmons@ARM.com{ 1143114Sgblack@eecs.umich.edu} 1152680Sktlim@umich.edu 116360SN/Atypedef map<std::string, Info *> NameMapType; 1176029Ssteve.reinhardt@amd.comNameMapType & 1186029Ssteve.reinhardt@amd.comnameMap() 1196701Sgblack@eecs.umich.edu{ 1205958Sgblack@eecs.umich.edu static NameMapType the_map; 1216701Sgblack@eecs.umich.edu return the_map; 1226029Ssteve.reinhardt@amd.com} 1236029Ssteve.reinhardt@amd.com 1246029Ssteve.reinhardt@amd.comint Info::id_count = 0; 1252834Sksewell@umich.edu 126360SN/Aint debug_break_id = -1; 1271458SN/A 128360SN/AInfo::Info() 129360SN/A : flags(none), precision(-1), prereq(0), storageParams(NULL) 130360SN/A{ 1311450SN/A id = id_count++; 1326109Ssanchezd@stanford.edu if (debug_break_id >= 0 and debug_break_id == id) 1336109Ssanchezd@stanford.edu debug_break(); 1346109Ssanchezd@stanford.edu} 1356109Ssanchezd@stanford.edu 1366109Ssanchezd@stanford.eduInfo::~Info() 1376701Sgblack@eecs.umich.edu{ 1386109Ssanchezd@stanford.edu} 1396701Sgblack@eecs.umich.edu 1406109Ssanchezd@stanford.eduvoid 1416109Ssanchezd@stanford.eduInfo::setName(const string &name) 1426109Ssanchezd@stanford.edu{ 1436109Ssanchezd@stanford.edu pair<NameMapType::iterator, bool> p = 1446109Ssanchezd@stanford.edu nameMap().insert(make_pair(name, this)); 1456109Ssanchezd@stanford.edu 1463114Sgblack@eecs.umich.edu Info *other = p.first->second; 147360SN/A bool result = p.second; 1482107SN/A 149360SN/A if (!result) { 150360SN/A // using other->name instead of just name to avoid a compiler 151360SN/A // warning. They should be the same. 1521450SN/A panic("same statistic name used twice! name=%s\n", other->name); 1535748SSteve.Reinhardt@amd.com } 154360SN/A 155360SN/A this->name = name; 1566701Sgblack@eecs.umich.edu} 1576701Sgblack@eecs.umich.edu 1585748SSteve.Reinhardt@amd.combool 1595748SSteve.Reinhardt@amd.comInfo::less(Info *stat1, Info *stat2) 1605748SSteve.Reinhardt@amd.com{ 1615748SSteve.Reinhardt@amd.com const string &name1 = stat1->name; 1625748SSteve.Reinhardt@amd.com const string &name2 = stat2->name; 1635748SSteve.Reinhardt@amd.com 1645748SSteve.Reinhardt@amd.com vector<string> v1; 1655748SSteve.Reinhardt@amd.com vector<string> v2; 1662474SN/A 1672474SN/A tokenize(v1, name1, '.'); 1685748SSteve.Reinhardt@amd.com tokenize(v2, name2, '.'); 1698601Ssteve.reinhardt@amd.com 1706687Stjones1@inf.ed.ac.uk size_type last = min(v1.size(), v2.size()) - 1; 1716687Stjones1@inf.ed.ac.uk for (off_type i = 0; i < last; ++i) 1726687Stjones1@inf.ed.ac.uk if (v1[i] != v2[i]) 1736687Stjones1@inf.ed.ac.uk return v1[i] < v2[i]; 1748852Sandreas.hansson@arm.com 1756687Stjones1@inf.ed.ac.uk // Special compare for last element. 1766687Stjones1@inf.ed.ac.uk if (v1[last] == v2[last]) 1776687Stjones1@inf.ed.ac.uk return v1.size() < v2.size(); 1786687Stjones1@inf.ed.ac.uk else 1798852Sandreas.hansson@arm.com return v1[last] < v2[last]; 1806687Stjones1@inf.ed.ac.uk 1816687Stjones1@inf.ed.ac.uk return false; 1826687Stjones1@inf.ed.ac.uk} 1836687Stjones1@inf.ed.ac.uk 1846687Stjones1@inf.ed.ac.ukbool 1858852Sandreas.hansson@arm.comInfo::baseCheck() const 1866687Stjones1@inf.ed.ac.uk{ 1876687Stjones1@inf.ed.ac.uk if (!(flags & Stats::init)) { 1882474SN/A#ifdef DEBUG 1891450SN/A cprintf("this is stat number %d\n", id); 1905748SSteve.Reinhardt@amd.com#endif 1915748SSteve.Reinhardt@amd.com panic("Not all stats have been initialized"); 1921458SN/A return false; 1931458SN/A } 194360SN/A 195360SN/A if ((flags & display) && name.empty()) { 196360SN/A panic("all printable stats must be named"); 1971450SN/A return false; 1983114Sgblack@eecs.umich.edu } 199360SN/A 2006701Sgblack@eecs.umich.edu return true; 2016701Sgblack@eecs.umich.edu} 2027508Stjones1@inf.ed.ac.uk 2037508Stjones1@inf.ed.ac.ukvoid 2047508Stjones1@inf.ed.ac.ukInfo::enable() 2057508Stjones1@inf.ed.ac.uk{ 2061970SN/A} 2071970SN/A 2081970SN/Avoid 209360SN/AVectorInfo::enable() 210360SN/A{ 211360SN/A size_type s = size(); 2121450SN/A if (subnames.size() < s) 2133114Sgblack@eecs.umich.edu subnames.resize(s); 214360SN/A if (subdescs.size() < s) 2156701Sgblack@eecs.umich.edu subdescs.resize(s); 2166701Sgblack@eecs.umich.edu} 2176701Sgblack@eecs.umich.edu 2186701Sgblack@eecs.umich.eduvoid 2196701Sgblack@eecs.umich.eduVectorDistInfo::enable() 220360SN/A{ 221360SN/A size_type s = size(); 222360SN/A if (subnames.size() < s) 223360SN/A subnames.resize(s); 2248706Sandreas.hansson@arm.com if (subdescs.size() < s) 225360SN/A subdescs.resize(s); 2261458SN/A} 227360SN/A 228360SN/Avoid 2291450SN/AVector2dInfo::enable() 2303114Sgblack@eecs.umich.edu{ 231360SN/A if (subnames.size() < x) 2326701Sgblack@eecs.umich.edu subnames.resize(x); 2336701Sgblack@eecs.umich.edu if (subdescs.size() < x) 2346701Sgblack@eecs.umich.edu subdescs.resize(x); 2356701Sgblack@eecs.umich.edu if (y_subnames.size() < y) 2366701Sgblack@eecs.umich.edu y_subnames.resize(y); 237360SN/A} 2388706Sandreas.hansson@arm.com 239360SN/Avoid 240360SN/AHistStor::grow_out() 241360SN/A{ 242360SN/A int size = cvec.size(); 243360SN/A int zero = size / 2; // round down! 2441458SN/A int top_half = zero + (size - zero + 1) / 2; // round up! 245360SN/A int bottom_half = (size - zero) / 2; // round down! 246360SN/A 247360SN/A // grow down 2481450SN/A int low_pair = zero - 1; 2493114Sgblack@eecs.umich.edu for (int i = zero - 1; i >= bottom_half; i--) { 250360SN/A cvec[i] = cvec[low_pair]; 2516701Sgblack@eecs.umich.edu if (low_pair - 1 >= 0) 2526701Sgblack@eecs.umich.edu cvec[i] += cvec[low_pair - 1]; 2536701Sgblack@eecs.umich.edu low_pair -= 2; 2546701Sgblack@eecs.umich.edu } 255360SN/A assert(low_pair == 0 || low_pair == -1 || low_pair == -2); 256360SN/A 257360SN/A for (int i = bottom_half - 1; i >= 0; i--) 2581458SN/A cvec[i] = Counter(); 259360SN/A 260360SN/A // grow up 261360SN/A int high_pair = zero; 2621450SN/A for (int i = zero; i < top_half; i++) { 2634118Sgblack@eecs.umich.edu cvec[i] = cvec[high_pair]; 2644118Sgblack@eecs.umich.edu if (high_pair + 1 < size) 2656701Sgblack@eecs.umich.edu cvec[i] += cvec[high_pair + 1]; 2666701Sgblack@eecs.umich.edu high_pair += 2; 2676701Sgblack@eecs.umich.edu } 2686701Sgblack@eecs.umich.edu assert(high_pair == size || high_pair == size + 1); 2696701Sgblack@eecs.umich.edu 2706701Sgblack@eecs.umich.edu for (int i = top_half; i < size; i++) 2714118Sgblack@eecs.umich.edu cvec[i] = Counter(); 2724118Sgblack@eecs.umich.edu 2734118Sgblack@eecs.umich.edu max_bucket *= 2; 2744118Sgblack@eecs.umich.edu min_bucket *= 2; 2754118Sgblack@eecs.umich.edu bucket_size *= 2; 2764118Sgblack@eecs.umich.edu} 2774118Sgblack@eecs.umich.edu 2784118Sgblack@eecs.umich.eduvoid 2794118Sgblack@eecs.umich.eduHistStor::grow_convert() 2804118Sgblack@eecs.umich.edu{ 2816111Ssteve.reinhardt@amd.com int size = cvec.size(); 2826111Ssteve.reinhardt@amd.com int half = (size + 1) / 2; // round up! 2836111Ssteve.reinhardt@amd.com //bool even = (size & 1) == 0; 2846111Ssteve.reinhardt@amd.com 2854118Sgblack@eecs.umich.edu int pair = size - 1; 2864118Sgblack@eecs.umich.edu for (int i = size - 1; i >= half; --i) { 2878706Sandreas.hansson@arm.com cvec[i] = cvec[pair]; 2884118Sgblack@eecs.umich.edu if (pair - 1 >= 0) 2894118Sgblack@eecs.umich.edu cvec[i] += cvec[pair - 1]; 2904118Sgblack@eecs.umich.edu pair -= 2; 2914118Sgblack@eecs.umich.edu } 2924118Sgblack@eecs.umich.edu 2934118Sgblack@eecs.umich.edu for (int i = half - 1; i >= 0; i--) 2944118Sgblack@eecs.umich.edu cvec[i] = Counter(); 2954118Sgblack@eecs.umich.edu 2964118Sgblack@eecs.umich.edu min_bucket = -max_bucket;// - (even ? bucket_size : 0); 2973114Sgblack@eecs.umich.edu bucket_size *= 2; 298360SN/A} 299360SN/A 3001458SN/Avoid 301360SN/AHistStor::grow_up() 302360SN/A{ 303360SN/A int size = cvec.size(); 304360SN/A int half = (size + 1) / 2; // round up! 305360SN/A 3061450SN/A int pair = 0; 3073114Sgblack@eecs.umich.edu for (int i = 0; i < half; i++) { 308360SN/A cvec[i] = cvec[pair]; 3096701Sgblack@eecs.umich.edu if (pair + 1 < size) 3106701Sgblack@eecs.umich.edu cvec[i] += cvec[pair + 1]; 3116701Sgblack@eecs.umich.edu pair += 2; 3126701Sgblack@eecs.umich.edu } 313360SN/A assert(pair == size || pair == size + 1); 314360SN/A 315360SN/A for (int i = half; i < size; i++) 3168706Sandreas.hansson@arm.com cvec[i] = Counter(); 317360SN/A 3181458SN/A max_bucket *= 2; 319360SN/A bucket_size *= 2; 320360SN/A} 3211450SN/A 3225513SMichael.Adler@intel.comFormula::Formula() 3235513SMichael.Adler@intel.com{ 3245513SMichael.Adler@intel.com} 3256731Svince@csl.cornell.edu 3266701Sgblack@eecs.umich.eduFormula::Formula(Temp r) 3276701Sgblack@eecs.umich.edu{ 3286701Sgblack@eecs.umich.edu root = r; 3295513SMichael.Adler@intel.com setInit(); 3305513SMichael.Adler@intel.com assert(size()); 3315513SMichael.Adler@intel.com} 3325513SMichael.Adler@intel.com 3335513SMichael.Adler@intel.comconst Formula & 3345513SMichael.Adler@intel.comFormula::operator=(Temp r) 3355513SMichael.Adler@intel.com{ 3365513SMichael.Adler@intel.com assert(!root && "Can't change formulas"); 3375513SMichael.Adler@intel.com root = r; 3385513SMichael.Adler@intel.com setInit(); 3395513SMichael.Adler@intel.com assert(size()); 3405513SMichael.Adler@intel.com return *this; 3415513SMichael.Adler@intel.com} 3425513SMichael.Adler@intel.com 3435513SMichael.Adler@intel.comconst Formula & 3445513SMichael.Adler@intel.comFormula::operator+=(Temp r) 3455513SMichael.Adler@intel.com{ 3465513SMichael.Adler@intel.com if (root) 3475513SMichael.Adler@intel.com root = NodePtr(new BinaryNode<std::plus<Result> >(root, r)); 3485513SMichael.Adler@intel.com else { 3498706Sandreas.hansson@arm.com root = r; 3505513SMichael.Adler@intel.com setInit(); 3515513SMichael.Adler@intel.com } 3525513SMichael.Adler@intel.com 3535513SMichael.Adler@intel.com assert(size()); 35410203SAli.Saidi@ARM.com return *this; 35510203SAli.Saidi@ARM.com} 35610203SAli.Saidi@ARM.com 35710203SAli.Saidi@ARM.comvoid 35810203SAli.Saidi@ARM.comFormula::result(VResult &vec) const 35910203SAli.Saidi@ARM.com{ 36010203SAli.Saidi@ARM.com if (root) 3615513SMichael.Adler@intel.com vec = root->result(); 3625513SMichael.Adler@intel.com} 36310203SAli.Saidi@ARM.com 36410203SAli.Saidi@ARM.comResult 3655513SMichael.Adler@intel.comFormula::total() const 3665513SMichael.Adler@intel.com{ 3675513SMichael.Adler@intel.com return root ? root->total() : 0.0; 3688852Sandreas.hansson@arm.com} 36910223Ssteve.reinhardt@amd.com 3705513SMichael.Adler@intel.comsize_type 3715513SMichael.Adler@intel.comFormula::size() const 3725513SMichael.Adler@intel.com{ 3735513SMichael.Adler@intel.com if (!root) 3746701Sgblack@eecs.umich.edu return 0; 3756701Sgblack@eecs.umich.edu else 3766701Sgblack@eecs.umich.edu return root->size(); 3776701Sgblack@eecs.umich.edu} 3785513SMichael.Adler@intel.com 3795513SMichael.Adler@intel.comvoid 3805513SMichael.Adler@intel.comFormula::reset() 3818706Sandreas.hansson@arm.com{ 3825513SMichael.Adler@intel.com} 3835513SMichael.Adler@intel.com 3845513SMichael.Adler@intel.combool 3855513SMichael.Adler@intel.comFormula::zero() const 3865513SMichael.Adler@intel.com{ 3873114Sgblack@eecs.umich.edu VResult vec; 388511SN/A result(vec); 3891706SN/A for (VResult::size_type i = 0; i < vec.size(); ++i) 390360SN/A if (vec[i] != 0.0) 3916701Sgblack@eecs.umich.edu return false; 3928852Sandreas.hansson@arm.com return true; 39310223Ssteve.reinhardt@amd.com} 394511SN/A 3953669Sbinkertn@umich.edustring 3963669Sbinkertn@umich.eduFormula::str() const 3973669Sbinkertn@umich.edu{ 398511SN/A return root ? root->str() : ""; 3991458SN/A} 400511SN/A 401511SN/Avoid 4025513SMichael.Adler@intel.comenable() 4035513SMichael.Adler@intel.com{ 4045513SMichael.Adler@intel.com typedef list<Info *>::iterator iter_t; 4055513SMichael.Adler@intel.com 4065513SMichael.Adler@intel.com iter_t i, end = statsList().end(); 4075513SMichael.Adler@intel.com for (i = statsList().begin(); i != end; ++i) { 4086701Sgblack@eecs.umich.edu Info *info = *i; 4098852Sandreas.hansson@arm.com assert(info); 41010223Ssteve.reinhardt@amd.com if (!info->check() || !info->baseCheck()) 4115513SMichael.Adler@intel.com panic("stat check failed for '%s' %d\n", info->name, info->id); 4125513SMichael.Adler@intel.com } 4135513SMichael.Adler@intel.com 4145513SMichael.Adler@intel.com off_t j = 0; 4156701Sgblack@eecs.umich.edu for (i = statsList().begin(); i != end; ++i) { 4165513SMichael.Adler@intel.com Info *info = *i; 4175513SMichael.Adler@intel.com if (!(info->flags & display)) 4185513SMichael.Adler@intel.com info->name = "__Stat" + to_string(j++); 4195513SMichael.Adler@intel.com } 4205513SMichael.Adler@intel.com 4211450SN/A statsList().sort(Info::less); 4223114Sgblack@eecs.umich.edu 423511SN/A for (i = statsList().begin(); i != end; ++i) { 4241706SN/A Info *info = *i; 425511SN/A info->enable(); 4266701Sgblack@eecs.umich.edu } 4278852Sandreas.hansson@arm.com} 4281458SN/A 429511SN/Avoid 4301706SN/Aprepare() 431511SN/A{ 4328852Sandreas.hansson@arm.com list<Info *>::iterator i = statsList().begin(); 4331458SN/A list<Info *>::iterator end = statsList().end(); 434511SN/A while (i != end) { 4353669Sbinkertn@umich.edu Info *info = *i; 4363669Sbinkertn@umich.edu info->prepare(); 4373669Sbinkertn@umich.edu ++i; 4383669Sbinkertn@umich.edu } 4391706SN/A} 4401458SN/A 441511SN/ACallbackQueue resetQueue; 442511SN/A 4431706SN/Avoid 4443114Sgblack@eecs.umich.edureset() 4451706SN/A{ 4461706SN/A list<Info *>::iterator i = statsList().begin(); 4471706SN/A list<Info *>::iterator end = statsList().end(); 4486701Sgblack@eecs.umich.edu while (i != end) { 4498852Sandreas.hansson@arm.com Info *info = *i; 4501706SN/A info->reset(); 4511706SN/A ++i; 4526701Sgblack@eecs.umich.edu } 4531706SN/A 4543669Sbinkertn@umich.edu resetQueue.process(); 4553669Sbinkertn@umich.edu} 4563669Sbinkertn@umich.edu 4571706SN/Avoid 4581706SN/AregisterResetCallback(Callback *cb) 4591706SN/A{ 4601706SN/A resetQueue.add(cb); 4611706SN/A} 4626111Ssteve.reinhardt@amd.com 4636111Ssteve.reinhardt@amd.com} // namespace Stats 4641706SN/A