Chris@0
|
1 /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@0
|
2
|
Chris@0
|
3 /*
|
Chris@0
|
4 A waveform viewer and audio annotation editor.
|
Chris@2
|
5 Chris Cannam, Queen Mary University of London, 2005-2006
|
Chris@0
|
6
|
Chris@0
|
7 This is experimental software. Not for distribution.
|
Chris@0
|
8 */
|
Chris@0
|
9
|
Chris@0
|
10 /*
|
Chris@0
|
11 This is a modified version of a source file from the
|
Chris@0
|
12 Rosegarden MIDI and audio sequencer and notation editor.
|
Chris@17
|
13 This file copyright 2000-2006 Chris Cannam and Guillaume Laurent.
|
Chris@0
|
14 */
|
Chris@0
|
15
|
Chris@0
|
16 #include <iostream>
|
Chris@0
|
17 #include "Profiler.h"
|
Chris@0
|
18
|
Chris@0
|
19 #include <vector>
|
Chris@0
|
20 #include <algorithm>
|
Chris@0
|
21
|
Chris@0
|
22 //#define NO_TIMING 1
|
Chris@0
|
23
|
Chris@0
|
24 #ifdef NDEBUG
|
Chris@0
|
25 #define NO_TIMING 1
|
Chris@0
|
26 #endif
|
Chris@0
|
27
|
Chris@0
|
28 using std::cerr;
|
Chris@0
|
29 using std::endl;
|
Chris@0
|
30
|
Chris@0
|
31 Profiles* Profiles::m_instance = 0;
|
Chris@0
|
32
|
Chris@0
|
33 Profiles* Profiles::getInstance()
|
Chris@0
|
34 {
|
Chris@0
|
35 if (!m_instance) m_instance = new Profiles();
|
Chris@0
|
36
|
Chris@0
|
37 return m_instance;
|
Chris@0
|
38 }
|
Chris@0
|
39
|
Chris@0
|
40 Profiles::Profiles()
|
Chris@0
|
41 {
|
Chris@0
|
42 }
|
Chris@0
|
43
|
Chris@0
|
44 Profiles::~Profiles()
|
Chris@0
|
45 {
|
Chris@0
|
46 dump();
|
Chris@0
|
47 }
|
Chris@0
|
48
|
Chris@0
|
49 void Profiles::accumulate(const char* id, clock_t time, RealTime rt)
|
Chris@0
|
50 {
|
Chris@0
|
51 #ifndef NO_TIMING
|
Chris@0
|
52 ProfilePair &pair(m_profiles[id]);
|
Chris@0
|
53 ++pair.first;
|
Chris@0
|
54 pair.second.first += time;
|
Chris@0
|
55 pair.second.second = pair.second.second + rt;
|
Chris@0
|
56
|
Chris@0
|
57 TimePair &timePair(m_lastCalls[id]);
|
Chris@0
|
58 timePair.first = time;
|
Chris@0
|
59 timePair.second = rt;
|
Chris@0
|
60 #endif
|
Chris@0
|
61 }
|
Chris@0
|
62
|
Chris@0
|
63 void Profiles::dump()
|
Chris@0
|
64 {
|
Chris@0
|
65 #ifndef NO_TIMING
|
Chris@0
|
66 cerr << "Profiles::dump() :\n";
|
Chris@0
|
67
|
Chris@0
|
68 // I'm finding these two confusing dumped out in random order,
|
Chris@0
|
69 // so I'm going to sort them alphabetically:
|
Chris@0
|
70
|
Chris@0
|
71 std::vector<const char *> profileNames;
|
Chris@0
|
72 for (ProfileMap::iterator i = m_profiles.begin();
|
Chris@0
|
73 i != m_profiles.end(); ++i) {
|
Chris@0
|
74 profileNames.push_back((*i).first);
|
Chris@0
|
75 }
|
Chris@0
|
76
|
Chris@0
|
77 std::sort(profileNames.begin(), profileNames.end());
|
Chris@0
|
78
|
Chris@0
|
79 for (std::vector<const char *>::iterator i = profileNames.begin();
|
Chris@0
|
80 i != profileNames.end(); ++i) {
|
Chris@0
|
81
|
Chris@0
|
82 cerr << "-> " << *i << ": CPU: "
|
Chris@0
|
83 << m_profiles[*i].first << " calls, "
|
Chris@0
|
84 << int((m_profiles[*i].second.first * 1000.0) / CLOCKS_PER_SEC) << "ms, "
|
Chris@0
|
85 << (((double)m_profiles[*i].second.first * 1000000.0 /
|
Chris@0
|
86 (double)m_profiles[*i].first) / CLOCKS_PER_SEC) << "us/call"
|
Chris@0
|
87 << endl;
|
Chris@0
|
88
|
Chris@0
|
89 cerr << "-> " << *i << ": real: "
|
Chris@0
|
90 << m_profiles[*i].first << " calls, "
|
Chris@0
|
91 << m_profiles[*i].second.second << ", "
|
Chris@0
|
92 << (m_profiles[*i].second.second / m_profiles[*i].first)
|
Chris@0
|
93 << "/call"
|
Chris@0
|
94 << endl;
|
Chris@0
|
95
|
Chris@0
|
96 cerr << "-> " << *i << ": last: CPU: "
|
Chris@0
|
97 << int((m_lastCalls[*i].first * 1000.0) / CLOCKS_PER_SEC) << "ms, "
|
Chris@0
|
98 << " real: "
|
Chris@0
|
99 << m_lastCalls[*i].second << endl;
|
Chris@0
|
100 }
|
Chris@0
|
101
|
Chris@0
|
102 cerr << "Profiles::dump() finished\n";
|
Chris@0
|
103 #endif
|
Chris@0
|
104 }
|
Chris@0
|
105
|
Chris@0
|
106 Profiler::Profiler(const char* c, bool showOnDestruct)
|
Chris@0
|
107 : m_c(c),
|
Chris@0
|
108 m_showOnDestruct(showOnDestruct)
|
Chris@0
|
109 {
|
Chris@0
|
110 #ifndef NO_TIMING
|
Chris@0
|
111 m_startCPU = clock();
|
Chris@0
|
112
|
Chris@0
|
113 struct timeval tv;
|
Chris@0
|
114 (void)gettimeofday(&tv, 0);
|
Chris@0
|
115 m_startTime = RealTime(tv.tv_sec, tv.tv_usec * 1000);
|
Chris@0
|
116 #endif
|
Chris@0
|
117 }
|
Chris@0
|
118
|
Chris@0
|
119 void
|
Chris@0
|
120 Profiler::update()
|
Chris@0
|
121 {
|
Chris@0
|
122 #ifndef NO_TIMING
|
Chris@0
|
123 clock_t elapsedCPU = clock() - m_startCPU;
|
Chris@0
|
124
|
Chris@0
|
125 struct timeval tv;
|
Chris@0
|
126 (void)gettimeofday(&tv, 0);
|
Chris@0
|
127 RealTime elapsedTime = RealTime(tv.tv_sec, tv.tv_usec * 1000) - m_startTime;
|
Chris@0
|
128
|
Chris@0
|
129 cerr << "Profiler : id = " << m_c
|
Chris@0
|
130 << " - elapsed so far = " << ((elapsedCPU * 1000) / CLOCKS_PER_SEC)
|
Chris@0
|
131 << "ms CPU, " << elapsedTime << " real" << endl;
|
Chris@0
|
132 #endif
|
Chris@0
|
133 }
|
Chris@0
|
134
|
Chris@0
|
135 Profiler::~Profiler()
|
Chris@0
|
136 {
|
Chris@0
|
137 #ifndef NO_TIMING
|
Chris@0
|
138 clock_t elapsedCPU = clock() - m_startCPU;
|
Chris@0
|
139
|
Chris@0
|
140 struct timeval tv;
|
Chris@0
|
141 (void)gettimeofday(&tv, 0);
|
Chris@0
|
142 RealTime elapsedTime = RealTime(tv.tv_sec, tv.tv_usec * 1000) - m_startTime;
|
Chris@0
|
143
|
Chris@0
|
144 Profiles::getInstance()->accumulate(m_c, elapsedCPU, elapsedTime);
|
Chris@0
|
145
|
Chris@0
|
146 if (m_showOnDestruct)
|
Chris@0
|
147 cerr << "Profiler : id = " << m_c
|
Chris@0
|
148 << " - elapsed = " << ((elapsedCPU * 1000) / CLOCKS_PER_SEC)
|
Chris@0
|
149 << "ms CPU, " << elapsedTime << " real" << endl;
|
Chris@0
|
150 #endif
|
Chris@0
|
151 }
|
Chris@0
|
152
|