annotate base/Profiler.cpp @ 1412:b7a9edee85e0 scale-ticks

Change loop to something that feels more correct, though it makes no difference to the tests here. More tests, one failing.
author Chris Cannam
date Thu, 04 May 2017 08:32:41 +0100
parents c811991a5efa
children 48e9f538e6e9
rev   line source
Chris@49 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@52 4 Sonic Visualiser
Chris@52 5 An audio file viewer and annotation editor.
Chris@52 6 Centre for Digital Music, Queen Mary, University of London.
Chris@0 7
Chris@52 8 This program is free software; you can redistribute it and/or
Chris@52 9 modify it under the terms of the GNU General Public License as
Chris@52 10 published by the Free Software Foundation; either version 2 of the
Chris@52 11 License, or (at your option) any later version. See the file
Chris@52 12 COPYING included with this distribution for more information.
Chris@0 13 */
Chris@0 14
Chris@0 15 /*
Chris@0 16 This is a modified version of a source file from the
Chris@0 17 Rosegarden MIDI and audio sequencer and notation editor.
Chris@202 18 This file copyright 2000-2006 Chris Cannam, Guillaume Laurent,
Chris@202 19 and QMUL.
Chris@0 20 */
Chris@0 21
Chris@0 22 #include <iostream>
Chris@0 23 #include "Profiler.h"
Chris@0 24
Chris@658 25 #include <cstdio>
Chris@658 26
Chris@0 27 #include <vector>
Chris@0 28 #include <algorithm>
Chris@183 29 #include <set>
Chris@183 30 #include <map>
Chris@0 31
Chris@0 32 Profiles* Profiles::m_instance = 0;
Chris@0 33
Chris@0 34 Profiles* Profiles::getInstance()
Chris@0 35 {
Chris@0 36 if (!m_instance) m_instance = new Profiles();
Chris@0 37
Chris@0 38 return m_instance;
Chris@0 39 }
Chris@0 40
Chris@0 41 Profiles::Profiles()
Chris@0 42 {
Chris@0 43 }
Chris@0 44
Chris@0 45 Profiles::~Profiles()
Chris@0 46 {
Chris@0 47 dump();
Chris@0 48 }
Chris@0 49
Chris@1216 50 #ifndef NO_TIMING
Chris@259 51 void Profiles::accumulate(
Chris@259 52 const char* id, clock_t time, RealTime rt
Chris@259 53 )
Chris@0 54 {
Chris@0 55 ProfilePair &pair(m_profiles[id]);
Chris@0 56 ++pair.first;
Chris@0 57 pair.second.first += time;
Chris@0 58 pair.second.second = pair.second.second + rt;
Chris@0 59
Chris@183 60 TimePair &lastPair(m_lastCalls[id]);
Chris@183 61 lastPair.first = time;
Chris@183 62 lastPair.second = rt;
Chris@183 63
Chris@183 64 TimePair &worstPair(m_worstCalls[id]);
Chris@183 65 if (time > worstPair.first) {
Chris@183 66 worstPair.first = time;
Chris@183 67 }
Chris@183 68 if (rt > worstPair.second) {
Chris@183 69 worstPair.second = rt;
Chris@183 70 }
Chris@1216 71 }
Chris@0 72 #endif
Chris@0 73
Chris@183 74 void Profiles::dump() const
Chris@0 75 {
Chris@183 76 #ifndef NO_TIMING
Chris@0 77
Chris@183 78 fprintf(stderr, "Profiling points:\n");
Chris@0 79
Chris@183 80 fprintf(stderr, "\nBy name:\n");
Chris@183 81
Chris@183 82 typedef std::set<const char *, std::less<std::string> > StringSet;
Chris@183 83
Chris@183 84 StringSet profileNames;
Chris@183 85 for (ProfileMap::const_iterator i = m_profiles.begin();
Chris@183 86 i != m_profiles.end(); ++i) {
Chris@183 87 profileNames.insert(i->first);
Chris@0 88 }
Chris@0 89
Chris@183 90 for (StringSet::const_iterator i = profileNames.begin();
Chris@183 91 i != profileNames.end(); ++i) {
Chris@0 92
Chris@183 93 ProfileMap::const_iterator j = m_profiles.find(*i);
Chris@0 94
Chris@183 95 if (j == m_profiles.end()) continue;
Chris@0 96
Chris@183 97 const ProfilePair &pp(j->second);
Chris@0 98
Chris@183 99 fprintf(stderr, "%s(%d):\n", *i, pp.first);
Chris@183 100
Chris@183 101 fprintf(stderr, "\tCPU: \t%.9g ms/call \t[%d ms total]\n",
Chris@183 102 (((double)pp.second.first * 1000.0 /
Chris@183 103 (double)pp.first) / CLOCKS_PER_SEC),
Chris@1042 104 int((double(pp.second.first) * 1000.0) / CLOCKS_PER_SEC));
Chris@183 105
Chris@183 106 fprintf(stderr, "\tReal: \t%s ms \t[%s ms total]\n",
Chris@183 107 ((pp.second.second / pp.first) * 1000).toString().c_str(),
Chris@183 108 (pp.second.second * 1000).toString().c_str());
Chris@183 109
Chris@183 110 WorstCallMap::const_iterator k = m_worstCalls.find(*i);
Chris@183 111 if (k == m_worstCalls.end()) continue;
Chris@183 112
Chris@183 113 const TimePair &wc(k->second);
Chris@183 114
Chris@183 115 fprintf(stderr, "\tWorst:\t%s ms/call \t[%d ms CPU]\n",
Chris@183 116 (wc.second * 1000).toString().c_str(),
Chris@1042 117 int((double(wc.first) * 1000.0) / CLOCKS_PER_SEC));
Chris@0 118 }
Chris@0 119
Chris@183 120 typedef std::multimap<RealTime, const char *> TimeRMap;
Chris@183 121 typedef std::multimap<int, const char *> IntRMap;
Chris@183 122
Chris@183 123 TimeRMap totmap, avgmap, worstmap;
Chris@183 124 IntRMap ncallmap;
Chris@183 125
Chris@183 126 for (ProfileMap::const_iterator i = m_profiles.begin();
Chris@183 127 i != m_profiles.end(); ++i) {
Chris@183 128 totmap.insert(TimeRMap::value_type(i->second.second.second, i->first));
Chris@183 129 avgmap.insert(TimeRMap::value_type(i->second.second.second /
Chris@183 130 i->second.first, i->first));
Chris@183 131 ncallmap.insert(IntRMap::value_type(i->second.first, i->first));
Chris@183 132 }
Chris@183 133
Chris@183 134 for (WorstCallMap::const_iterator i = m_worstCalls.begin();
Chris@183 135 i != m_worstCalls.end(); ++i) {
Chris@183 136 worstmap.insert(TimeRMap::value_type(i->second.second,
Chris@183 137 i->first));
Chris@183 138 }
Chris@183 139
Chris@183 140
Chris@183 141 fprintf(stderr, "\nBy total:\n");
Chris@183 142 for (TimeRMap::const_iterator i = totmap.end(); i != totmap.begin(); ) {
Chris@183 143 --i;
Chris@183 144 fprintf(stderr, "%-40s %s ms\n", i->second,
Chris@183 145 (i->first * 1000).toString().c_str());
Chris@183 146 }
Chris@183 147
Chris@183 148 fprintf(stderr, "\nBy average:\n");
Chris@183 149 for (TimeRMap::const_iterator i = avgmap.end(); i != avgmap.begin(); ) {
Chris@183 150 --i;
Chris@183 151 fprintf(stderr, "%-40s %s ms\n", i->second,
Chris@183 152 (i->first * 1000).toString().c_str());
Chris@183 153 }
Chris@183 154
Chris@183 155 fprintf(stderr, "\nBy worst case:\n");
Chris@183 156 for (TimeRMap::const_iterator i = worstmap.end(); i != worstmap.begin(); ) {
Chris@183 157 --i;
Chris@183 158 fprintf(stderr, "%-40s %s ms\n", i->second,
Chris@408 159 (i->first * 1000).toString().c_str());
Chris@183 160 }
Chris@183 161
Chris@183 162 fprintf(stderr, "\nBy number of calls:\n");
Chris@183 163 for (IntRMap::const_iterator i = ncallmap.end(); i != ncallmap.begin(); ) {
Chris@183 164 --i;
Chris@183 165 fprintf(stderr, "%-40s %d\n", i->second, i->first);
Chris@183 166 }
Chris@183 167
Chris@0 168 #endif
Chris@0 169 }
Chris@0 170
Chris@183 171 #ifndef NO_TIMING
Chris@183 172
Chris@408 173 Profiler::Profiler(const char* c, bool showOnDestruct) :
Chris@408 174 m_c(c),
Chris@408 175 m_showOnDestruct(showOnDestruct),
Chris@408 176 m_ended(false)
Chris@0 177 {
Chris@0 178 m_startCPU = clock();
Chris@0 179
Chris@0 180 struct timeval tv;
Chris@0 181 (void)gettimeofday(&tv, 0);
Chris@26 182 m_startTime = RealTime::fromTimeval(tv);
Chris@0 183 }
Chris@0 184
Chris@0 185 void
Chris@183 186 Profiler::update() const
Chris@0 187 {
Chris@0 188 clock_t elapsedCPU = clock() - m_startCPU;
Chris@0 189
Chris@0 190 struct timeval tv;
Chris@0 191 (void)gettimeofday(&tv, 0);
Chris@26 192 RealTime elapsedTime = RealTime::fromTimeval(tv) - m_startTime;
Chris@0 193
Chris@0 194 cerr << "Profiler : id = " << m_c
Chris@0 195 << " - elapsed so far = " << ((elapsedCPU * 1000) / CLOCKS_PER_SEC)
Chris@0 196 << "ms CPU, " << elapsedTime << " real" << endl;
Chris@0 197 }
Chris@0 198
Chris@0 199 Profiler::~Profiler()
Chris@0 200 {
Chris@408 201 if (!m_ended) end();
Chris@408 202 }
Chris@408 203
Chris@408 204 void
Chris@408 205 Profiler::end()
Chris@408 206 {
Chris@0 207 clock_t elapsedCPU = clock() - m_startCPU;
Chris@0 208
Chris@0 209 struct timeval tv;
Chris@0 210 (void)gettimeofday(&tv, 0);
Chris@26 211 RealTime elapsedTime = RealTime::fromTimeval(tv) - m_startTime;
Chris@0 212
Chris@0 213 Profiles::getInstance()->accumulate(m_c, elapsedCPU, elapsedTime);
Chris@0 214
Chris@0 215 if (m_showOnDestruct)
Chris@0 216 cerr << "Profiler : id = " << m_c
Chris@0 217 << " - elapsed = " << ((elapsedCPU * 1000) / CLOCKS_PER_SEC)
Chris@0 218 << "ms CPU, " << elapsedTime << " real" << endl;
Chris@408 219
Chris@408 220 m_ended = true;
Chris@0 221 }
Chris@0 222
Chris@183 223 #endif
Chris@183 224