diff options
Diffstat (limited to 'src/mem/ruby/common')
-rw-r--r-- | src/mem/ruby/common/Histogram.cc | 97 | ||||
-rw-r--r-- | src/mem/ruby/common/Histogram.hh | 30 |
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; }; |