0
0
mirror of https://github.com/yse/easy_profiler.git synced 2024-12-28 01:04:41 +08:00

(Core) Calculating total children duration per thread/frame/parent

This commit is contained in:
Victor Zarubkin 2017-04-20 22:29:02 +03:00
parent dff1d8b2a4
commit d1e68e0cec
2 changed files with 52 additions and 10 deletions

View File

@ -63,14 +63,16 @@ namespace profiler {
#pragma pack(push, 1) #pragma pack(push, 1)
struct BlockStatistics EASY_FINAL struct BlockStatistics EASY_FINAL
{ {
::profiler::timestamp_t total_duration; ///< Total duration of all block calls ::profiler::timestamp_t total_duration; ///< Total duration of all block calls
::profiler::block_index_t min_duration_block; ///< Will be used in GUI to jump to the block with min duration ::profiler::timestamp_t total_children_duration; ///< Total duration of all children of all block calls
::profiler::block_index_t max_duration_block; ///< Will be used in GUI to jump to the block with max duration ::profiler::block_index_t min_duration_block; ///< Will be used in GUI to jump to the block with min duration
::profiler::block_index_t parent_block; ///< Index of block which is "parent" for "per_parent_stats" or "frame" for "per_frame_stats" or thread-id for "per_thread_stats" ::profiler::block_index_t max_duration_block; ///< Will be used in GUI to jump to the block with max duration
::profiler::calls_number_t calls_number; ///< Block calls number ::profiler::block_index_t parent_block; ///< Index of block which is "parent" for "per_parent_stats" or "frame" for "per_frame_stats" or thread-id for "per_thread_stats"
::profiler::calls_number_t calls_number; ///< Block calls number
explicit BlockStatistics(::profiler::timestamp_t _duration, ::profiler::block_index_t _block_index, ::profiler::block_index_t _parent_index) explicit BlockStatistics(::profiler::timestamp_t _duration, ::profiler::block_index_t _block_index, ::profiler::block_index_t _parent_index)
: total_duration(_duration) : total_duration(_duration)
, total_children_duration(0)
, min_duration_block(_block_index) , min_duration_block(_block_index)
, max_duration_block(_block_index) , max_duration_block(_block_index)
, parent_block(_parent_index) , parent_block(_parent_index)
@ -106,7 +108,7 @@ namespace profiler {
::profiler::BlockStatistics* per_parent_stats; ///< Pointer to statistics for this block within the parent (may be nullptr for top-level blocks) ::profiler::BlockStatistics* per_parent_stats; ///< Pointer to statistics for this block within the parent (may be nullptr for top-level blocks)
::profiler::BlockStatistics* per_frame_stats; ///< Pointer to statistics for this block within the frame (may be nullptr for top-level blocks) ::profiler::BlockStatistics* per_frame_stats; ///< Pointer to statistics for this block within the frame (may be nullptr for top-level blocks)
::profiler::BlockStatistics* per_thread_stats; ///< Pointer to statistics for this block within the bounds of all frames per current thread ::profiler::BlockStatistics* per_thread_stats; ///< Pointer to statistics for this block within the bounds of all frames per current thread
uint16_t depth; ///< Maximum number of sublevels (maximum children depth) uint8_t depth; ///< Maximum number of sublevels (maximum children depth)
BlocksTree() BlocksTree()
: node(nullptr) : node(nullptr)
@ -205,7 +207,7 @@ namespace profiler {
::profiler::timestamp_t wait_time; ///< Wait time of this thread (sum of all context switches) ::profiler::timestamp_t wait_time; ///< Wait time of this thread (sum of all context switches)
::profiler::thread_id_t thread_id; ///< System Id of this thread ::profiler::thread_id_t thread_id; ///< System Id of this thread
::profiler::block_index_t blocks_number; ///< Total blocks number including their children ::profiler::block_index_t blocks_number; ///< Total blocks number including their children
uint16_t depth; ///< Maximum stack depth (number of levels) uint8_t depth; ///< Maximum stack depth (number of levels)
BlocksTreeRoot() : profiled_time(0), wait_time(0), thread_id(0), blocks_number(0), depth(0) BlocksTreeRoot() : profiled_time(0), wait_time(0), thread_id(0), blocks_number(0), depth(0)
{ {

View File

@ -216,7 +216,7 @@ typedef ::std::unordered_map<::profiler::hashed_stdstring, ::profiler::BlockStat
automatically receive statistics update. automatically receive statistics update.
*/ */
::profiler::BlockStatistics* update_statistics(StatsMap& _stats_map, const ::profiler::BlocksTree& _current, ::profiler::block_index_t _current_index, ::profiler::block_index_t _parent_index, const ::profiler::blocks_t& _blocks) ::profiler::BlockStatistics* update_statistics(StatsMap& _stats_map, const ::profiler::BlocksTree& _current, ::profiler::block_index_t _current_index, ::profiler::block_index_t _parent_index, const ::profiler::blocks_t& _blocks, bool _calculate_children = true)
{ {
auto duration = _current.node->duration(); auto duration = _current.node->duration();
//StatsMap::key_type key(_current.node->name()); //StatsMap::key_type key(_current.node->name());
@ -231,6 +231,12 @@ automatically receive statistics update.
++stats->calls_number; // update calls number of this block ++stats->calls_number; // update calls number of this block
stats->total_duration += duration; // update summary duration of all block calls stats->total_duration += duration; // update summary duration of all block calls
if (_calculate_children)
{
for (auto i : _current.children)
stats->total_children_duration += _blocks[i].node->duration();
}
if (duration > _blocks[stats->max_duration_block].node->duration()) if (duration > _blocks[stats->max_duration_block].node->duration())
{ {
// update max duration // update max duration
@ -256,10 +262,16 @@ automatically receive statistics update.
//_stats_map.emplace(key, stats); //_stats_map.emplace(key, stats);
_stats_map.emplace(_current.node->id(), stats); _stats_map.emplace(_current.node->id(), stats);
if (_calculate_children)
{
for (auto i : _current.children)
stats->total_children_duration += _blocks[i].node->duration();
}
return stats; return stats;
} }
::profiler::BlockStatistics* update_statistics(CsStatsMap& _stats_map, const ::profiler::BlocksTree& _current, ::profiler::block_index_t _current_index, ::profiler::block_index_t _parent_index, const ::profiler::blocks_t& _blocks) ::profiler::BlockStatistics* update_statistics(CsStatsMap& _stats_map, const ::profiler::BlocksTree& _current, ::profiler::block_index_t _current_index, ::profiler::block_index_t _parent_index, const ::profiler::blocks_t& _blocks, bool _calculate_children = true)
{ {
auto duration = _current.node->duration(); auto duration = _current.node->duration();
CsStatsMap::key_type key(_current.node->name()); CsStatsMap::key_type key(_current.node->name());
@ -273,6 +285,12 @@ automatically receive statistics update.
++stats->calls_number; // update calls number of this block ++stats->calls_number; // update calls number of this block
stats->total_duration += duration; // update summary duration of all block calls stats->total_duration += duration; // update summary duration of all block calls
if (_calculate_children)
{
for (auto i : _current.children)
stats->total_children_duration += _blocks[i].node->duration();
}
if (duration > _blocks[stats->max_duration_block].node->duration()) if (duration > _blocks[stats->max_duration_block].node->duration())
{ {
// update max duration // update max duration
@ -297,6 +315,12 @@ automatically receive statistics update.
auto stats = new ::profiler::BlockStatistics(duration, _current_index, _parent_index); auto stats = new ::profiler::BlockStatistics(duration, _current_index, _parent_index);
_stats_map.emplace(key, stats); _stats_map.emplace(key, stats);
if (_calculate_children)
{
for (auto i : _current.children)
stats->total_children_duration += _blocks[i].node->duration();
}
return stats; return stats;
} }
@ -304,9 +328,12 @@ automatically receive statistics update.
void update_statistics_recursive(StatsMap& _stats_map, ::profiler::BlocksTree& _current, ::profiler::block_index_t _current_index, ::profiler::block_index_t _parent_index, ::profiler::blocks_t& _blocks) void update_statistics_recursive(StatsMap& _stats_map, ::profiler::BlocksTree& _current, ::profiler::block_index_t _current_index, ::profiler::block_index_t _parent_index, ::profiler::blocks_t& _blocks)
{ {
_current.per_frame_stats = update_statistics(_stats_map, _current, _current_index, _parent_index, _blocks); _current.per_frame_stats = update_statistics(_stats_map, _current, _current_index, _parent_index, _blocks, false);
for (auto i : _current.children) for (auto i : _current.children)
{
_current.per_frame_stats->total_children_duration += _blocks[i].node->duration();
update_statistics_recursive(_stats_map, _blocks[i], i, _parent_index, _blocks); update_statistics_recursive(_stats_map, _blocks[i], i, _parent_index, _blocks);
}
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -731,6 +758,19 @@ extern "C" {
} }
} }
if (tree.depth == 254)
{
// 254 because we need 1 additional level for root (thread).
// In other words: real stack depth = 1 root block + 254 children
if (*tree.node->name() != 0)
_log << "Stack depth exceeded value of 254\nfor block \"" << desc->name() << "\"";
else
_log << "Stack depth exceeded value of 254\nfor block \"" << desc->name() << "\"\nfrom file \"" << desc->file() << "\":" << desc->line();
return 0;
}
++tree.depth; ++tree.depth;
} }
} }