Exclude context switch samples from the sampling flame graph.

Context switch samples are excluded from the sampling statistics, but
the flame graph built from thread samples included them. Threads which
spend time blocked accumulated large scheduler towers which none of the
other sampling views show, and the flame graph totals did not
correspond to the statistics for the same trace. Filter the samples the
same way the trace load jobs do.
This commit is contained in:
Bartosz Taudul
2026-07-25 22:13:25 +02:00
parent b743c13695
commit 2d5e397c9f
2 changed files with 12 additions and 3 deletions

View File

@@ -360,7 +360,7 @@ private:
void DrawFlameGraphItem( const FlameGraphItem& item, FlameGraphContext& ctx, int depth, bool samples );
void BuildFlameGraph( const Worker& worker, std::vector<FlameGraphItem>& data, const Vector<short_ptr<ZoneEvent>>& zones );
void BuildFlameGraph( const Worker& worker, std::vector<FlameGraphItem>& data, const Vector<short_ptr<ZoneEvent>>& zones, const ContextSwitch* ctx );
void BuildFlameGraph( const Worker& worker, std::vector<FlameGraphItem>& data, const Vector<SampleData>& samples, unordered_flat_map<uint32_t, bool>& externalCache, uint32_t& lastImage, uint32_t& lastSource );
void BuildFlameGraph( const Worker& worker, std::vector<FlameGraphItem>& data, const Vector<SampleData>& samples, const SortedVector<SampleData, SampleDataSort>& ctxSamples, unordered_flat_map<uint32_t, bool>& externalCache, uint32_t& lastImage, uint32_t& lastSource );
void ListMemData( std::vector<const MemEvent*>& vec, const std::function<void(const MemEvent*)>& DrawAddress, int64_t startTime = -1, uint64_t pool = 0 );

View File

@@ -243,7 +243,7 @@ void View::BuildFlameGraph( const Worker& worker, std::vector<FlameGraphItem>& d
}
}
void View::BuildFlameGraph( const Worker& worker, std::vector<FlameGraphItem>& data, const Vector<SampleData>& samples, unordered_flat_map<uint32_t, bool>& externalCache, uint32_t& lastImage, uint32_t& lastSource )
void View::BuildFlameGraph( const Worker& worker, std::vector<FlameGraphItem>& data, const Vector<SampleData>& samples, const SortedVector<SampleData, SampleDataSort>& ctxSamples, unordered_flat_map<uint32_t, bool>& externalCache, uint32_t& lastImage, uint32_t& lastSource )
{
struct FrameCache
{
@@ -254,6 +254,7 @@ void View::BuildFlameGraph( const Worker& worker, std::vector<FlameGraphItem>& d
std::vector<FrameCache> cache;
const SampleData* cit = ctxSamples.begin();
for( auto& v : samples )
{
if ( m_flameGraphInvariant.range.active )
@@ -265,6 +266,14 @@ void View::BuildFlameGraph( const Worker& worker, std::vector<FlameGraphItem>& d
}
}
// Context switch samples are excluded, following the sampling statistics.
if( cit != ctxSamples.end() )
{
const auto vt = v.time.Val();
cit = std::lower_bound( cit, ctxSamples.end(), vt, []( const auto& l, const auto& r ) { return (uint64_t)l.time.Val() < (uint64_t)r; } );
if( cit != ctxSamples.end() && cit->time.Val() == vt ) continue;
}
cache.clear();
const auto cs = v.callstack.Val();
@@ -1149,7 +1158,7 @@ void View::DrawFlameGraph()
unordered_flat_map<uint32_t, bool> externalCache;
uint32_t lastImage = 0;
uint32_t lastSource = 0;
BuildFlameGraph( m_worker, threadData[idx], thread->samples, externalCache, lastImage, lastSource );
BuildFlameGraph( m_worker, threadData[idx], thread->samples, thread->ctxSwitchSamples, externalCache, lastImage, lastSource );
} );
idx++;
}