Add documentation to profiler and profiler graph

This commit is contained in:
ZavGaro 2024-06-15 13:37:06 +03:00
parent 85878d894a
commit 7be7d15a02
2 changed files with 66 additions and 4 deletions

@ -30,11 +30,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class ProfilerGraph
{
private:
// One-frame slice of graph values.
struct Piece
{
Piece(Profiler::GraphValues v) : values(std::move(v)) {}
Profiler::GraphValues values;
};
// Data for drawing a one graph. Updates every frame.
struct Meta
{
float min;
@ -54,6 +56,8 @@ class ProfilerGraph
ProfilerGraph() = default;
// Adds graph values to the end of graph (rendered at right side) and
// removes the oldest ones (beyond the `m_log_max_size`).
void put(const Profiler::GraphValues &values);
void draw(s32 x_left, s32 y_bottom, video::IVideoDriver *driver,

@ -29,21 +29,55 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "util/timetaker.h"
#include "util/numeric.h" // paging()
// Global profiler
class Profiler;
// Global profiler. Its data is available for user.
extern Profiler *g_profiler;
/*
Time profiler
*/
Collects data (time intervals and other) in two independent cycles.
- Cycle for profiler graph lasts for one frame and managed in
`Game::updateProfilerGraphs()`, result is displayed by `ProfilerGraph`.
- Cycle for all other data lasts for `profiler_print_interval` seconds (user
setting) and managed in `Game::updateProfilers()`, result is given in text
form by `print` function. User can view it via in-game profiler menu or
"/profiler" command.
All data is cleared at cycle end.
*/
class Profiler
{
public:
Profiler();
/*
Adds value to given profiler entry (`name`). Does not change count
in the entry.
As a resut, profiler will give *sum* of record values as value and "1" as avgCount.
(If only this method is used for given entry between profiler updates)
*/
void add(const std::string &name, float value);
/*
Adds value to given profiler entry (`name`) and increases its record count
by 1.
As a resut, profiler will give *average* of record vaues as value and count of
records as avgCount.
(If only this method is used for given entry between profiler updates)
*/
void avg(const std::string &name, float value);
/*
Sets value to given profiler entry (`name`) if it is larger then existing one and
increases record coutn by 1.
As a resut, profiler will give *max* record value as value and count of records as avgCount.
(If only this method is used for given entry between profiler updates)
*/
void max(const std::string &name, float value);
void clear();
@ -55,6 +89,7 @@ class Profiler
// Returns the line count
int print(std::ostream &o, u32 page = 1, u32 pagecount = 1);
// Writes values on page into `o`.
void getPage(GraphValues &o, u32 page, u32 pagecount);
@ -87,7 +122,10 @@ class Profiler
private:
struct DataPair {
// Recorded value. Recording method depends on used functions (add/avg/max)
// of profiler
float value = 0;
// Count of records.
int avgcount = 0;
inline void reset() {
@ -102,33 +140,53 @@ class Profiler
};
std::mutex m_mutex;
// All the profiler entries, stored untill `clear()` call.
std::map<std::string, DataPair> m_data;
// Values for profiler graph collected untill next frame draw. Value history
// are stored in `ProfilerGraph`.
std::map<std::string, float> m_graphvalues;
u64 m_start_time;
};
enum ScopeProfilerType : u8
{
// Accumulate measurements untill profiler update.
// Profiler will print sum as value and "1" as count.
SPT_ADD = 1,
// Accumulate measurements and record count untill profiler update.
// Profiler will print average value as value and record count as count.
SPT_AVG,
// Accumulate measurements until frame update and then add sum to profiler graph.
SPT_GRAPH_ADD,
// Save only the largest recorded value. Profiler will print them as value and "1" as count.
SPT_MAX
};
// Note: this class should be kept lightweight.
/*
A class for time measurements. Each created object records time from its
construction till scope end.
Note: this class should be kept lightweight.
*/
class ScopeProfiler
{
public:
/*
Begins record untill scope end. Result will be added to `name` profiling
entry in `profiler` (profiling entries are created/deleted automatically).
*/
ScopeProfiler(Profiler *profiler, const std::string &name,
ScopeProfilerType type = SPT_ADD,
TimePrecision precision = PRECISION_MILLI);
// Ends record and logs result in profiler.
~ScopeProfiler();
private:
Profiler *m_profiler = nullptr;
std::string m_name;
u64 m_time1;
u64 m_time1; // Record start time
ScopeProfilerType m_type;
TimePrecision m_precision;
};