From da1e92956fec9387545c824ef4f232845ac0c7ef Mon Sep 17 00:00:00 2001 From: Bartosz Taudul Date: Sat, 28 Sep 2024 16:29:21 +0200 Subject: [PATCH] Enable running time calculation for instrumented zones in flame graph. --- profiler/src/profiler/TracyView.hpp | 3 + .../src/profiler/TracyView_FlameGraph.cpp | 114 +++++++++++++++++- 2 files changed, 114 insertions(+), 3 deletions(-) diff --git a/profiler/src/profiler/TracyView.hpp b/profiler/src/profiler/TracyView.hpp index 3ed19a7f..6697e74a 100644 --- a/profiler/src/profiler/TracyView.hpp +++ b/profiler/src/profiler/TracyView.hpp @@ -277,6 +277,9 @@ private: void DrawFlameGraph(); void DrawFlameGraphHeader( uint64_t timespan ); void DrawFlameGraphItem( const FlameGraphItem& item, FlameGraphContext& ctx, uint64_t ts, int depth, bool samples ); + void BuildFlameGraph( const Worker& worker, Vector& data, const Vector>& zones ); + void BuildFlameGraph( const Worker& worker, Vector& data, const Vector>& zones, const ContextSwitch* ctx ); + void BuildFlameGraph( const Worker& worker, Vector& data, const Vector& samples ); void ListMemData( std::vector& vec, const std::function& DrawAddress, int64_t startTime = -1, uint64_t pool = 0 ); diff --git a/profiler/src/profiler/TracyView_FlameGraph.cpp b/profiler/src/profiler/TracyView_FlameGraph.cpp index 9666564a..7978c54f 100644 --- a/profiler/src/profiler/TracyView_FlameGraph.cpp +++ b/profiler/src/profiler/TracyView_FlameGraph.cpp @@ -20,7 +20,7 @@ struct FlameGraphItem Vector children; }; -static void BuildFlameGraph( const Worker& worker, Vector& data, const Vector>& zones ) +void View::BuildFlameGraph( const Worker& worker, Vector& data, const Vector>& zones ) { FlameGraphItem* it; int16_t last = 0; @@ -112,7 +112,104 @@ static void BuildFlameGraph( const Worker& worker, Vector& data, } } -static void BuildFlameGraph( const Worker& worker, Vector& data, const Vector& samples ) +void View::BuildFlameGraph( const Worker& worker, Vector& data, const Vector>& zones, const ContextSwitch* ctx ) +{ + assert( ctx ); + FlameGraphItem* it; + int16_t last = 0; + + if( zones.is_magic() ) + { + auto& vec = *(Vector*)&zones; + for( auto& v : vec ) + { + if( !v.IsEndValid() ) break; + const auto srcloc = v.SrcLoc(); + int64_t duration; + uint64_t cnt; + if( !GetZoneRunningTime( ctx, v, duration, cnt ) ) break; + if( srcloc == last ) + { + it->time += duration; + if( v.HasChildren() ) + { + auto& children = worker.GetZoneChildren( v.Child() ); + BuildFlameGraph( worker, it->children, children, ctx ); + } + } + else + { + it = std::find_if( data.begin(), data.end(), [srcloc]( const auto& v ) { return v.srcloc == srcloc; } ); + if( it == data.end() ) + { + data.push_back( FlameGraphItem { srcloc, duration } ); + if( v.HasChildren() ) + { + auto& children = worker.GetZoneChildren( v.Child() ); + BuildFlameGraph( worker, data.back().children, children, ctx ); + } + it = &data.back(); + } + else + { + it->time += duration; + if( v.HasChildren() ) + { + auto& children = worker.GetZoneChildren( v.Child() ); + BuildFlameGraph( worker, it->children, children, ctx ); + } + } + last = srcloc; + } + } + } + else + { + for( auto& v : zones ) + { + if( !v->IsEndValid() ) break; + const auto srcloc = v->SrcLoc(); + int64_t duration; + uint64_t cnt; + if( !GetZoneRunningTime( ctx, *v, duration, cnt ) ) break; + if( srcloc == last ) + { + it->time += duration; + if( v->HasChildren() ) + { + auto& children = worker.GetZoneChildren( v->Child() ); + BuildFlameGraph( worker, it->children, children, ctx ); + } + } + else + { + it = std::find_if( data.begin(), data.end(), [srcloc]( const auto& v ) { return v.srcloc == srcloc; } ); + if( it == data.end() ) + { + data.push_back( FlameGraphItem { srcloc, duration } ); + if( v->HasChildren() ) + { + auto& children = worker.GetZoneChildren( v->Child() ); + BuildFlameGraph( worker, data.back().children, children, ctx ); + } + it = &data.back(); + } + else + { + it->time += duration; + if( v->HasChildren() ) + { + auto& children = worker.GetZoneChildren( v->Child() ); + BuildFlameGraph( worker, it->children, children, ctx ); + } + } + last = srcloc; + } + } + } +} + +void View::BuildFlameGraph( const Worker& worker, Vector& data, const Vector& samples ) { for( auto& v : samples ) { @@ -522,7 +619,18 @@ void View::DrawFlameGraph() { for( auto& thread : m_worker.GetThreadData() ) { - if( FlameGraphThread( thread->id ) ) BuildFlameGraph( m_worker, data, thread->timeline ); + if( FlameGraphThread( thread->id ) ) + { + if( m_flameRunningTime ) + { + const auto ctx = m_worker.GetContextSwitchData( thread->id ); + if( ctx ) BuildFlameGraph( m_worker, data, thread->timeline, ctx ); + } + else + { + BuildFlameGraph( m_worker, data, thread->timeline ); + } + } } } else