Cache flame graph.

This commit is contained in:
Bartosz Taudul 2024-09-29 00:26:00 +02:00
parent 02d60a3dde
commit 346d8a45c6
No known key found for this signature in database
GPG Key ID: B7FE2008B7575DF3
3 changed files with 78 additions and 55 deletions

View File

@ -53,7 +53,6 @@ struct CpuUsageDraw;
struct CpuCtxDraw; struct CpuCtxDraw;
struct LockDraw; struct LockDraw;
struct PlotDraw; struct PlotDraw;
struct FlameGraphItem;
struct FlameGraphContext; struct FlameGraphContext;
@ -902,6 +901,18 @@ private:
bool m_achievements = false; bool m_achievements = false;
TaskDispatch m_td; TaskDispatch m_td;
std::vector<FlameGraphItem> m_flameGraphData;
struct
{
uint64_t count = 0;
uint64_t lastTime = 0;
void Reset()
{
count = 0;
lastTime = 0;
}
} m_flameGraphInvariant;
}; };
} }

View File

@ -13,13 +13,6 @@
namespace tracy namespace tracy
{ {
struct FlameGraphItem
{
int64_t srcloc;
int64_t time;
std::vector<FlameGraphItem> children;
};
void View::BuildFlameGraph( const Worker& worker, std::vector<FlameGraphItem>& data, const Vector<short_ptr<ZoneEvent>>& zones ) void View::BuildFlameGraph( const Worker& worker, std::vector<FlameGraphItem>& data, const Vector<short_ptr<ZoneEvent>>& zones )
{ {
FlameGraphItem* cache; FlameGraphItem* cache;
@ -540,26 +533,26 @@ void View::DrawFlameGraph()
if( ImGui::GetCurrentWindowRead()->SkipItems ) { ImGui::End(); return; } if( ImGui::GetCurrentWindowRead()->SkipItems ) { ImGui::End(); return; }
ImGui::PushStyleVar( ImGuiStyleVar_FramePadding, ImVec2( 2, 2 ) ); ImGui::PushStyleVar( ImGuiStyleVar_FramePadding, ImVec2( 2, 2 ) );
ImGui::RadioButton( ICON_FA_SYRINGE " Instrumentation", &m_flameMode, 0 ); if( ImGui::RadioButton( ICON_FA_SYRINGE " Instrumentation", &m_flameMode, 0 ) ) m_flameGraphInvariant.Reset();
if( m_worker.AreCallstackSamplesReady() && m_worker.GetCallstackSampleCount() > 0 ) if( m_worker.AreCallstackSamplesReady() && m_worker.GetCallstackSampleCount() > 0 )
{ {
ImGui::SameLine(); ImGui::SameLine();
ImGui::RadioButton( ICON_FA_EYE_DROPPER " Sampling", &m_flameMode, 1 ); if( ImGui::RadioButton( ICON_FA_EYE_DROPPER " Sampling", &m_flameMode, 1 ) ) m_flameGraphInvariant.Reset();
} }
ImGui::SameLine(); ImGui::SameLine();
ImGui::SeparatorEx( ImGuiSeparatorFlags_Vertical ); ImGui::SeparatorEx( ImGuiSeparatorFlags_Vertical );
ImGui::SameLine(); ImGui::SameLine();
ImGui::Checkbox( ICON_FA_ARROW_UP_WIDE_SHORT " Sort by time", &m_flameSort ); if( ImGui::Checkbox( ICON_FA_ARROW_UP_WIDE_SHORT " Sort by time", &m_flameSort ) ) m_flameGraphInvariant.Reset();
if( m_flameMode == 0 ) if( m_flameMode == 0 )
{ {
if( m_worker.HasContextSwitches() ) if( m_worker.HasContextSwitches() )
{ {
ImGui::SameLine(); ImGui::SameLine();
ImGui::Checkbox( "Running time", &m_flameRunningTime ); if( ImGui::Checkbox( "Running time", &m_flameRunningTime ) ) m_flameGraphInvariant.Reset();
} }
else else
{ {
@ -593,6 +586,7 @@ void View::DrawFlameGraph()
{ {
FlameGraphThread( t->id ) = true; FlameGraphThread( t->id ) = true;
} }
m_flameGraphInvariant.Reset();
} }
ImGui::SameLine(); ImGui::SameLine();
if( ImGui::SmallButton( "Unselect all" ) ) if( ImGui::SmallButton( "Unselect all" ) )
@ -601,6 +595,7 @@ void View::DrawFlameGraph()
{ {
FlameGraphThread( t->id ) = false; FlameGraphThread( t->id ) = false;
} }
m_flameGraphInvariant.Reset();
} }
int idx = 0; int idx = 0;
@ -610,7 +605,7 @@ void View::DrawFlameGraph()
const auto threadColor = GetThreadColor( t->id, 0 ); const auto threadColor = GetThreadColor( t->id, 0 );
SmallColorBox( threadColor ); SmallColorBox( threadColor );
ImGui::SameLine(); ImGui::SameLine();
SmallCheckbox( m_worker.GetThreadName( t->id ), &FlameGraphThread( t->id ) ); if( SmallCheckbox( m_worker.GetThreadName( t->id ), &FlameGraphThread( t->id ) ) ) m_flameGraphInvariant.Reset();
ImGui::PopID(); ImGui::PopID();
if( t->isFiber ) if( t->isFiber )
{ {
@ -624,6 +619,9 @@ void View::DrawFlameGraph()
ImGui::Separator(); ImGui::Separator();
ImGui::PopStyleVar(); ImGui::PopStyleVar();
if( m_flameMode == 0 && ( m_flameGraphInvariant.count != m_worker.GetZoneCount() || m_flameGraphInvariant.lastTime != m_worker.GetLastTime() ) ||
m_flameMode == 1 && ( m_flameGraphInvariant.count != m_worker.GetCallstackSampleCount() ) )
{
size_t sz = 0; size_t sz = 0;
for( auto& thread : m_threadOrder ) if( FlameGraphThread( thread->id ) ) sz++; for( auto& thread : m_threadOrder ) if( FlameGraphThread( thread->id ) ) sz++;
@ -656,6 +654,9 @@ void View::DrawFlameGraph()
idx++; idx++;
} }
} }
m_flameGraphInvariant.count = m_worker.GetZoneCount();
m_flameGraphInvariant.lastTime = m_worker.GetLastTime();
} }
else else
{ {
@ -669,28 +670,31 @@ void View::DrawFlameGraph()
idx++; idx++;
} }
} }
m_flameGraphInvariant.count = m_worker.GetCallstackSampleCount();
} }
m_td.Sync(); m_td.Sync();
std::vector<FlameGraphItem> data; m_flameGraphData.clear();
if( !threadData.empty() ) if( !threadData.empty() )
{ {
std::swap( data, threadData[0] ); std::swap( m_flameGraphData, threadData[0] );
for( size_t i=1; i<threadData.size(); i++ ) for( size_t i=1; i<threadData.size(); i++ )
{ {
MergeFlameGraph( data, std::move( threadData[i] ) ); MergeFlameGraph( m_flameGraphData, std::move( threadData[i] ) );
} }
} }
if( m_flameSort ) SortFlameGraph( data ); if( m_flameSort ) SortFlameGraph( m_flameGraphData );
}
int64_t zsz = 0; int64_t zsz = 0;
for( auto& v : data ) zsz += v.time; for( auto& v : m_flameGraphData ) zsz += v.time;
ImGui::BeginChild( "##flameGraph" ); ImGui::BeginChild( "##flameGraph" );
const auto region = ImGui::GetContentRegionAvail(); const auto region = ImGui::GetContentRegionAvail();
if( data.empty() ) if( m_flameGraphData.empty() )
{ {
ImGui::PushFont( m_bigFont ); ImGui::PushFont( m_bigFont );
ImGui::Dummy( ImVec2( 0, ( region.y - ImGui::GetTextLineHeight() * 2 ) * 0.5f ) ); ImGui::Dummy( ImVec2( 0, ( region.y - ImGui::GetTextLineHeight() * 2 ) * 0.5f ) );
@ -713,7 +717,7 @@ void View::DrawFlameGraph()
ImGui::ItemSize( region ); ImGui::ItemSize( region );
uint64_t ts = 0; uint64_t ts = 0;
for( auto& v : data ) for( auto& v : m_flameGraphData )
{ {
DrawFlameGraphItem( v, ctx, ts, 0, m_flameMode == 1 ); DrawFlameGraphItem( v, ctx, ts, 0, m_flameMode == 1 );
ts += v.time; ts += v.time;

View File

@ -845,6 +845,14 @@ struct SymbolStats
enum { SymbolStatsSize = sizeof( SymbolStats ) }; enum { SymbolStatsSize = sizeof( SymbolStats ) };
struct FlameGraphItem
{
int64_t srcloc;
int64_t time;
std::vector<FlameGraphItem> children;
};
} }
#endif #endif