annotate base/Profiler.cpp @ 162:3fe6660f8fe2

* timestretcher improvements -- simplify API (it can calculate its own processing block sizes etc)
author Chris Cannam
date Wed, 13 Sep 2006 11:56:44 +0000
parents fb8422cf4326
children 146eb9e35baa
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@17 18 This file copyright 2000-2006 Chris Cannam and Guillaume Laurent.
Chris@0 19 */
Chris@0 20
Chris@0 21 #include <iostream>
Chris@0 22 #include "Profiler.h"
Chris@0 23
Chris@0 24 #include <vector>
Chris@0 25 #include <algorithm>
Chris@0 26
Chris@0 27 //#define NO_TIMING 1
Chris@0 28
Chris@135 29 #define WANT_TIMING 1
Chris@135 30
Chris@0 31 #ifdef NDEBUG
Chris@135 32 #ifndef WANT_TIMING
Chris@0 33 #define NO_TIMING 1
Chris@0 34 #endif
Chris@135 35 #endif
Chris@0 36
Chris@0 37 using std::cerr;
Chris@0 38 using std::endl;
Chris@0 39
Chris@0 40 Profiles* Profiles::m_instance = 0;
Chris@0 41
Chris@0 42 Profiles* Profiles::getInstance()
Chris@0 43 {
Chris@0 44 if (!m_instance) m_instance = new Profiles();
Chris@0 45
Chris@0 46 return m_instance;
Chris@0 47 }
Chris@0 48
Chris@0 49 Profiles::Profiles()
Chris@0 50 {
Chris@0 51 }
Chris@0 52
Chris@0 53 Profiles::~Profiles()
Chris@0 54 {
Chris@0 55 dump();
Chris@0 56 }
Chris@0 57
Chris@0 58 void Profiles::accumulate(const char* id, clock_t time, RealTime rt)
Chris@0 59 {
Chris@0 60 #ifndef NO_TIMING
Chris@0 61 ProfilePair &pair(m_profiles[id]);
Chris@0 62 ++pair.first;
Chris@0 63 pair.second.first += time;
Chris@0 64 pair.second.second = pair.second.second + rt;
Chris@0 65
Chris@0 66 TimePair &timePair(m_lastCalls[id]);
Chris@0 67 timePair.first = time;
Chris@0 68 timePair.second = rt;
Chris@0 69 #endif
Chris@0 70 }
Chris@0 71
Chris@0 72 void Profiles::dump()
Chris@0 73 {
Chris@0 74 #ifndef NO_TIMING
Chris@0 75 cerr << "Profiles::dump() :\n";
Chris@0 76
Chris@0 77 // I'm finding these two confusing dumped out in random order,
Chris@0 78 // so I'm going to sort them alphabetically:
Chris@0 79
Chris@0 80 std::vector<const char *> profileNames;
Chris@0 81 for (ProfileMap::iterator i = m_profiles.begin();
Chris@0 82 i != m_profiles.end(); ++i) {
Chris@0 83 profileNames.push_back((*i).first);
Chris@0 84 }
Chris@0 85
Chris@0 86 std::sort(profileNames.begin(), profileNames.end());
Chris@0 87
Chris@0 88 for (std::vector<const char *>::iterator i = profileNames.begin();
Chris@0 89 i != profileNames.end(); ++i) {
Chris@0 90
Chris@0 91 cerr << "-> " << *i << ": CPU: "
Chris@0 92 << m_profiles[*i].first << " calls, "
Chris@0 93 << int((m_profiles[*i].second.first * 1000.0) / CLOCKS_PER_SEC) << "ms, "
Chris@0 94 << (((double)m_profiles[*i].second.first * 1000000.0 /
Chris@0 95 (double)m_profiles[*i].first) / CLOCKS_PER_SEC) << "us/call"
Chris@0 96 << endl;
Chris@0 97
Chris@0 98 cerr << "-> " << *i << ": real: "
Chris@0 99 << m_profiles[*i].first << " calls, "
Chris@0 100 << m_profiles[*i].second.second << ", "
Chris@0 101 << (m_profiles[*i].second.second / m_profiles[*i].first)
Chris@0 102 << "/call"
Chris@0 103 << endl;
Chris@0 104
Chris@0 105 cerr << "-> " << *i << ": last: CPU: "
Chris@0 106 << int((m_lastCalls[*i].first * 1000.0) / CLOCKS_PER_SEC) << "ms, "
Chris@0 107 << " real: "
Chris@0 108 << m_lastCalls[*i].second << endl;
Chris@0 109 }
Chris@0 110
Chris@0 111 cerr << "Profiles::dump() finished\n";
Chris@0 112 #endif
Chris@0 113 }
Chris@0 114
Chris@0 115 Profiler::Profiler(const char* c, bool showOnDestruct)
Chris@0 116 : m_c(c),
Chris@0 117 m_showOnDestruct(showOnDestruct)
Chris@0 118 {
Chris@0 119 #ifndef NO_TIMING
Chris@0 120 m_startCPU = clock();
Chris@0 121
Chris@0 122 struct timeval tv;
Chris@0 123 (void)gettimeofday(&tv, 0);
Chris@26 124 m_startTime = RealTime::fromTimeval(tv);
Chris@0 125 #endif
Chris@0 126 }
Chris@0 127
Chris@0 128 void
Chris@0 129 Profiler::update()
Chris@0 130 {
Chris@0 131 #ifndef NO_TIMING
Chris@0 132 clock_t elapsedCPU = clock() - m_startCPU;
Chris@0 133
Chris@0 134 struct timeval tv;
Chris@0 135 (void)gettimeofday(&tv, 0);
Chris@26 136 RealTime elapsedTime = RealTime::fromTimeval(tv) - m_startTime;
Chris@0 137
Chris@0 138 cerr << "Profiler : id = " << m_c
Chris@0 139 << " - elapsed so far = " << ((elapsedCPU * 1000) / CLOCKS_PER_SEC)
Chris@0 140 << "ms CPU, " << elapsedTime << " real" << endl;
Chris@0 141 #endif
Chris@0 142 }
Chris@0 143
Chris@0 144 Profiler::~Profiler()
Chris@0 145 {
Chris@0 146 #ifndef NO_TIMING
Chris@0 147 clock_t elapsedCPU = clock() - m_startCPU;
Chris@0 148
Chris@0 149 struct timeval tv;
Chris@0 150 (void)gettimeofday(&tv, 0);
Chris@26 151 RealTime elapsedTime = RealTime::fromTimeval(tv) - m_startTime;
Chris@0 152
Chris@0 153 Profiles::getInstance()->accumulate(m_c, elapsedCPU, elapsedTime);
Chris@0 154
Chris@0 155 if (m_showOnDestruct)
Chris@0 156 cerr << "Profiler : id = " << m_c
Chris@0 157 << " - elapsed = " << ((elapsedCPU * 1000) / CLOCKS_PER_SEC)
Chris@0 158 << "ms CPU, " << elapsedTime << " real" << endl;
Chris@0 159 #endif
Chris@0 160 }
Chris@0 161