Skyscraper 2.0
profiler.cpp
Go to the documentation of this file.
1#include <OgreBulletDynamicsWorld.h>
2#include <OgrePlatform.h>
3#include "globals.h"
4#include "sbs.h"
5#include "profiler.h"
6
7static oClock gProfileClock;
8
9#if OGRE_PLATFORM != OGRE_PLATFORM_WIN32
10 #define _snprintf snprintf
11#endif
12
13namespace SBS {
14
15bool SBSIMPEXP enable_profiling; //enable general profiling
17
18/*
19
20***************************************************************************************************
21**
22** profile.cpp
23**
24** Real-Time Hierarchical Profiling for Game Programming Gems 3
25**
26** by Greg Hjelstrom & Byon Garrabrant
27**
28***************************************************************************************************/
29
30inline void Profile_Get_Ticks(unsigned long int * ticks)
31{
32 *ticks = gProfileClock.getTimeMicroseconds();
33}
34
35inline float Profile_Get_Tick_Rate(void)
36{
37// return 1000000.f;
38 return 1000.f;
39
40}
41
42/***************************************************************************************************
43**
44** ProfileNode
45**
46***************************************************************************************************/
47
48/***********************************************************************************************
49 * INPUT: *
50 * name - pointer to a static string which is the name of this profile node *
51 * parent - parent pointer *
52 * *
53 * WARNINGS: *
54 * The name is assumed to be a static pointer, only the pointer is stored and compared for *
55 * efficiency reasons. *
56 *=============================================================================================*/
57ProfileNode::ProfileNode( const char * name, ProfileNode * parent ) :
58 Name( name ),
59 TotalCalls( 0 ),
60 TotalTime( 0 ),
61 StartTime( 0 ),
62 RecursionCounter( 0 ),
63 Parent( parent ),
64 Child( NULL ),
65 Sibling( NULL )
66{
67 Reset();
68}
69
70
72{
73 delete ( Child);
74 Child = NULL;
75 delete ( Sibling);
76 Sibling = NULL;
77}
78
80{
81 delete ( Child);
82 delete ( Sibling);
83}
84
85
86/***********************************************************************************************
87 * INPUT: *
88 * name - static string pointer to the name of the node we are searching for *
89 * *
90 * WARNINGS: *
91 * All profile names are assumed to be static strings so this function uses pointer compares *
92 * to find the named node. *
93 *=============================================================================================*/
95{
96 // Try to find this sub node
97 ProfileNode * child = Child;
98 while ( child ) {
99 if ( child->Name == name ) {
100 return child;
101 }
102 child = child->Sibling;
103 }
104
105 // We didn't find it, so add it
106
107 ProfileNode * node = new ProfileNode( name, this );
108 node->Sibling = Child;
109 Child = node;
110 return node;
111}
112
113
115{
116 TotalCalls = 0;
117 TotalTime = 0.0f;
118
119
120 if ( Child ) {
121 Child->Reset();
122 }
123 if ( Sibling ) {
124 Sibling->Reset();
125 }
126}
127
128
130{
131 TotalCalls++;
132 if (RecursionCounter++ == 0) {
134 }
135}
136
137
139{
140 if ( --RecursionCounter == 0 && TotalCalls != 0 ) {
141 unsigned long int time;
142 Profile_Get_Ticks(&time);
143 time -= StartTime;
144 TotalTime += (float)time / Profile_Get_Tick_Rate();
145 }
146 return ( RecursionCounter == 0 );
147}
148
149
150/***************************************************************************************************
151**
152** ProfileIterator
153**
154***************************************************************************************************/
160
161
166
167
172
173
175{
176 return CurrentChild == NULL;
177}
178
179
181{
183 while ( (CurrentChild != NULL) && (index != 0) ) {
184 index--;
186 }
187
188 if ( CurrentChild != NULL ) {
191 }
192}
193
194
202
203
204/***************************************************************************************************
205**
206** ProfileManager
207**
208***************************************************************************************************/
209
210ProfileNode ProfileManager::Root( "Root", NULL );
213unsigned long int ProfileManager::ResetTime = 0;
214
215
216/***********************************************************************************************
217 * ProfileManager::Start_Profile -- Begin a named profile *
218 * *
219 * Steps one level deeper into the tree, if a child already exists with the specified name *
220 * then it accumulates the profiling; otherwise a new child node is added to the profile tree. *
221 * *
222 * INPUT: *
223 * name - name of this profiling record *
224 * *
225 * WARNINGS: *
226 * The string used is assumed to be a static string; pointer compares are used throughout *
227 * the profiling code for efficiency. *
228 *=============================================================================================*/
229void ProfileManager::Start_Profile( const char * name )
230{
231 if (enable_profiling == false)
232 return;
233
234 if (name != CurrentNode->Get_Name()) {
236 }
237
238 CurrentNode->Call();
239}
240
241
242/***********************************************************************************************
243 * ProfileManager::Stop_Profile -- Stop timing and record the results. *
244 *=============================================================================================*/
246{
247 if (enable_profiling == false)
248 return;
249
250 // Return will indicate whether we should back up to our parent (we may
251 // be profiling a recursive function)
252 if (CurrentNode->Return()) {
254 }
255}
256
257
258/***********************************************************************************************
259 * ProfileManager::Reset -- Reset the contents of the profiling system *
260 * *
261 * This resets everything except for the tree structure. All of the timing data is reset. *
262 *=============================================================================================*/
264{
265 if (enable_profiling == false)
266 return;
267
268 gProfileClock.reset();
269 Root.Reset();
270 Root.Call();
271 FrameCounter = 0;
273}
274
275
276/***********************************************************************************************
277 * ProfileManager::Increment_Frame_Counter -- Increment the frame counter *
278 *=============================================================================================*/
280{
281 if (enable_profiling == false)
282 return;
283
284 FrameCounter++;
285}
286
287
288/***********************************************************************************************
289 * ProfileManager::Get_Time_Since_Reset -- returns the elapsed time since last reset *
290 *=============================================================================================*/
292{
293 unsigned long int time;
294 Profile_Get_Ticks(&time);
295 time -= ResetTime;
296 return (float)time / Profile_Get_Tick_Rate();
297}
298
299#include <stdio.h>
300
301void ProfileManager::dumpRecursive(std::string &output, ProfileIterator* profileIterator, int spacing)
302{
303 if (enable_profiling == false)
304 return;
305
306 profileIterator->First();
307 if (profileIterator->Is_Done())
308 return;
309
310 float accumulated_time=0, parent_time = profileIterator->Is_Root() ? ProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time();
311 int frames_since_reset = ProfileManager::Get_Frame_Count_Since_Reset();
312 for (int i = 0; i < spacing; i++)
313 output.append(".");
314 output.append("----------------------------------\n");
315 for (int i = 0; i < spacing; i++)
316 output.append(".");
317 char buffer[1000];
318 _snprintf(buffer, 1000, "Profiling: %s (total running time: %.3f ms) ---\n", profileIterator->Get_Current_Parent_Name(), parent_time);
319 output.append(buffer);
320 float totalTime = 0.f;
321
322
323 int numChildren = 0;
324
325 for (int i = 0; !profileIterator->Is_Done(); i++, profileIterator->Next())
326 {
327 numChildren++;
328 float current_total_time = profileIterator->Get_Current_Total_Time();
329 accumulated_time += current_total_time;
330 float fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f;
331 for (int j = 0; j < spacing; j++)
332 output.append(".");
333 _snprintf(buffer, 1000, "%d -- %s (%.2f %%) :: %.3f ms / frame (%d calls)\n", i, profileIterator->Get_Current_Name(), fraction,(current_total_time / (double)frames_since_reset), profileIterator->Get_Current_Total_Calls());
334 output.append(buffer);
335 totalTime += current_total_time;
336 //recurse into children
337 }
338
339 if (parent_time < accumulated_time)
340 {
341 output.append("what's wrong\n");
342 }
343 for (int i = 0; i < spacing; i++)
344 output.append(".");
345 _snprintf(buffer, 1000, "%s (%.3f %%) :: %.3f ms\n", "Unaccounted:", parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
346 output.append(buffer);
347
348 for (int i = 0; i < numChildren; i++)
349 {
350 profileIterator->Enter_Child(i);
351 dumpRecursive(output, profileIterator, spacing + 3);
352 profileIterator->Enter_Parent();
353 }
354}
355
356void ProfileManager::dumpAll(std::string &output)
357{
358 ProfileIterator* profileIterator = 0;
359 profileIterator = ProfileManager::Get_Iterator();
360
361 dumpRecursive(output, profileIterator, 0);
362 //printf("%s\n", output.c_str());
363
364 ProfileManager::Release_Iterator(profileIterator);
365}
366
367ProfileSample::ProfileSample( const char * name, bool advanced )
368{
369 is_advanced = advanced;
370 if (is_advanced == true && enable_advanced_profiling == false)
371 return;
373}
374
376{
377 if (is_advanced == true && enable_advanced_profiling == false)
378 return;
380}
381
382}
An iterator to navigate through the tree.
Definition profiler.h:53
int Get_Current_Total_Calls(void)
Definition profiler.h:67
ProfileIterator(ProfileNode *start)
Definition profiler.cpp:155
const char * Get_Current_Parent_Name(void)
Definition profiler.h:71
const char * Get_Current_Name(void)
Definition profiler.h:66
ProfileNode * CurrentParent
Definition profiler.h:77
bool Is_Root(void)
Definition profiler.h:59
float Get_Current_Parent_Total_Time(void)
Definition profiler.h:73
ProfileNode * CurrentChild
Definition profiler.h:78
void Enter_Parent(void)
Definition profiler.cpp:195
float Get_Current_Total_Time(void)
Definition profiler.h:68
void Enter_Child(int index)
Definition profiler.cpp:180
static void Reset(void)
Definition profiler.cpp:263
static void dumpRecursive(std::string &output, ProfileIterator *profileIterator, int spacing)
Definition profiler.cpp:301
static float Get_Time_Since_Reset(void)
Definition profiler.cpp:291
static void Stop_Profile(void)
Definition profiler.cpp:245
static ProfileNode Root
Definition profiler.h:113
static void Release_Iterator(ProfileIterator *iterator)
Definition profiler.h:106
static void Start_Profile(const char *name)
Definition profiler.cpp:229
static void Increment_Frame_Counter(void)
Definition profiler.cpp:279
static int Get_Frame_Count_Since_Reset(void)
Definition profiler.h:98
static unsigned long int ResetTime
Definition profiler.h:116
static int FrameCounter
Definition profiler.h:115
static ProfileNode * CurrentNode
Definition profiler.h:114
static void dumpAll(std::string &output)
Definition profiler.cpp:356
static ProfileIterator * Get_Iterator(void)
Definition profiler.h:101
A node in the Profile Hierarchy Tree.
Definition profiler.h:17
ProfileNode(const char *name, ProfileNode *parent)
Definition profiler.cpp:57
ProfileNode * Get_Child(void)
Definition profiler.h:27
ProfileNode * Child
Definition profiler.h:47
ProfileNode * Sibling
Definition profiler.h:48
ProfileNode * Get_Sibling(void)
Definition profiler.h:26
void Reset(void)
Definition profiler.cpp:114
unsigned long int StartTime
Definition profiler.h:43
ProfileNode * Get_Parent(void)
Definition profiler.h:25
ProfileNode * Get_Sub_Node(const char *name)
Definition profiler.cpp:94
bool Return(void)
Definition profiler.cpp:138
void Call(void)
Definition profiler.cpp:129
const char * Name
Definition profiler.h:40
const char * Get_Name(void)
Definition profiler.h:34
void CleanupMemory()
Definition profiler.cpp:71
ProfileSample(const char *name, bool advanced=true)
Definition profiler.cpp:367
#define SBSIMPEXP
Definition globals.h:53
bool SBSIMPEXP enable_profiling
Definition profiler.cpp:15
bool SBSIMPEXP enable_advanced_profiling
Definition profiler.cpp:16
float Profile_Get_Tick_Rate(void)
Definition profiler.cpp:35
void Profile_Get_Ticks(unsigned long int *ticks)
Definition profiler.cpp:30
static oClock gProfileClock
Definition profiler.cpp:7