Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
ProfileTimer.cpp
Go to the documentation of this file.
1
2
3#include "config.h"
4
7
9
10namespace Divide::Time {
11
12namespace {
13 std::array<ProfileTimer, Config::Profile::MAX_PROFILE_TIMERS> g_profileTimers;
14 std::array<bool, Config::Profile::MAX_PROFILE_TIMERS> g_profileTimersState;
15
16 bool g_timersInit = false;
17}
18
20 : _timer(timer)
21{
22 _timer.start();
23}
24
26{
27 _timer.stop();
28}
29
30void ProfileTimer::start() noexcept
31{
33}
34
35void ProfileTimer::stop() noexcept
36{
39}
40
41void ProfileTimer::reset() noexcept
42{
43 _timerAverage = 0u;
44 _timerCounter = 0u;
45}
46
48{
49 // must not have a parent
51 // must be unique child
52 assert(!hasChildTimer(child));
53
54 _children.push_back(child._globalIndex);
55 child._parent = _globalIndex;
56}
57
59{
60 erase_if(_children, [childID = child._globalIndex](const U32 entry) { return entry == childID; });
62}
63
65{
66 return eastl::any_of(cbegin(_children),
67 cend(_children),
68 [childID = child._globalIndex](const U32 entry) {
69 return entry == childID;
70 });
71}
72
74{
75 U64 ret = 0u;
76 for (const U32 child : _children)
77 {
78 if (g_profileTimersState[child])
79 {
80 ret += g_profileTimers[child].get();
81 }
82 }
83
84 return ret;
85}
86
87string ProfileTimer::print(const U32 level) const
88{
89 string ret = Util::StringFormat("[ {} ] : [ {:5.3f} ms]", _name, MicrosecondsToMilliseconds<F32>(get()));
90
91 for (const U32 child : _children)
92 {
93 if (g_profileTimersState[child])
94 {
95 ret.append("\n " + g_profileTimers[child].print(level + 1));
96 }
97 }
98
99 for (U32 i = 0u; i < level; ++i)
100 {
101 ret.insert(0, " ");
102 }
103
104 return ret;
105}
106
108{
109 constexpr U8 overheadLoopCount = 3u;
110
111 U64 overhead = 0u;
112 ProfileTimer test;
113
114 for (U8 i = 0u; i < overheadLoopCount; ++i)
115 {
116 test.start();
117 test.stop();
118 overhead += test.get();
119 }
120
121 return overhead / overheadLoopCount;
122}
123
125{
126 string ret(Util::StringFormat("Profiler overhead: [{} us]\n", overhead()));
127
128 for (ProfileTimer& entry : g_profileTimers)
129 {
130 if (!g_profileTimersState[entry._globalIndex] ||
132 entry._timerCounter == 0u)
133 {
134 continue;
135 }
136
137 ret.append(entry.print());
138 ret.append("\n");
139 entry.reset();
140 }
141
142 return ret;
143}
144
146{
147 if (!g_timersInit)
148 {
149 g_profileTimersState.fill(false);
150
151 U32 index = 0u;
152 for (ProfileTimer& entry : g_profileTimers)
153 {
154 entry._globalIndex = index++;
155 }
156 g_timersInit = true;
157 }
158
159 for (ProfileTimer& entry : g_profileTimers)
160 {
161 if (!g_profileTimersState[entry._globalIndex])
162 {
163 entry.reset();
164 entry._name = timerName;
165 g_profileTimersState[entry._globalIndex] = true;
166 return entry;
167 }
168 }
169
170 DIVIDE_UNEXPECTED_CALL_MSG("Reached max profile timer count!");
171 return g_profileTimers[0];
172}
173
175{
176 g_profileTimersState[timer._globalIndex] = false;
178 {
179 g_profileTimers[timer._parent].removeChildTimer(timer);
180 }
181}
182
183} // namespace Divide::Time
#define DIVIDE_UNEXPECTED_CALL_MSG(X)
void removeChildTimer(ProfileTimer &child)
void addChildTimer(ProfileTimer &child)
static void removeTimer(ProfileTimer &timer)
static ProfileTimer & getNewTimer(const char *timerName)
string print(U32 level=0) const
bool hasChildTimer(const ProfileTimer &child) const
ScopedTimer(ProfileTimer &timer) noexcept
constexpr unsigned short MAX_PROFILE_TIMERS
How many profiling timers are we allowed to use in our applications. We allocate them upfront,...
Definition: config.h:84
U64 ElapsedMicroseconds() noexcept
std::array< ProfileTimer, Config::Profile::MAX_PROFILE_TIMERS > g_profileTimers
std::array< bool, Config::Profile::MAX_PROFILE_TIMERS > g_profileTimersState
Str StringFormat(const char *fmt, Args &&...args)
uint8_t U8
uint32_t U32
Project const SceneEntry & entry
Definition: DefaultScene.h:41
uint64_t U64