profiler hierarchy
This commit is contained in:
parent
f446f90266
commit
701e4c5b15
@ -21,36 +21,62 @@
|
|||||||
Profiler* g_profiler = nullptr;
|
Profiler* g_profiler = nullptr;
|
||||||
ProfilerListener* g_profilerListener = nullptr;
|
ProfilerListener* g_profilerListener = nullptr;
|
||||||
|
|
||||||
Profiler::Profiler()
|
Profiler::Profiler() : m_pool(sizeof(ProfilerNode))
|
||||||
{
|
{
|
||||||
|
m_root = nullptr;
|
||||||
m_top = nullptr;
|
m_top = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Profiler::~Profiler()
|
Profiler::~Profiler()
|
||||||
{
|
{
|
||||||
|
B3_ASSERT(m_root == nullptr);
|
||||||
|
B3_ASSERT(m_top == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProfilerNode* Profiler::CreateNode()
|
||||||
|
{
|
||||||
|
void* block = m_pool.Allocate();
|
||||||
|
ProfilerNode* n = new (block) ProfilerNode();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Profiler::DestroyNode(ProfilerNode* node)
|
||||||
|
{
|
||||||
|
node->~ProfilerNode();
|
||||||
|
m_pool.Free(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Profiler::PushEvent(const char* name)
|
void Profiler::PushEvent(const char* name)
|
||||||
{
|
{
|
||||||
m_time.Update();
|
m_time.Update();
|
||||||
|
|
||||||
ProfilerEvent e;
|
ProfilerNode* n = CreateNode();
|
||||||
e.t0 = m_time.GetCurrentMilis();
|
n->name = name;
|
||||||
e.t1 = -1.0;
|
n->t0 = m_time.GetCurrentMilis();
|
||||||
e.name = name;
|
n->t1 = 0.0;
|
||||||
e.parent = m_top;
|
n->parent = m_top;
|
||||||
|
|
||||||
m_events.PushBack(e);
|
if (m_root == nullptr)
|
||||||
|
{
|
||||||
|
m_root = n;
|
||||||
|
m_top = n;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_top = &m_events.Back();
|
if (m_top)
|
||||||
|
{
|
||||||
|
m_top->children.PushBack(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_top = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Profiler::PopEvent()
|
void Profiler::PopEvent()
|
||||||
{
|
{
|
||||||
m_time.Update();
|
m_time.Update();
|
||||||
|
|
||||||
|
B3_ASSERT(m_top != nullptr);
|
||||||
m_top->t1 = m_time.GetCurrentMilis();
|
m_top->t1 = m_time.GetCurrentMilis();
|
||||||
|
|
||||||
B3_ASSERT(m_top->t1 > m_top->t0);
|
B3_ASSERT(m_top->t1 > m_top->t0);
|
||||||
|
|
||||||
m_top = m_top->parent;
|
m_top = m_top->parent;
|
||||||
@ -59,12 +85,41 @@ void Profiler::PopEvent()
|
|||||||
void Profiler::Begin()
|
void Profiler::Begin()
|
||||||
{
|
{
|
||||||
// If this assert is hit then it means Profiler::End hasn't been called.
|
// If this assert is hit then it means Profiler::End hasn't been called.
|
||||||
B3_ASSERT(m_events.IsEmpty());
|
B3_ASSERT(m_root == nullptr);
|
||||||
B3_ASSERT(m_top == NULL);
|
B3_ASSERT(m_top == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void RecurseEvents(ProfilerNode* node)
|
||||||
|
{
|
||||||
|
ProfilerListener* listener = g_profilerListener;
|
||||||
|
|
||||||
|
if (listener)
|
||||||
|
{
|
||||||
|
listener->BeginEvent(node->name, node->t0);
|
||||||
|
|
||||||
|
listener->EndEvent(node->name, node->t1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u32 i = 0; i < node->children.Count(); ++i)
|
||||||
|
{
|
||||||
|
RecurseEvents(node->children[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Profiler::RecurseDestroy(ProfilerNode* node)
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < node->children.Count(); ++i)
|
||||||
|
{
|
||||||
|
RecurseDestroy(node->children[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
DestroyNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Profiler::End()
|
void Profiler::End()
|
||||||
{
|
{
|
||||||
|
B3_ASSERT(m_top == nullptr);
|
||||||
|
|
||||||
ProfilerListener* listener = g_profilerListener;
|
ProfilerListener* listener = g_profilerListener;
|
||||||
|
|
||||||
if (listener)
|
if (listener)
|
||||||
@ -72,22 +127,12 @@ void Profiler::End()
|
|||||||
listener->BeginEvents();
|
listener->BeginEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u32 i = 0; i < m_events.Count(); ++i)
|
RecurseEvents(m_root);
|
||||||
{
|
|
||||||
ProfilerEvent e = m_events[i];
|
RecurseDestroy(m_root);
|
||||||
|
m_root = nullptr;
|
||||||
|
|
||||||
if (listener)
|
B3_ASSERT(m_root == nullptr);
|
||||||
{
|
|
||||||
listener->BeginEvent(e.name, e.t0);
|
|
||||||
|
|
||||||
listener->EndEvent(e.name, e.t1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_events.Resize(0);
|
|
||||||
|
|
||||||
B3_ASSERT(m_events.IsEmpty());
|
|
||||||
B3_ASSERT(m_top == NULL);
|
|
||||||
|
|
||||||
if (listener)
|
if (listener)
|
||||||
{
|
{
|
||||||
|
@ -20,21 +20,23 @@
|
|||||||
#define PROFILER_H
|
#define PROFILER_H
|
||||||
|
|
||||||
#include <bounce/common/math/math.h>
|
#include <bounce/common/math/math.h>
|
||||||
#include <bounce/common/time.h>
|
#include <bounce/common/memory/block_pool.h>
|
||||||
#include <bounce/common/template/array.h>
|
#include <bounce/common/template/array.h>
|
||||||
|
#include <bounce/common/time.h>
|
||||||
|
|
||||||
class ProfilerListener;
|
class ProfilerListener;
|
||||||
|
|
||||||
// A time-stamped profiler event.
|
// Profiler node
|
||||||
struct ProfilerEvent
|
struct ProfilerNode
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
float64 t0;
|
float64 t0;
|
||||||
float64 t1;
|
float64 t1;
|
||||||
ProfilerEvent* parent;
|
ProfilerNode* parent;
|
||||||
|
b3StackArray<ProfilerNode*, 256> children;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A single-threaded event-based profiler.
|
// A single-threaded profiler.
|
||||||
class Profiler
|
class Profiler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -51,17 +53,21 @@ public:
|
|||||||
// This function also flushes the profiler.
|
// This function also flushes the profiler.
|
||||||
void End();
|
void End();
|
||||||
|
|
||||||
// Add a profiler event to the queue.
|
// Push an event.
|
||||||
// You can control the maximum number of profiler events using
|
|
||||||
// MAX_PROFILER_EVENTS.
|
|
||||||
void PushEvent(const char* name);
|
void PushEvent(const char* name);
|
||||||
|
|
||||||
// Remove the top profiler event.
|
// Remove the top profiler event.
|
||||||
void PopEvent();
|
void PopEvent();
|
||||||
private:
|
private:
|
||||||
b3Time m_time;
|
ProfilerNode* CreateNode();
|
||||||
b3StackArray<ProfilerEvent, 256> m_events;
|
void DestroyNode(ProfilerNode* node);
|
||||||
ProfilerEvent* m_top;
|
|
||||||
|
void RecurseDestroy(ProfilerNode* node);
|
||||||
|
|
||||||
|
b3BlockPool m_pool; // pool of nodes
|
||||||
|
b3Time m_time; // timer
|
||||||
|
ProfilerNode* m_root; // tree root node
|
||||||
|
ProfilerNode* m_top; // top node
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Profiler* g_profiler;
|
extern Profiler* g_profiler;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user