annotate base/Profiler.cpp @ 282:d9319859a4cf tip

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