mirror of
https://github.com/wolfpld/tracy
synced 2025-05-06 07:03:52 +00:00
Replace linear search with hash lookup.
This commit is contained in:
parent
82dad3fb97
commit
a7886cf82c
@ -204,7 +204,7 @@ struct CallstackFrameTree
|
|||||||
CallstackFrameId frame;
|
CallstackFrameId frame;
|
||||||
uint64_t alloc;
|
uint64_t alloc;
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
std::vector<CallstackFrameTree> children;
|
flat_hash_map<uint64_t, CallstackFrameTree, nohash<uint64_t>> children;
|
||||||
flat_hash_set<uint32_t, nohash<uint32_t>> callstacks;
|
flat_hash_set<uint32_t, nohash<uint32_t>> callstacks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8961,34 +8961,28 @@ void View::ListMemData( T ptr, T end, std::function<void(T&)> DrawAddress, const
|
|||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
}
|
}
|
||||||
|
|
||||||
static tracy_force_inline CallstackFrameTree* GetFrameTreeItem( std::vector<CallstackFrameTree>& tree, CallstackFrameId idx, const Worker& worker, bool groupByName )
|
static tracy_force_inline CallstackFrameTree* GetFrameTreeItemNoGroup( flat_hash_map<uint64_t, CallstackFrameTree, nohash<uint64_t>>& tree, CallstackFrameId idx, const Worker& worker )
|
||||||
{
|
{
|
||||||
std::vector<CallstackFrameTree>::iterator it;
|
auto it = tree.find( idx.data );
|
||||||
if( groupByName )
|
if( it == tree.end() )
|
||||||
{
|
{
|
||||||
|
it = tree.emplace( idx.data, CallstackFrameTree { idx } ).first;
|
||||||
|
}
|
||||||
|
return &it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
static tracy_force_inline CallstackFrameTree* GetFrameTreeItemGroup( flat_hash_map<uint64_t, CallstackFrameTree, nohash<uint64_t>>& tree, CallstackFrameId idx, const Worker& worker )
|
||||||
|
{
|
||||||
auto& frameData = *worker.GetCallstackFrame( idx );
|
auto& frameData = *worker.GetCallstackFrame( idx );
|
||||||
auto& frame = frameData.data[frameData.size-1];
|
auto& frame = frameData.data[frameData.size-1];
|
||||||
auto fidx = frame.name.idx;
|
auto fidx = frame.name.idx;
|
||||||
|
|
||||||
it = std::find_if( tree.begin(), tree.end(), [&worker, fidx] ( const auto& v ) {
|
auto it = tree.find( fidx );
|
||||||
auto& frameData = *worker.GetCallstackFrame( v.frame );
|
|
||||||
auto& frame = frameData.data[frameData.size-1];
|
|
||||||
return frame.name.idx == fidx;
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
it = std::find_if( tree.begin(), tree.end(), [idx] ( const auto& v ) { return v.frame.data == idx.data; } );
|
|
||||||
}
|
|
||||||
if( it == tree.end() )
|
if( it == tree.end() )
|
||||||
{
|
{
|
||||||
tree.emplace_back( CallstackFrameTree { idx } );
|
it = tree.emplace( fidx, CallstackFrameTree { idx } ).first;
|
||||||
return &tree.back();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return &*it;
|
|
||||||
}
|
}
|
||||||
|
return &it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
flat_hash_map<uint32_t, View::PathData, nohash<uint32_t>> View::GetCallstackPaths( const MemData& mem ) const
|
flat_hash_map<uint32_t, View::PathData, nohash<uint32_t>> View::GetCallstackPaths( const MemData& mem ) const
|
||||||
@ -9017,53 +9011,102 @@ flat_hash_map<uint32_t, View::PathData, nohash<uint32_t>> View::GetCallstackPath
|
|||||||
return pathSum;
|
return pathSum;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<CallstackFrameTree> View::GetCallstackFrameTreeBottomUp( const MemData& mem ) const
|
flat_hash_map<uint64_t, CallstackFrameTree, nohash<uint64_t>> View::GetCallstackFrameTreeBottomUp( const MemData& mem ) const
|
||||||
{
|
{
|
||||||
std::vector<CallstackFrameTree> root;
|
flat_hash_map<uint64_t, CallstackFrameTree, nohash<uint64_t>> root;
|
||||||
auto pathSum = GetCallstackPaths( mem );
|
auto pathSum = GetCallstackPaths( mem );
|
||||||
|
if( m_groupCallstackTreeByNameBottomUp )
|
||||||
|
{
|
||||||
for( auto& path : pathSum )
|
for( auto& path : pathSum )
|
||||||
{
|
{
|
||||||
auto& cs = m_worker.GetCallstack( path.first );
|
auto& cs = m_worker.GetCallstack( path.first );
|
||||||
|
|
||||||
auto base = cs.back();
|
auto base = cs.back();
|
||||||
auto treePtr = GetFrameTreeItem( root, base, m_worker, m_groupCallstackTreeByNameBottomUp );
|
auto treePtr = GetFrameTreeItemGroup( root, base, m_worker );
|
||||||
treePtr->count += path.second.cnt;
|
treePtr->count += path.second.cnt;
|
||||||
treePtr->alloc += path.second.mem;
|
treePtr->alloc += path.second.mem;
|
||||||
treePtr->callstacks.emplace( path.first );
|
treePtr->callstacks.emplace( path.first );
|
||||||
|
|
||||||
for( int i = int( cs.size() ) - 2; i >= 0; i-- )
|
for( int i = int( cs.size() ) - 2; i >= 0; i-- )
|
||||||
{
|
{
|
||||||
treePtr = GetFrameTreeItem( treePtr->children, cs[i], m_worker, m_groupCallstackTreeByNameBottomUp );
|
treePtr = GetFrameTreeItemGroup( treePtr->children, cs[i], m_worker );
|
||||||
treePtr->count += path.second.cnt;
|
treePtr->count += path.second.cnt;
|
||||||
treePtr->alloc += path.second.mem;
|
treePtr->alloc += path.second.mem;
|
||||||
treePtr->callstacks.emplace( path.first );
|
treePtr->callstacks.emplace( path.first );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( auto& path : pathSum )
|
||||||
|
{
|
||||||
|
auto& cs = m_worker.GetCallstack( path.first );
|
||||||
|
|
||||||
|
auto base = cs.back();
|
||||||
|
auto treePtr = GetFrameTreeItemNoGroup( root, base, m_worker );
|
||||||
|
treePtr->count += path.second.cnt;
|
||||||
|
treePtr->alloc += path.second.mem;
|
||||||
|
treePtr->callstacks.emplace( path.first );
|
||||||
|
|
||||||
|
for( int i = int( cs.size() ) - 2; i >= 0; i-- )
|
||||||
|
{
|
||||||
|
treePtr = GetFrameTreeItemNoGroup( treePtr->children, cs[i], m_worker );
|
||||||
|
treePtr->count += path.second.cnt;
|
||||||
|
treePtr->alloc += path.second.mem;
|
||||||
|
treePtr->callstacks.emplace( path.first );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<CallstackFrameTree> View::GetCallstackFrameTreeTopDown( const MemData& mem ) const
|
flat_hash_map<uint64_t, CallstackFrameTree, nohash<uint64_t>> View::GetCallstackFrameTreeTopDown( const MemData& mem ) const
|
||||||
{
|
{
|
||||||
std::vector<CallstackFrameTree> root;
|
flat_hash_map<uint64_t, CallstackFrameTree, nohash<uint64_t>> root;
|
||||||
auto pathSum = GetCallstackPaths( mem );
|
auto pathSum = GetCallstackPaths( mem );
|
||||||
|
if( m_groupCallstackTreeByNameTopDown )
|
||||||
|
{
|
||||||
for( auto& path : pathSum )
|
for( auto& path : pathSum )
|
||||||
{
|
{
|
||||||
auto& cs = m_worker.GetCallstack( path.first );
|
auto& cs = m_worker.GetCallstack( path.first );
|
||||||
|
|
||||||
auto base = cs.front();
|
auto base = cs.front();
|
||||||
auto treePtr = GetFrameTreeItem( root, base, m_worker, m_groupCallstackTreeByNameTopDown );
|
auto treePtr = GetFrameTreeItemGroup( root, base, m_worker );
|
||||||
treePtr->count += path.second.cnt;
|
treePtr->count += path.second.cnt;
|
||||||
treePtr->alloc += path.second.mem;
|
treePtr->alloc += path.second.mem;
|
||||||
treePtr->callstacks.emplace( path.first );
|
treePtr->callstacks.emplace( path.first );
|
||||||
|
|
||||||
for( int i = 1; i < cs.size(); i++ )
|
for( int i = 1; i < cs.size(); i++ )
|
||||||
{
|
{
|
||||||
treePtr = GetFrameTreeItem( treePtr->children, cs[i], m_worker, m_groupCallstackTreeByNameTopDown );
|
treePtr = GetFrameTreeItemGroup( treePtr->children, cs[i], m_worker );
|
||||||
treePtr->count += path.second.cnt;
|
treePtr->count += path.second.cnt;
|
||||||
treePtr->alloc += path.second.mem;
|
treePtr->alloc += path.second.mem;
|
||||||
treePtr->callstacks.emplace( path.first );
|
treePtr->callstacks.emplace( path.first );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( auto& path : pathSum )
|
||||||
|
{
|
||||||
|
auto& cs = m_worker.GetCallstack( path.first );
|
||||||
|
|
||||||
|
auto base = cs.front();
|
||||||
|
auto treePtr = GetFrameTreeItemNoGroup( root, base, m_worker );
|
||||||
|
treePtr->count += path.second.cnt;
|
||||||
|
treePtr->alloc += path.second.mem;
|
||||||
|
treePtr->callstacks.emplace( path.first );
|
||||||
|
|
||||||
|
for( int i = 1; i < cs.size(); i++ )
|
||||||
|
{
|
||||||
|
treePtr = GetFrameTreeItemNoGroup( treePtr->children, cs[i], m_worker );
|
||||||
|
treePtr->count += path.second.cnt;
|
||||||
|
treePtr->alloc += path.second.mem;
|
||||||
|
treePtr->callstacks.emplace( path.first );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9389,14 +9432,22 @@ void View::DrawMemory()
|
|||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
void View::DrawFrameTreeLevel( std::vector<CallstackFrameTree>& tree, int& idx )
|
void View::DrawFrameTreeLevel( const flat_hash_map<uint64_t, CallstackFrameTree, nohash<uint64_t>>& tree, int& idx )
|
||||||
{
|
{
|
||||||
auto& io = ImGui::GetIO();
|
auto& io = ImGui::GetIO();
|
||||||
|
|
||||||
int lidx = 0;
|
std::vector<flat_hash_map<uint64_t, CallstackFrameTree, nohash<uint64_t>>::const_iterator> sorted;
|
||||||
pdqsort_branchless( tree.begin(), tree.end(), [] ( const auto& lhs, const auto& rhs ) { return lhs.alloc > rhs.alloc; } );
|
sorted.reserve( tree.size() );
|
||||||
for( auto& v : tree )
|
for( auto it = tree.begin(); it != tree.end(); ++it )
|
||||||
{
|
{
|
||||||
|
sorted.emplace_back( it );
|
||||||
|
}
|
||||||
|
pdqsort_branchless( sorted.begin(), sorted.end(), [] ( const auto& lhs, const auto& rhs ) { return lhs->second.alloc > rhs->second.alloc; } );
|
||||||
|
|
||||||
|
int lidx = 0;
|
||||||
|
for( auto& _v : sorted )
|
||||||
|
{
|
||||||
|
auto& v = _v->second;
|
||||||
idx++;
|
idx++;
|
||||||
auto& frameData = *m_worker.GetCallstackFrame( v.frame );
|
auto& frameData = *m_worker.GetCallstackFrame( v.frame );
|
||||||
auto frame = frameData.data[frameData.size-1];
|
auto frame = frameData.data[frameData.size-1];
|
||||||
|
@ -134,9 +134,9 @@ private:
|
|||||||
void ListMemData( T ptr, T end, std::function<void(T&)> DrawAddress, const char* id = nullptr, int64_t startTime = -1 );
|
void ListMemData( T ptr, T end, std::function<void(T&)> DrawAddress, const char* id = nullptr, int64_t startTime = -1 );
|
||||||
|
|
||||||
flat_hash_map<uint32_t, PathData, nohash<uint32_t>> GetCallstackPaths( const MemData& mem ) const;
|
flat_hash_map<uint32_t, PathData, nohash<uint32_t>> GetCallstackPaths( const MemData& mem ) const;
|
||||||
std::vector<CallstackFrameTree> GetCallstackFrameTreeBottomUp( const MemData& mem ) const;
|
flat_hash_map<uint64_t, CallstackFrameTree, nohash<uint64_t>> GetCallstackFrameTreeBottomUp( const MemData& mem ) const;
|
||||||
std::vector<CallstackFrameTree> GetCallstackFrameTreeTopDown( const MemData& mem ) const;
|
flat_hash_map<uint64_t, CallstackFrameTree, nohash<uint64_t>> GetCallstackFrameTreeTopDown( const MemData& mem ) const;
|
||||||
void DrawFrameTreeLevel( std::vector<CallstackFrameTree>& tree, int& idx );
|
void DrawFrameTreeLevel( const flat_hash_map<uint64_t, CallstackFrameTree, nohash<uint64_t>>& tree, int& idx );
|
||||||
void DrawZoneList( const Vector<ZoneEvent*>& zones );
|
void DrawZoneList( const Vector<ZoneEvent*>& zones );
|
||||||
|
|
||||||
void DrawInfoWindow();
|
void DrawInfoWindow();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user