mirror of
https://github.com/wolfpld/tracy.git
synced 2025-03-20 07:40:02 +08:00
Greatly simplify call stack tree calculation.
Instead of caching paths, compute accumulated cost of each path and only then create the tree, going through each path just once.
This commit is contained in:
parent
e1821e439a
commit
6224daf9c9
@ -6537,9 +6537,15 @@ static tracy_force_inline CallstackFrameTree* GetFrameTreeItem( std::vector<Call
|
|||||||
|
|
||||||
std::vector<CallstackFrameTree> View::GetCallstackFrameTree( const MemData& mem ) const
|
std::vector<CallstackFrameTree> View::GetCallstackFrameTree( const MemData& mem ) const
|
||||||
{
|
{
|
||||||
|
struct PathData
|
||||||
|
{
|
||||||
|
uint32_t cnt;
|
||||||
|
uint64_t mem;
|
||||||
|
};
|
||||||
|
|
||||||
std::vector<CallstackFrameTree> root;
|
std::vector<CallstackFrameTree> root;
|
||||||
std::vector<Vector<uint32_t>> paths;
|
flat_hash_map<uint32_t, PathData, nohash<uint32_t>> pathSum;
|
||||||
paths.resize( m_worker.GetCallstackPayloadCount() );
|
pathSum.reserve( m_worker.GetCallstackPayloadCount() );
|
||||||
|
|
||||||
const auto zvMid = m_zvStart + ( m_zvEnd - m_zvStart ) / 2;
|
const auto zvMid = m_zvStart + ( m_zvEnd - m_zvStart ) / 2;
|
||||||
|
|
||||||
@ -6548,49 +6554,37 @@ std::vector<CallstackFrameTree> View::GetCallstackFrameTree( const MemData& mem
|
|||||||
if( ev.csAlloc == 0 ) continue;
|
if( ev.csAlloc == 0 ) continue;
|
||||||
if( m_memInfo.restrictTime && ev.timeAlloc >= zvMid ) continue;
|
if( m_memInfo.restrictTime && ev.timeAlloc >= zvMid ) continue;
|
||||||
|
|
||||||
auto& path = paths[ev.csAlloc];
|
auto it = pathSum.find( ev.csAlloc );
|
||||||
if( !path.empty() )
|
if( it == pathSum.end() )
|
||||||
{
|
{
|
||||||
auto treePtr = &root;
|
pathSum.emplace( ev.csAlloc, PathData { 1, ev.size } );
|
||||||
CallstackFrameTree* node = nullptr;
|
|
||||||
for( auto& v : path )
|
|
||||||
{
|
|
||||||
node = treePtr->data() + v;
|
|
||||||
node->countInclusive++;
|
|
||||||
node->allocInclusive += ev.size;
|
|
||||||
treePtr = &node->children;
|
|
||||||
}
|
|
||||||
assert( treePtr->empty() );
|
|
||||||
node->countExclusive++;
|
|
||||||
node->allocExclusive += ev.size;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto& cs = m_worker.GetCallstack( ev.csAlloc );
|
it->second.cnt++;
|
||||||
Vector<uint32_t> path;
|
it->second.mem += ev.size;
|
||||||
path.reserve( cs.size() );
|
|
||||||
|
|
||||||
auto base = cs.back();
|
|
||||||
auto treePtr = GetFrameTreeItem( root, base );
|
|
||||||
treePtr->countInclusive++;
|
|
||||||
treePtr->allocInclusive += ev.size;
|
|
||||||
path.push_back( uint32_t( treePtr - root.data() ) );
|
|
||||||
|
|
||||||
for( int i = int( cs.size() ) - 2; i >= 0; i-- )
|
|
||||||
{
|
|
||||||
auto newTreePtr = GetFrameTreeItem( treePtr->children, cs[i] );
|
|
||||||
newTreePtr->countInclusive++;
|
|
||||||
newTreePtr->allocInclusive += ev.size;
|
|
||||||
path.push_back( uint32_t( newTreePtr - treePtr->children.data() ) );
|
|
||||||
treePtr = newTreePtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
treePtr->countExclusive++;
|
|
||||||
treePtr->allocExclusive += ev.size;
|
|
||||||
|
|
||||||
paths[ev.csAlloc] = std::move( path );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for( auto& path : pathSum )
|
||||||
|
{
|
||||||
|
auto& cs = m_worker.GetCallstack( path.first );
|
||||||
|
|
||||||
|
auto base = cs.back();
|
||||||
|
auto treePtr = GetFrameTreeItem( root, base );
|
||||||
|
treePtr->countInclusive += path.second.cnt;
|
||||||
|
treePtr->allocInclusive += path.second.mem;
|
||||||
|
|
||||||
|
for( int i = int( cs.size() ) - 2; i >= 0; i-- )
|
||||||
|
{
|
||||||
|
treePtr = GetFrameTreeItem( treePtr->children, cs[i] );
|
||||||
|
treePtr->countInclusive += path.second.cnt;
|
||||||
|
treePtr->allocInclusive += path.second.mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
treePtr->countExclusive += path.second.cnt;
|
||||||
|
treePtr->allocExclusive += path.second.mem;
|
||||||
|
}
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user