gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
statistics.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2003-2005 The Regents of The University of Michigan
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met: redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer;
9  * redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution;
12  * neither the name of the copyright holders nor the names of its
13  * contributors may be used to endorse or promote products derived from
14  * this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * Authors: Nathan Binkert
29  */
30 
31 #include "base/statistics.hh"
32 
33 #include <fstream>
34 #include <iomanip>
35 #include <list>
36 #include <map>
37 #include <string>
38 
39 #include "base/callback.hh"
40 #include "base/cprintf.hh"
41 #include "base/debug.hh"
42 #include "base/hostinfo.hh"
43 #include "base/misc.hh"
44 #include "base/str.hh"
45 #include "base/time.hh"
46 #include "base/trace.hh"
47 
48 using namespace std;
49 
50 namespace Stats {
51 
52 std::string Info::separatorString = "::";
53 
54 // We wrap these in a function to make sure they're built in time.
57 {
58  static list<Info *> the_list;
59  return the_list;
60 }
61 
62 MapType &
64 {
65  static MapType the_map;
66  return the_map;
67 }
68 
69 void
70 InfoAccess::setInfo(Info *info)
71 {
72  if (statsMap().find(this) != statsMap().end())
73  panic("shouldn't register stat twice!");
74 
75  statsList().push_back(info);
76 
77 #ifndef NDEBUG
79 #endif
80  statsMap().insert(make_pair(this, info));
81  assert(result.second && "this should never fail");
82  assert(statsMap().find(this) != statsMap().end());
83 }
84 
85 void
86 InfoAccess::setParams(const StorageParams *params)
87 {
88  info()->storageParams = params;
89 }
90 
91 void
92 InfoAccess::setInit()
93 {
94  info()->flags.set(init);
95 }
96 
97 Info *
98 InfoAccess::info()
99 {
100  MapType::const_iterator i = statsMap().find(this);
101  assert(i != statsMap().end());
102  return (*i).second;
103 }
104 
105 const Info *
106 InfoAccess::info() const
107 {
108  MapType::const_iterator i = statsMap().find(this);
109  assert(i != statsMap().end());
110  return (*i).second;
111 }
112 
113 StorageParams::~StorageParams()
114 {
115 }
116 
117 NameMapType &
119 {
120  static NameMapType the_map;
121  return the_map;
122 }
123 
124 int Info::id_count = 0;
125 
126 int debug_break_id = -1;
127 
128 Info::Info()
129  : flags(none), precision(-1), prereq(0), storageParams(NULL)
130 {
131  id = id_count++;
132  if (debug_break_id >= 0 and debug_break_id == id)
134 }
135 
137 {
138 }
139 
140 bool
141 validateStatName(const string &name)
142 {
143  if (name.empty())
144  return false;
145 
146  vector<string> vec;
147  tokenize(vec, name, '.');
148  vector<string>::const_iterator item = vec.begin();
149  while (item != vec.end()) {
150  if (item->empty())
151  return false;
152 
153  string::const_iterator c = item->begin();
154 
155  // The first character is different
156  if (!isalpha(*c) && *c != '_')
157  return false;
158 
159  // The rest of the characters have different rules.
160  while (++c != item->end()) {
161  if (!isalnum(*c) && *c != '_')
162  return false;
163  }
164 
165  ++item;
166  }
167 
168  return true;
169 }
170 
171 void
172 Info::setName(const string &name)
173 {
174  if (!validateStatName(name))
175  panic("invalid stat name '%s'", name);
176 
178  nameMap().insert(make_pair(name, this));
179 
180  Info *other = p.first->second;
181  bool result = p.second;
182 
183  if (!result) {
184  // using other->name instead of just name to avoid a compiler
185  // warning. They should be the same.
186  panic("same statistic name used twice! name=%s\n", other->name);
187  }
188 
189  this->name = name;
190 }
191 
192 bool
193 Info::less(Info *stat1, Info *stat2)
194 {
195  const string &name1 = stat1->name;
196  const string &name2 = stat2->name;
197 
198  vector<string> v1;
199  vector<string> v2;
200 
201  tokenize(v1, name1, '.');
202  tokenize(v2, name2, '.');
203 
204  size_type last = min(v1.size(), v2.size()) - 1;
205  for (off_type i = 0; i < last; ++i)
206  if (v1[i] != v2[i])
207  return v1[i] < v2[i];
208 
209  // Special compare for last element.
210  if (v1[last] == v2[last])
211  return v1.size() < v2.size();
212  else
213  return v1[last] < v2[last];
214 
215  return false;
216 }
217 
218 bool
220 {
221  if (!(flags & Stats::init)) {
222 #ifdef DEBUG
223  cprintf("this is stat number %d\n", id);
224 #endif
225  panic("Not all stats have been initialized.\n"
226  "You may need to add <ParentClass>::regStats() to a"
227  " new SimObject's regStats() function.");
228  return false;
229  }
230 
231  if ((flags & display) && name.empty()) {
232  panic("all printable stats must be named");
233  return false;
234  }
235 
236  return true;
237 }
238 
239 void
241 {
242 }
243 
244 void
246 {
247  size_type s = size();
248  if (subnames.size() < s)
249  subnames.resize(s);
250  if (subdescs.size() < s)
251  subdescs.resize(s);
252 }
253 
254 void
256 {
257  size_type s = size();
258  if (subnames.size() < s)
259  subnames.resize(s);
260  if (subdescs.size() < s)
261  subdescs.resize(s);
262 }
263 
264 void
266 {
267  if (subnames.size() < x)
268  subnames.resize(x);
269  if (subdescs.size() < x)
270  subdescs.resize(x);
271  if (y_subnames.size() < y)
272  y_subnames.resize(y);
273 }
274 
275 void
277 {
278  int size = cvec.size();
279  int zero = size / 2; // round down!
280  int top_half = zero + (size - zero + 1) / 2; // round up!
281  int bottom_half = (size - zero) / 2; // round down!
282 
283  // grow down
284  int low_pair = zero - 1;
285  for (int i = zero - 1; i >= bottom_half; i--) {
286  cvec[i] = cvec[low_pair];
287  if (low_pair - 1 >= 0)
288  cvec[i] += cvec[low_pair - 1];
289  low_pair -= 2;
290  }
291  assert(low_pair == 0 || low_pair == -1 || low_pair == -2);
292 
293  for (int i = bottom_half - 1; i >= 0; i--)
294  cvec[i] = Counter();
295 
296  // grow up
297  int high_pair = zero;
298  for (int i = zero; i < top_half; i++) {
299  cvec[i] = cvec[high_pair];
300  if (high_pair + 1 < size)
301  cvec[i] += cvec[high_pair + 1];
302  high_pair += 2;
303  }
304  assert(high_pair == size || high_pair == size + 1);
305 
306  for (int i = top_half; i < size; i++)
307  cvec[i] = Counter();
308 
309  max_bucket *= 2;
310  min_bucket *= 2;
311  bucket_size *= 2;
312 }
313 
314 void
316 {
317  int size = cvec.size();
318  int half = (size + 1) / 2; // round up!
319  //bool even = (size & 1) == 0;
320 
321  int pair = size - 1;
322  for (int i = size - 1; i >= half; --i) {
323  cvec[i] = cvec[pair];
324  if (pair - 1 >= 0)
325  cvec[i] += cvec[pair - 1];
326  pair -= 2;
327  }
328 
329  for (int i = half - 1; i >= 0; i--)
330  cvec[i] = Counter();
331 
332  min_bucket = -max_bucket;// - (even ? bucket_size : 0);
333  bucket_size *= 2;
334 }
335 
336 void
338 {
339  int size = cvec.size();
340  int half = (size + 1) / 2; // round up!
341 
342  int pair = 0;
343  for (int i = 0; i < half; i++) {
344  cvec[i] = cvec[pair];
345  if (pair + 1 < size)
346  cvec[i] += cvec[pair + 1];
347  pair += 2;
348  }
349  assert(pair == size || pair == size + 1);
350 
351  for (int i = half; i < size; i++)
352  cvec[i] = Counter();
353 
354  max_bucket *= 2;
355  bucket_size *= 2;
356 }
357 
358 void
360 {
361  int b_size = hs->size();
362  assert(size() == b_size);
363  assert(min_bucket == hs->min_bucket);
364 
365  sum += hs->sum;
366  logs += hs->logs;
367  squares += hs->squares;
368  samples += hs->samples;
369 
370  while (bucket_size > hs->bucket_size)
371  hs->grow_up();
372  while (bucket_size < hs->bucket_size)
373  grow_up();
374 
375  for (uint32_t i = 0; i < b_size; i++)
376  cvec[i] += hs->cvec[i];
377 }
378 
380 {
381 }
382 
384 {
385  root = r.getNodePtr();
386  setInit();
387  assert(size());
388 }
389 
390 const Formula &
392 {
393  assert(!root && "Can't change formulas");
394  root = r.getNodePtr();
395  setInit();
396  assert(size());
397  return *this;
398 }
399 
400 const Formula &
402 {
403  if (root)
404  root = NodePtr(new BinaryNode<std::plus<Result> >(root, r));
405  else {
406  root = r.getNodePtr();
407  setInit();
408  }
409 
410  assert(size());
411  return *this;
412 }
413 
414 const Formula &
416 {
417  assert (root);
418  root = NodePtr(new BinaryNode<std::divides<Result> >(root, r));
419 
420  assert(size());
421  return *this;
422 }
423 
424 void
426 {
427  if (root)
428  vec = root->result();
429 }
430 
431 Result
433 {
434  return root ? root->total() : 0.0;
435 }
436 
437 size_type
439 {
440  if (!root)
441  return 0;
442  else
443  return root->size();
444 }
445 
446 void
448 {
449 }
450 
451 bool
453 {
454  VResult vec;
455  result(vec);
456  for (VResult::size_type i = 0; i < vec.size(); ++i)
457  if (vec[i] != 0.0)
458  return false;
459  return true;
460 }
461 
462 string
464 {
465  return root ? root->str() : "";
466 }
467 
470 
471 void
472 registerHandlers(Handler reset_handler, Handler dump_handler)
473 {
474  resetHandler = reset_handler;
475  dumpHandler = dump_handler;
476 }
477 
480 
481 void
483 {
485 }
486 
487 void
489 {
490  dumpQueue.process();
491 }
492 
493 void
495 {
496  resetQueue.add(cb);
497 }
498 
499 bool _enabled = false;
500 
501 bool
503 {
504  return _enabled;
505 }
506 
507 void
509 {
510  if (_enabled)
511  fatal("Stats are already enabled");
512 
513  _enabled = true;
514 }
515 
516 void
518 {
519  if (dumpHandler)
520  dumpHandler();
521  else
522  fatal("No registered Stats::dump handler");
523 }
524 
525 void
527 {
528  if (resetHandler)
529  resetHandler();
530  else
531  fatal("No registered Stats::reset handler");
532 }
533 
534 void
536 {
537  dumpQueue.add(cb);
538 }
539 
540 } // namespace Stats
541 
542 void
544 {
545  Stats::dump();
546 }
double Result
All results are doubles.
Definition: types.hh:52
const Formula & operator=(Temp r)
Set an unitialized Formula to the given root.
Definition: statistics.cc:391
Counter samples
The number of samples.
Definition: statistics.hh:1544
std::string name
The name of the stat.
Definition: info.hh:73
void debugDumpStats()
Definition: statistics.cc:543
static int id_count
A unique stat ID for each stat in the simulator.
Definition: info.hh:88
void enable()
Enable the stat for use.
Definition: statistics.cc:265
void processDumpQueue()
Process all the callbacks in the dump callbacks queue.
Definition: statistics.cc:488
bool zero() const
Definition: statistics.cc:452
void breakpoint()
Definition: debug.cc:52
std::vector< std::string > subdescs
Definition: info.hh:206
Generic callback class.
Definition: callback.hh:41
std::vector< std::string > subdescs
Definition: info.hh:160
const std::string & name()
Definition: trace.cc:49
Bitfield< 7 > i
Definition: miscregs.hh:1378
STL pair class.
Definition: stl.hh:61
#define panic(...)
Definition: misc.hh:153
const Formula & operator/=(Temp r)
Divide the existing tree by the given one.
Definition: statistics.cc:415
void process()
process all callbacks
Definition: callback.hh:135
Counter max_bucket
The maximum value to track.
Definition: statistics.hh:1533
Result total() const
Return the total Formula result.
Definition: statistics.cc:432
virtual size_type size() const =0
VCounter cvec
Counter for each bucket.
Definition: statistics.hh:1546
virtual void enable()
Enable the stat for use.
Definition: statistics.cc:240
std::vector< std::string > subnames
Names and descriptions of subfields.
Definition: info.hh:159
void(* Handler)()
Register reset and dump handlers.
Definition: statistics.hh:3240
void reset()
Definition: statistics.cc:526
list< Info * > & statsList()
Definition: statistics.cc:56
bool _enabled
Definition: statistics.cc:499
std::vector< std::string > y_subnames
Definition: info.hh:223
Counter logs
The sum of logarithm of each sample, used to compute geometric mean.
Definition: statistics.hh:1540
void add(HistStor *)
Definition: statistics.cc:359
void enable()
Enable the stat for use.
Definition: statistics.cc:255
CallbackQueue resetQueue
Definition: statistics.cc:479
Counter squares
The sum of squares.
Definition: statistics.hh:1542
Counter min_bucket
The minimum value to track.
Definition: statistics.hh:1531
std::vector< std::string > subnames
Names and descriptions of subfields.
Definition: info.hh:221
unsigned int size_type
Definition: types.hh:56
Declaration of Statistics objects.
const Formula & operator+=(Temp r)
Add the given tree to the existing one.
Definition: statistics.cc:401
double Counter
All counters are of 64-bit values.
Definition: types.hh:43
void result(VResult &vec) const
Return the result of the Fomula in a vector.
Definition: statistics.cc:425
Formula()
Create and initialize thie formula, and register it with the database.
Definition: statistics.cc:379
bool zero() const
Returns true if any calls to sample have been made.
Definition: statistics.hh:1608
void enable()
Definition: statistics.cc:508
void add(Callback *callback)
Add a callback to the end of the queue.
Definition: callback.hh:107
Bitfield< 4 > s
Definition: miscregs.hh:1738
Templatized storage and interface for a histogram stat.
Definition: statistics.hh:1517
void reset()
Formulas don't need to be reset.
Definition: statistics.cc:447
static bool less(Info *stat1, Info *stat2)
Checks if the first stat's name is alphabetically less than the second.
Definition: statistics.cc:193
Counter sum
The current sum.
Definition: statistics.hh:1538
std::shared_ptr< Node > NodePtr
Shared pointer to a function Node.
Definition: statistics.hh:2096
void grow_convert()
Definition: statistics.cc:315
Flags flags
The formatting flags.
Definition: info.hh:79
void registerResetCallback(Callback *cb)
Register a callback that should be called whenever statistics are reset.
Definition: statistics.cc:494
virtual size_type size() const =0
size_type size() const
Return the number of buckets in this distribution.
Definition: statistics.hh:1601
#define fatal(...)
Definition: misc.hh:163
void setName(const std::string &name)
Set the name of this statistic.
Definition: statistics.cc:172
STL list class.
Definition: stl.hh:54
const FlagsType display
Print this stat.
Definition: info.hh:47
const FlagsType none
Nothing extra to print.
Definition: info.hh:43
virtual ~Info()
Definition: statistics.cc:136
int debug_break_id
Definition: statistics.cc:126
unsigned int off_type
Definition: types.hh:57
std::map< const void *, Info * > MapType
Definition: statistics.hh:3268
size_type x
Definition: info.hh:225
void enable()
Enable the stat for use.
Definition: statistics.cc:245
bool baseCheck() const
Definition: statistics.cc:219
Counter bucket_size
The number of entries in each bucket.
Definition: statistics.hh:1535
Helper class to construct formula node trees.
Definition: statistics.hh:2996
bool enabled()
Definition: statistics.cc:502
std::vector< std::string > subdescs
Definition: info.hh:222
NameMapType & nameMap()
Definition: statistics.cc:118
void registerDumpCallback(Callback *cb)
Register a callback that should be called whenever statistics are about to be dumped.
Definition: statistics.cc:535
A formula for statistics that is calculated when printed.
Definition: statistics.hh:2895
size_type size() const
Return the number of elements in the tree.
Definition: statistics.cc:438
void setInit()
Save Storage class parameters if any.
Definition: statistics.cc:92
Bitfield< 29 > c
Definition: miscregs.hh:1365
size_type y
Definition: info.hh:226
void processResetQueue()
Process all the callbacks in the reset callbacks queue.
Definition: statistics.cc:482
NodePtr getNodePtr() const
Makde gcc < 4.6.3 happy and explicitly get the underlying node.
Definition: statistics.hh:3022
bool validateStatName(const string &name)
Definition: statistics.cc:141
Handler resetHandler
Definition: statistics.cc:468
void tokenize(vector< string > &v, const string &s, char token, bool ignore)
Definition: str.cc:69
Handler dumpHandler
Definition: statistics.cc:469
NodePtr root
The root of the tree which represents the Formula.
Definition: statistics.hh:2899
std::string str() const
Definition: statistics.cc:463
void dump()
Dump all statistics data to the registered outputs.
Definition: statistics.cc:517
std::map< std::string, Info * > NameMapType
Definition: statistics.hh:3271
CallbackQueue dumpQueue
Definition: statistics.cc:478
void registerHandlers(Handler reset_handler, Handler dump_handler)
Definition: statistics.cc:472
Bitfield< 0 > p
const FlagsType init
This Stat is Initialized.
Definition: info.hh:45
std::vector< std::string > subnames
Names and descriptions of subfields.
Definition: info.hh:205
void cprintf(const char *format, const Args &...args)
Definition: cprintf.hh:155
MapType & statsMap()
Definition: statistics.cc:63

Generated on Fri Jun 9 2017 13:03:41 for gem5 by doxygen 1.8.6