summaryrefslogtreecommitdiff
path: root/src/mem/ruby/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/ruby/common')
-rw-r--r--src/mem/ruby/common/Histogram.cc97
-rw-r--r--src/mem/ruby/common/Histogram.hh30
2 files changed, 84 insertions, 43 deletions
diff --git a/src/mem/ruby/common/Histogram.cc b/src/mem/ruby/common/Histogram.cc
index dcb723f1b..0558e5198 100644
--- a/src/mem/ruby/common/Histogram.cc
+++ b/src/mem/ruby/common/Histogram.cc
@@ -34,11 +34,10 @@
using namespace std;
-Histogram::Histogram(int binsize, int bins)
+Histogram::Histogram(int binsize, uint32_t bins)
{
m_binsize = binsize;
- m_bins = bins;
- clear();
+ clear(bins);
}
Histogram::~Histogram()
@@ -46,29 +45,43 @@ Histogram::~Histogram()
}
void
-Histogram::clear(int binsize, int bins)
+Histogram::clear(int binsize, uint32_t bins)
{
m_binsize = binsize;
clear(bins);
}
void
-Histogram::clear(int bins)
+Histogram::clear(uint32_t bins)
{
- m_bins = bins;
m_largest_bin = 0;
m_max = 0;
- m_data.resize(m_bins);
- for (int i = 0; i < m_bins; i++) {
+ m_data.resize(bins);
+ for (uint32_t i = 0; i < bins; i++) {
m_data[i] = 0;
}
+
m_count = 0;
m_max = 0;
-
m_sumSamples = 0;
m_sumSquaredSamples = 0;
}
+void
+Histogram::doubleBinSize()
+{
+ assert(m_binsize != -1);
+ uint32_t t_bins = m_data.size();
+
+ for (uint32_t i = 0; i < t_bins/2; i++) {
+ m_data[i] = m_data[i*2] + m_data[i*2 + 1];
+ }
+ for (uint32_t i = t_bins/2; i < t_bins; i++) {
+ m_data[i] = 0;
+ }
+
+ m_binsize *= 2;
+}
void
Histogram::add(int64 value)
@@ -80,7 +93,8 @@ Histogram::add(int64 value)
m_sumSamples += value;
m_sumSquaredSamples += (value*value);
- int index;
+ uint32_t index;
+
if (m_binsize == -1) {
// This is a log base 2 histogram
if (value == 0) {
@@ -93,37 +107,59 @@ Histogram::add(int64 value)
}
} else {
// This is a linear histogram
- while (m_max >= (m_bins * m_binsize)) {
- for (int i = 0; i < m_bins/2; i++) {
- m_data[i] = m_data[i*2] + m_data[i*2 + 1];
- }
- for (int i = m_bins/2; i < m_bins; i++) {
- m_data[i] = 0;
- }
- m_binsize *= 2;
- }
+ uint32_t t_bins = m_data.size();
+
+ while (m_max >= (t_bins * m_binsize)) doubleBinSize();
index = value/m_binsize;
}
- assert(index >= 0);
+
+ assert(index < m_data.size());
m_data[index]++;
m_largest_bin = max(m_largest_bin, index);
}
void
-Histogram::add(const Histogram& hist)
+Histogram::add(Histogram& hist)
{
- assert(hist.getBins() == m_bins);
- assert(hist.getBinSize() == -1); // assume log histogram
- assert(m_binsize == -1);
+ uint32_t t_bins = m_data.size();
- for (int j = 0; j < hist.getData(0); j++) {
- add(0);
+ if (hist.getBins() != t_bins) {
+ fatal("Histograms with different number of bins cannot be combined!");
}
- for (int i = 1; i < m_bins; i++) {
- for (int j = 0; j < hist.getData(i); j++) {
- add(1<<(i-1)); // account for the + 1 index
+ m_max = max(m_max, hist.getMax());
+ m_count += hist.size();
+ m_sumSamples += hist.getTotal();
+ m_sumSquaredSamples += hist.getSquaredTotal();
+
+ // Both histograms are log base 2.
+ if (hist.getBinSize() == -1 && m_binsize == -1) {
+ for (int j = 0; j < hist.getData(0); j++) {
+ add(0);
+ }
+
+ for (uint32_t i = 1; i < t_bins; i++) {
+ for (int j = 0; j < hist.getData(i); j++) {
+ add(1<<(i-1)); // account for the + 1 index
+ }
+ }
+ } else if (hist.getBinSize() >= 1 && m_binsize >= 1) {
+ // Both the histogram are linear.
+ // We are assuming that the two histograms have the same
+ // minimum value that they can store.
+
+ while (m_binsize > hist.getBinSize()) hist.doubleBinSize();
+ while (hist.getBinSize() > m_binsize) doubleBinSize();
+
+ assert(m_binsize == hist.getBinSize());
+
+ for (uint32_t i = 0; i < t_bins; i++) {
+ m_data[i] += hist.getData(i);
+
+ if (m_data[i] > 0) m_largest_bin = i;
}
+ } else {
+ fatal("Don't know how to combine log and linear histograms!");
}
}
@@ -177,7 +213,8 @@ Histogram::printWithMultiplier(ostream& out, double multiplier) const
<< " | ";
out << "standard deviation: " << getStandardDeviation() << " |";
}
- for (int i = 0; i < m_bins && i <= m_largest_bin; i++) {
+
+ for (uint32_t i = 0; i <= m_largest_bin; i++) {
if (multiplier == 1.0) {
out << " " << m_data[i];
} else {
diff --git a/src/mem/ruby/common/Histogram.hh b/src/mem/ruby/common/Histogram.hh
index bfc0e4293..c34e39af1 100644
--- a/src/mem/ruby/common/Histogram.hh
+++ b/src/mem/ruby/common/Histogram.hh
@@ -37,34 +37,38 @@
class Histogram
{
public:
- Histogram(int binsize = 1, int bins = 50);
+ Histogram(int binsize = 1, uint32_t bins = 50);
~Histogram();
void add(int64 value);
- void add(const Histogram& hist);
- void clear() { clear(m_bins); }
- void clear(int bins);
- void clear(int binsize, int bins);
- int64 size() const { return m_count; }
- int getBins() const { return m_bins; }
+ void add(Histogram& hist);
+ void doubleBinSize();
+
+ void clear() { clear(m_data.size()); }
+ void clear(uint32_t bins);
+ void clear(int binsize, uint32_t bins);
+
+ uint64_t size() const { return m_count; }
+ uint32_t getBins() const { return m_data.size(); }
int getBinSize() const { return m_binsize; }
int64 getTotal() const { return m_sumSamples; }
- int64 getData(int index) const { return m_data[index]; }
+ uint64_t getSquaredTotal() const { return m_sumSquaredSamples; }
+ uint64_t getData(int index) const { return m_data[index]; }
+ int64 getMax() const { return m_max; }
void printWithMultiplier(std::ostream& out, double multiplier) const;
void printPercent(std::ostream& out) const;
void print(std::ostream& out) const;
private:
- std::vector<int64> m_data;
+ std::vector<uint64_t> m_data;
int64 m_max; // the maximum value seen so far
- int64 m_count; // the number of elements added
+ uint64_t m_count; // the number of elements added
int m_binsize; // the size of each bucket
- int m_bins; // the number of buckets
- int m_largest_bin; // the largest bin used
+ uint32_t m_largest_bin; // the largest bin used
int64 m_sumSamples; // the sum of all samples
- int64 m_sumSquaredSamples; // the sum of the square of all samples
+ uint64_t m_sumSquaredSamples; // the sum of the square of all samples
double getStandardDeviation() const;
};