// USAGE:
// - Just adding *Enter* and *Exit* are required on where you want to analyze.
// I recommend put a *Enter* function on the very beginning of each target
// function and correspondingly put a *Exit* function on the very end of
// each target function.
// - It generates the output file as csv format. Reading the csv file can be
// a little hard...
#ifndef PROFILER_H
#define PROFILER_H
typedef unsigned __int64 uint64;
#include <vector>
#include <string>
struct FunctionNode
{
FunctionNode()
{
callCount = 0;
recursionCount = 0;
recursionCountMax = 0;
cyclesStart = 0;
cyclesTotal = 0;
cyclesExclusive = 0;
nodePrev = nullptr;
nodeNext = nullptr;
}
// ID for each function
// it's not unique! Ref. ProfilerTestFuncSameButDiffParent and FindByName
std::string functionName;
unsigned callCount;
unsigned recursionCount;
unsigned recursionCountMax;
uint64 cyclesStart;
uint64 cyclesTotal;
// excluding nested function calls
// warning! this will be calculated in the last step, PrintInfoToCSV
uint64 cyclesExclusive;
FunctionNode* nodePrev;
FunctionNode* nodeNext;
std::vector<FunctionNode*> children;
};
class Profiler
{
public:
static Profiler* GetInstance();
// Use __FUNCSIG__ for its ID
// it's not unique! Ref. ProfilerTestFuncSameButDiffParent and FindByName
void Enter(const std::string ID);
void Exit();
// Test functions
void ProfilerTestFuncRecursion(const unsigned count);
void ProfilerTestFuncSameButDiffParent();
private:
Profiler();
~Profiler();
void Init(FunctionNode* root);
void Destroy(const uint64 cycles);
// search from m_NodeCurr ONLY to m_NodePrev (parent)
FunctionNode* FindByName(FunctionNode* node, const std::string name);
// CSV
void PrintInfoToCSV(std::ofstream& csvFile, FunctionNode* function, const unsigned depth);
void PrintHeader(std::ofstream& csvFile, const unsigned depth);
uint64 GetExclusiveTime(FunctionNode* node); // to get the exclusive time
FunctionNode* m_NodeRoot;
FunctionNode* m_NodeCurr;
uint64 m_CyclesStart;
uint64 m_CyclesTotal;
float m_CyclesPerSec; // to mesure the speed of this processor
};
#endif