annotate base/Profiler.cpp @ 101:ce1d385f4f89

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