diff --git a/src/gui/profilergraph.h b/src/gui/profilergraph.h index 6354ac9ef..186304468 100644 --- a/src/gui/profilergraph.h +++ b/src/gui/profilergraph.h @@ -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, diff --git a/src/profiler.h b/src/profiler.h index e7135d9c2..3e28b8e24 100644 --- a/src/profiler.h +++ b/src/profiler.h @@ -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 m_data; + // Values for profiler graph collected untill next frame draw. Value history + // are stored in `ProfilerGraph`. std::map 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; };