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
|