gem5  v22.1.0.0
Histogram.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
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 
30 
31 #include <cmath>
32 #include <iomanip>
33 
34 #include "base/intmath.hh"
35 #include "base/logging.hh"
36 
37 namespace gem5
38 {
39 
40 namespace ruby
41 {
42 
43 Histogram::Histogram(int binsize, uint32_t bins)
44 {
45  m_binsize = binsize;
46  clear(bins);
47 }
48 
50 {
51 }
52 
53 void
54 Histogram::clear(int binsize, uint32_t bins)
55 {
56  m_binsize = binsize;
57  clear(bins);
58 }
59 
60 void
61 Histogram::clear(uint32_t bins)
62 {
63  m_largest_bin = 0;
64  m_max = 0;
65  m_data.resize(bins);
66  for (uint32_t i = 0; i < bins; i++) {
67  m_data[i] = 0;
68  }
69 
70  m_count = 0;
71  m_max = 0;
72  m_sumSamples = 0;
74 }
75 
76 void
78 {
79  assert(m_binsize != -1);
80  uint32_t t_bins = m_data.size();
81 
82  for (uint32_t i = 0; i < t_bins/2; i++) {
83  m_data[i] = m_data[i*2] + m_data[i*2 + 1];
84  }
85  for (uint32_t i = t_bins/2; i < t_bins; i++) {
86  m_data[i] = 0;
87  }
88 
89  m_binsize *= 2;
90 }
91 
92 void
93 Histogram::add(int64_t value)
94 {
95  assert(value >= 0);
96  m_max = std::max(m_max, value);
97  m_count++;
98 
99  m_sumSamples += value;
100  m_sumSquaredSamples += (value*value);
101 
102  uint32_t index;
103 
104  if (m_binsize == -1) {
105  // This is a log base 2 histogram
106  if (value == 0) {
107  index = 0;
108  } else {
109  index = floorLog2(value) + 1;
110  if (index >= m_data.size()) {
111  index = m_data.size() - 1;
112  }
113  }
114  } else {
115  // This is a linear histogram
116  uint32_t t_bins = m_data.size();
117 
118  while (m_max >= (t_bins * m_binsize)) doubleBinSize();
119  index = value/m_binsize;
120  }
121 
122  assert(index < m_data.size());
123  m_data[index]++;
124  m_largest_bin = std::max(m_largest_bin, index);
125 }
126 
127 void
129 {
130  uint32_t t_bins = m_data.size();
131 
132  if (hist.getBins() != t_bins) {
133  if (m_count == 0) {
134  m_data.resize(hist.getBins());
135  } else {
136  fatal("Histograms with different number of bins "
137  "cannot be combined!");
138  }
139  }
140 
141  m_max = std::max(m_max, hist.getMax());
142  m_count += hist.size();
143  m_sumSamples += hist.getTotal();
145 
146  // Both histograms are log base 2.
147  if (hist.getBinSize() == -1 && m_binsize == -1) {
148  for (int j = 0; j < hist.getData(0); j++) {
149  add(0);
150  }
151 
152  for (uint32_t i = 1; i < t_bins; i++) {
153  for (int j = 0; j < hist.getData(i); j++) {
154  add(1<<(i-1)); // account for the + 1 index
155  }
156  }
157  } else if (hist.getBinSize() >= 1 && m_binsize >= 1) {
158  // Both the histogram are linear.
159  // We are assuming that the two histograms have the same
160  // minimum value that they can store.
161 
162  while (m_binsize > hist.getBinSize()) hist.doubleBinSize();
163  while (hist.getBinSize() > m_binsize) doubleBinSize();
164 
165  assert(m_binsize == hist.getBinSize());
166 
167  for (uint32_t i = 0; i < t_bins; i++) {
168  m_data[i] += hist.getData(i);
169 
170  if (m_data[i] > 0) m_largest_bin = i;
171  }
172  } else {
173  fatal("Don't know how to combine log and linear histograms!");
174  }
175 }
176 
177 // Computation of standard deviation of samples a1, a2, ... aN
178 // variance = [SUM {ai^2} - (SUM {ai})^2/N]/(N-1)
179 // std deviation equals square root of variance
180 double
182 {
183  if (m_count <= 1)
184  return 0.0;
185 
186  double variance =
188  / (m_count - 1);
189  return sqrt(variance);
190 }
191 
192 void
193 Histogram::print(std::ostream& out) const
194 {
195  printWithMultiplier(out, 1.0);
196 }
197 
198 void
199 Histogram::printPercent(std::ostream& out) const
200 {
201  if (m_count == 0) {
202  printWithMultiplier(out, 0.0);
203  } else {
204  printWithMultiplier(out, 100.0 / double(m_count));
205  }
206 }
207 
208 void
209 Histogram::printWithMultiplier(std::ostream& out, double multiplier) const
210 {
211  if (m_binsize == -1) {
212  out << "[binsize: log2 ";
213  } else {
214  out << "[binsize: " << m_binsize << " ";
215  }
216  out << "max: " << m_max << " ";
217  out << "count: " << m_count << " ";
218  // out << "total: " << m_sumSamples << " ";
219  if (m_count == 0) {
220  out << "average: NaN |";
221  out << "standard deviation: NaN |";
222  } else {
223  out << "average: " << std::setw(5) << ((double) m_sumSamples)/m_count
224  << " | ";
225  out << "standard deviation: " << getStandardDeviation() << " |";
226  }
227 
228  for (uint32_t i = 0; i <= m_largest_bin; i++) {
229  if (multiplier == 1.0) {
230  out << " " << m_data[i];
231  } else {
232  out << " " << double(m_data[i]) * multiplier;
233  }
234  }
235  out << " ]";
236 }
237 
238 bool
239 node_less_then_eq(const Histogram* n1, const Histogram* n2)
240 {
241  return (n1->size() > n2->size());
242 }
243 
244 } // namespace ruby
245 } // namespace gem5
double getStandardDeviation() const
Definition: Histogram.cc:181
void print(std::ostream &out) const
Definition: Histogram.cc:193
int64_t getTotal() const
Definition: Histogram.hh:60
int64_t getMax() const
Definition: Histogram.hh:63
uint64_t getSquaredTotal() const
Definition: Histogram.hh:61
uint64_t size() const
Definition: Histogram.hh:57
uint64_t getData(int index) const
Definition: Histogram.hh:62
void printWithMultiplier(std::ostream &out, double multiplier) const
Definition: Histogram.cc:209
uint32_t m_largest_bin
Definition: Histogram.hh:74
int getBinSize() const
Definition: Histogram.hh:59
uint32_t getBins() const
Definition: Histogram.hh:58
void add(int64_t value)
Definition: Histogram.cc:93
uint64_t m_sumSquaredSamples
Definition: Histogram.hh:77
std::vector< uint64_t > m_data
Definition: Histogram.hh:70
void printPercent(std::ostream &out) const
Definition: Histogram.cc:199
Histogram(int binsize=1, uint32_t bins=50)
Definition: Histogram.cc:43
static constexpr std::enable_if_t< std::is_integral_v< T >, int > floorLog2(T x)
Definition: intmath.hh:59
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:190
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 24 > j
Definition: misc_types.hh:57
Bitfield< 30, 0 > index
bool node_less_then_eq(const Histogram *n1, const Histogram *n2)
Definition: Histogram.cc:239
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....

Generated on Wed Dec 21 2022 10:22:38 for gem5 by doxygen 1.9.1