3 Copyright (C) 2015 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 static Profiler main_profiler
;
24 Profiler
*g_profiler
= &main_profiler
;
25 ScopeProfiler::ScopeProfiler(
26 Profiler
*profiler
, const std::string
&name
, ScopeProfilerType type
) :
28 m_name(name
), m_type(type
)
30 m_name
.append(" [ms]");
32 m_timer
= new TimeTaker(m_name
, nullptr, PRECISION_MILLI
);
35 ScopeProfiler::~ScopeProfiler()
40 float duration_ms
= m_timer
->stop(true);
41 float duration
= duration_ms
/ 1000.0;
45 m_profiler
->add(m_name
, duration
);
48 m_profiler
->avg(m_name
, duration
);
51 m_profiler
->graphAdd(m_name
, duration
);
60 m_start_time
= porting::getTimeMs();
63 void Profiler::add(const std::string
&name
, float value
)
65 MutexAutoLock
lock(m_mutex
);
67 /* No average shall have been used; mark add used as -2 */
68 std::map
<std::string
, int>::iterator n
= m_avgcounts
.find(name
);
69 if (n
== m_avgcounts
.end()) {
70 m_avgcounts
[name
] = -2;
74 assert(n
->second
== -2);
78 std::map
<std::string
, float>::iterator n
= m_data
.find(name
);
79 if (n
== m_data
.end())
86 void Profiler::avg(const std::string
&name
, float value
)
88 MutexAutoLock
lock(m_mutex
);
89 int &count
= m_avgcounts
[name
];
92 count
= MYMAX(count
, 0) + 1;
93 m_data
[name
] += value
;
96 void Profiler::clear()
98 MutexAutoLock
lock(m_mutex
);
99 for (auto &it
: m_data
) {
103 m_start_time
= porting::getTimeMs();
106 float Profiler::getValue(const std::string
&name
) const
108 auto numerator
= m_data
.find(name
);
109 if (numerator
== m_data
.end())
112 auto denominator
= m_avgcounts
.find(name
);
113 if (denominator
!= m_avgcounts
.end()) {
114 if (denominator
->second
>= 1)
115 return numerator
->second
/ denominator
->second
;
118 return numerator
->second
;
121 int Profiler::getAvgCount(const std::string
&name
) const
123 auto n
= m_avgcounts
.find(name
);
125 if (n
!= m_avgcounts
.end() && n
->second
>= 1)
131 u64
Profiler::getElapsedMs() const
133 return porting::getTimeMs() - m_start_time
;
136 int Profiler::print(std::ostream
&o
, u32 page
, u32 pagecount
)
139 getPage(values
, page
, pagecount
);
142 for (const auto &i
: values
) {
143 o
<< " " << i
.first
<< " ";
149 s32 space
= 44 - i
.first
.size();
150 for (s32 j
= 0; j
< space
; j
++) {
151 if ((j
& 1) && j
< space
- 1)
156 porting::mt_snprintf(num_buf
, sizeof(num_buf
), "% 4ix % 3g",
157 getAvgCount(i
.first
), i
.second
);
158 o
<< num_buf
<< std::endl
;
160 return values
.size();
163 void Profiler::getPage(GraphValues
&o
, u32 page
, u32 pagecount
)
165 MutexAutoLock
lock(m_mutex
);
167 u32 minindex
, maxindex
;
168 paging(m_data
.size(), page
, pagecount
, minindex
, maxindex
);
170 for (const auto &i
: m_data
) {
180 o
[i
.first
] = i
.second
/ getAvgCount(i
.first
);