mirror of
https://github.com/wolfpld/tracy.git
synced 2024-11-22 22:44:34 +00:00
Apply group filters to the samples statistics in the "find zone" window
reduce memory by storing the thread ids next to the zones intead of making zone lists per thread. speed-up by reading the zones in linear order rather than bisecting the whole list for each sample.
This commit is contained in:
parent
41130d2a69
commit
63acfe72e7
@ -10721,42 +10721,41 @@ void View::DrawFindZone()
|
||||
ImGui::SameLine();
|
||||
if( ImGui::Checkbox( ICON_FA_HAT_WIZARD " Include kernel", &m_statShowKernel ))
|
||||
{
|
||||
m_findZone.samplesCache.scheduleUpdate = true;
|
||||
m_findZone.samples.scheduleUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( !m_findZone.samplesCache.needZonesPerThread )
|
||||
if( !m_findZone.samples.enabled )
|
||||
{
|
||||
m_findZone.samplesCache.needZonesPerThread = true;
|
||||
m_findZone.samples.enabled = true;
|
||||
m_findZone.samples.scheduleUpdate = true;
|
||||
m_findZone.scheduleResetMatch = true;
|
||||
}
|
||||
|
||||
if( m_findZone.samplesCache.scheduleUpdate && !m_findZone.scheduleResetMatch )
|
||||
if( m_findZone.samples.enabled && m_findZone.samples.scheduleUpdate && !m_findZone.scheduleResetMatch )
|
||||
{
|
||||
m_findZone.samplesCache.scheduleUpdate = false;
|
||||
|
||||
m_findZone.samplesCache.timeRange = 0;
|
||||
for( auto& t: m_findZone.samplesCache.threads )
|
||||
{
|
||||
pdqsort_branchless( t.second.begin(), t.second.end(), []( const auto& lhs, const auto& rhs ) { return (*lhs).Start() < (*rhs).Start(); } );
|
||||
|
||||
int64_t prevEnd = 0;
|
||||
for( const auto& it : t.second )
|
||||
{
|
||||
int64_t start = (*it).Start();
|
||||
int64_t end = (*it).End();
|
||||
if( start < prevEnd ) start = prevEnd;
|
||||
if( start < end )
|
||||
{
|
||||
prevEnd = end;
|
||||
m_findZone.samplesCache.timeRange += end - start;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_findZone.samples.scheduleUpdate = false;
|
||||
|
||||
const auto& symMap = m_worker.GetSymbolMap();
|
||||
m_findZone.samplesCache.counts.clear();
|
||||
m_findZone.samplesCache.counts.reserve( symMap.size() );
|
||||
m_findZone.samples.counts.clear();
|
||||
m_findZone.samples.counts.reserve( symMap.size() );
|
||||
|
||||
struct GroupRange {
|
||||
const FindZone::Group* group;
|
||||
Vector<short_ptr<ZoneEvent>>::const_iterator begin;
|
||||
Vector<short_ptr<ZoneEvent>>::const_iterator end;
|
||||
};
|
||||
Vector<GroupRange> selectedGroups;
|
||||
selectedGroups.reserve( m_findZone.groups.size() );
|
||||
for( auto it = m_findZone.groups.begin(); it != m_findZone.groups.end(); ++it )
|
||||
{
|
||||
assert( it->second.zones.size() == it->second.zonesTids.size() );
|
||||
if( ( m_findZone.selGroup == m_findZone.Unselected || it->first == m_findZone.selGroup )
|
||||
&& !it->second.zones.empty() )
|
||||
{
|
||||
selectedGroups.push_back_no_space_check( GroupRange{&it->second} );
|
||||
}
|
||||
}
|
||||
|
||||
for( auto& v : symMap )
|
||||
{
|
||||
@ -10777,37 +10776,81 @@ void View::DrawFindZone()
|
||||
|
||||
auto samples = m_worker.GetSamplesForSymbol( v.first );
|
||||
if( !samples ) continue;
|
||||
if( samples->empty() ) continue;
|
||||
|
||||
uint32_t count = 0;
|
||||
for( auto it: *samples )
|
||||
auto samplesBegin = samples->begin();
|
||||
auto samplesEnd = samples->end();
|
||||
if( m_findZone.range.active )
|
||||
{
|
||||
const auto time = it.time.Val();
|
||||
const auto& zones = m_findZone.samplesCache.threads[it.thread];
|
||||
auto z = std::lower_bound( zones.begin(), zones.end(), time, [] ( const auto& l, const auto& r ) { return l->Start() < r; } );
|
||||
if( z == zones.end() ) continue;
|
||||
if( z != zones.begin() ) --z;
|
||||
if( time >= (*z)->Start() && time < (*z)->End() )
|
||||
count++;
|
||||
const auto rangeMin = m_findZone.range.min;
|
||||
const auto rangeMax = m_findZone.range.max;
|
||||
samplesBegin = std::lower_bound( samplesBegin, samplesEnd, rangeMin, [] ( const auto& lhs, const auto& rhs ) { return lhs.time.Val() < rhs; } );
|
||||
if( samplesBegin != samplesEnd )
|
||||
{
|
||||
samplesEnd = std::lower_bound( samplesBegin, samplesEnd, rangeMax, [] ( const auto& lhs, const auto& rhs ) { return lhs.time.Val() < rhs; } );
|
||||
}
|
||||
}
|
||||
if( count > 0 ) m_findZone.samplesCache.counts.push_back_no_space_check( SymList { v.first, 0, count } );
|
||||
if( samplesBegin == samplesEnd ) continue;
|
||||
|
||||
bool empty = true;
|
||||
const auto firstTime = samplesBegin->time.Val();
|
||||
const auto lastTime = samplesEnd->time.Val();
|
||||
for( auto& g: selectedGroups )
|
||||
{
|
||||
const auto& zones = g.group->zones;
|
||||
auto begin = std::lower_bound( zones.begin(), zones.end(), firstTime, [] ( const auto& l, const auto& r ) { return l->Start() < r; } );
|
||||
auto end = std::upper_bound( begin, zones.end(), lastTime, [] ( const auto& l, const auto& r ) { return l <= r->Start(); } );
|
||||
g.begin = begin;
|
||||
g.end = end;
|
||||
empty = empty && (begin == end);
|
||||
}
|
||||
if (empty) continue;
|
||||
|
||||
uint32_t count = 0;
|
||||
for( auto it = samplesBegin; it != samplesEnd; ++it )
|
||||
{
|
||||
const auto time = it->time.Val();
|
||||
bool pass = false;
|
||||
for( auto& g: selectedGroups )
|
||||
{
|
||||
while( g.begin != g.end && time > (*g.begin)->End() ) ++g.begin;
|
||||
if( g.begin == g.end ) continue;
|
||||
if( time < (*g.begin)->Start() ) continue;
|
||||
|
||||
const auto& tids = g.group->zonesTids;
|
||||
const auto firstZone = g.group->zones.begin();
|
||||
for (auto z = g.begin; z != g.end && (*z)->Start() <= time; ++z)
|
||||
{
|
||||
auto zoneIndex = z - firstZone;
|
||||
if( (*z)->End() > time && it->thread == tids[zoneIndex] )
|
||||
{
|
||||
pass = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( pass ) count ++;
|
||||
}
|
||||
if( count > 0 ) m_findZone.samples.counts.push_back_no_space_check( SymList { v.first, 0, count } );
|
||||
}
|
||||
}
|
||||
|
||||
Vector<SymList> data;
|
||||
data.reserve( m_findZone.samplesCache.counts.size() );
|
||||
for( auto it: m_findZone.samplesCache.counts ) data.push_back_no_space_check( it );
|
||||
DrawSamplesStatistics( data, m_findZone.samplesCache.timeRange, AccumulationMode::SelfOnly );
|
||||
data.reserve( m_findZone.samples.counts.size() );
|
||||
for( auto it: m_findZone.samples.counts ) data.push_back_no_space_check( it );
|
||||
int64_t timeRange = ( m_findZone.selGroup != m_findZone.Unselected ) ? m_findZone.selTotal : m_findZone.total;
|
||||
DrawSamplesStatistics( data, timeRange, AccumulationMode::SelfOnly );
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_findZone.samplesCache.needZonesPerThread )
|
||||
if( m_findZone.samples.enabled )
|
||||
{
|
||||
m_findZone.samplesCache.needZonesPerThread = false;
|
||||
m_findZone.samplesCache.scheduleUpdate = false;
|
||||
m_findZone.samplesCache.counts = Vector<SymList>();
|
||||
m_findZone.samplesCache.threads = unordered_flat_map<uint16_t, Vector<short_ptr<ZoneEvent>> >();
|
||||
m_findZone.samples.enabled = false;
|
||||
m_findZone.samples.scheduleUpdate = false;
|
||||
m_findZone.samples.counts = Vector<SymList>();
|
||||
for( auto& it: m_findZone.groups ) it.second.zonesTids.clear();
|
||||
}
|
||||
}
|
||||
ImGui::Separator();
|
||||
@ -10866,9 +10909,8 @@ void View::DrawFindZone()
|
||||
const auto highlightActive = m_findZone.highlight.active;
|
||||
const auto limitRange = m_findZone.range.active;
|
||||
FindZone::Group* group = nullptr;
|
||||
uint64_t lastGid = std::numeric_limits<uint64_t>::max() - 1;
|
||||
Vector<short_ptr<ZoneEvent>>* threadZones = nullptr;
|
||||
uint16_t lastTid = std::numeric_limits<uint16_t>::max();
|
||||
const uint64_t invalidGid = std::numeric_limits<uint64_t>::max() - 1;
|
||||
uint64_t lastGid = invalidGid;
|
||||
auto zptr = zones.data() + m_findZone.processed;
|
||||
const auto zend = zones.data() + zones.size();
|
||||
while( zptr < zend )
|
||||
@ -10964,27 +11006,25 @@ void View::DrawFindZone()
|
||||
{
|
||||
it = m_findZone.groups.emplace( gid, FindZone::Group { m_findZone.groupId++ } ).first;
|
||||
it->second.zones.reserve( 1024 );
|
||||
if( m_findZone.samples.enabled )
|
||||
it->second.zonesTids.reserve( 1024 );
|
||||
}
|
||||
group = &it->second;
|
||||
}
|
||||
group->time += timespan;
|
||||
group->zones.push_back_non_empty( ev.Zone() );
|
||||
|
||||
|
||||
if( m_findZone.samplesCache.needZonesPerThread )
|
||||
{
|
||||
if( lastTid != ev.Thread() )
|
||||
{
|
||||
lastTid = ev.Thread();
|
||||
threadZones = &m_findZone.samplesCache.threads[lastTid];
|
||||
threadZones->reserve( 1024 );
|
||||
}
|
||||
threadZones->push_back_non_empty( ev.Zone() );
|
||||
m_findZone.samplesCache.scheduleUpdate = true;
|
||||
}
|
||||
if( m_findZone.samples.enabled )
|
||||
group->zonesTids.push_back_non_empty( ev.Thread() );
|
||||
}
|
||||
m_findZone.processed = zptr - zones.data();
|
||||
|
||||
const bool groupsUpdated = lastGid != invalidGid;
|
||||
if( m_findZone.samples.enabled && groupsUpdated )
|
||||
{
|
||||
m_findZone.samples.scheduleUpdate = true;
|
||||
}
|
||||
|
||||
|
||||
Vector<decltype( m_findZone.groups )::iterator> groups;
|
||||
groups.reserve_and_use( m_findZone.groups.size() );
|
||||
int idx = 0;
|
||||
|
@ -516,6 +516,7 @@ private:
|
||||
{
|
||||
uint16_t id;
|
||||
Vector<short_ptr<ZoneEvent>> zones;
|
||||
Vector<uint16_t> zonesTids;
|
||||
int64_t time = 0;
|
||||
};
|
||||
|
||||
@ -563,12 +564,10 @@ private:
|
||||
} binCache;
|
||||
|
||||
struct {
|
||||
unordered_flat_map<uint16_t, Vector<short_ptr<ZoneEvent>> > threads;
|
||||
Vector<SymList> counts;
|
||||
int64_t timeRange = 0;
|
||||
bool scheduleUpdate = false;
|
||||
bool needZonesPerThread = false;
|
||||
} samplesCache;
|
||||
bool enabled = false;
|
||||
} samples;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
@ -595,8 +594,6 @@ private:
|
||||
{
|
||||
ResetSelection();
|
||||
groups.clear();
|
||||
samplesCache.threads.clear();
|
||||
samplesCache.counts.clear();
|
||||
processed = 0;
|
||||
groupId = 0;
|
||||
selCs = 0;
|
||||
@ -613,6 +610,8 @@ private:
|
||||
selTotal = 0;
|
||||
selTime = 0;
|
||||
binCache.numBins = -1;
|
||||
samples.counts.clear();
|
||||
samples.scheduleUpdate = true;
|
||||
}
|
||||
|
||||
void ShowZone( int16_t srcloc, const char* name )
|
||||
|
Loading…
Reference in New Issue
Block a user