Mercurial > hg > svcore
changeset 1256:d8d6d01505ed 3.0-integration
Print out cache hit/miss counts
author | Chris Cannam |
---|---|
date | Wed, 09 Nov 2016 18:08:40 +0000 |
parents | ca9032dd2811 |
children | 5236543343c3 |
files | base/HitCount.h data/fileio/WavFileReader.cpp data/model/FFTModel.cpp files.pri |
diffstat | 4 files changed, 94 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/base/HitCount.h Wed Nov 09 18:08:40 2016 +0000 @@ -0,0 +1,68 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#ifndef HIT_COUNT_H +#define HIT_COUNT_H + +#include <string> +#include <iostream> + +/** + * Profile class for counting cache hits and the like. + */ +class HitCount +{ +public: + HitCount(std::string name) : + m_name(name), + m_hit(0), + m_partial(0), + m_miss(0) + { } + + ~HitCount() { + using namespace std; + int total = m_hit + m_partial + m_miss; + cerr << "Hit count: " << m_name << ": "; + if (m_partial > 0) { + cerr << m_hit << " hits, " << m_partial << " partial, " + << m_miss << " misses"; + } else { + cerr << m_hit << " hits, " << m_miss << " misses"; + } + if (total > 0) { + if (m_partial > 0) { + cerr << " (" << ((m_hit * 100.0) / total) << "%, " + << ((m_partial * 100.0) / total) << "%, " + << ((m_miss * 100.0) / total) << "%)"; + } else { + cerr << " (" << ((m_hit * 100.0) / total) << "%, " + << ((m_miss * 100.0) / total) << "%)"; + } + } + cerr << endl; + } + + void hit() { ++m_hit; } + void partial() { ++m_partial; } + void miss() { ++m_miss; } + +private: + std::string m_name; + int m_hit; + int m_partial; + int m_miss; +}; + +#endif
--- a/data/fileio/WavFileReader.cpp Sat Nov 05 10:41:41 2016 +0000 +++ b/data/fileio/WavFileReader.cpp Wed Nov 09 18:08:40 2016 +0000 @@ -15,6 +15,8 @@ #include "WavFileReader.h" +#include "base/HitCount.h" + #include <iostream> #include <QMutexLocker> @@ -130,6 +132,8 @@ vector<float> WavFileReader::getInterleavedFrames(sv_frame_t start, sv_frame_t count) const { + static HitCount lastRead("WavFileReader: last read"); + if (count == 0) return {}; QMutexLocker locker(&m_mutex); @@ -152,8 +156,18 @@ // individual channels, it's quite common for us to be called // repeatedly for the same data. So this is worth cacheing. if (start == m_lastStart && count == m_lastCount) { + lastRead.hit(); return m_buffer; } + + // We don't actually support partial cache reads, but let's use + // the term partial to refer to any forward seek and consider a + // backward seek to be a miss + if (start >= m_lastStart) { + lastRead.partial(); + } else { + lastRead.miss(); + } if (sf_seek(m_file, start, SEEK_SET) < 0) { return {};
--- a/data/model/FFTModel.cpp Sat Nov 05 10:41:41 2016 +0000 +++ b/data/model/FFTModel.cpp Wed Nov 09 18:08:40 2016 +0000 @@ -18,6 +18,7 @@ #include "base/Profiler.h" #include "base/Pitch.h" +#include "base/HitCount.h" #include <algorithm> @@ -26,6 +27,9 @@ using namespace std; +static HitCount inSmallCache("FFTModel: Small FFT cache"); +static HitCount inSourceCache("FFTModel: Source data cache"); + FFTModel::FFTModel(const DenseTimeValueModel *model, int channel, WindowType windowType, @@ -215,6 +219,7 @@ // << "," << m_savedData.range.second << ")" << endl; if (m_savedData.range == range) { + inSourceCache.hit(); return m_savedData.data; } @@ -222,6 +227,8 @@ range.first >= m_savedData.range.first && range.second > m_savedData.range.second) { + inSourceCache.partial(); + sv_frame_t discard = range.first - m_savedData.range.first; vector<float> acc(m_savedData.data.begin() + discard, @@ -237,6 +244,8 @@ } else { + inSourceCache.miss(); + auto data = getSourceDataUncached(range); m_savedData = { range, data }; return data; @@ -284,9 +293,11 @@ { for (auto &incache : m_cached) { if (incache.n == n) { + inSmallCache.hit(); return incache.col; } } + inSmallCache.miss(); auto samples = getSourceSamples(n); m_windower.cut(samples.data());