mirror of
https://github.com/wolfpld/tracy.git
synced 2024-11-30 01:04:36 +00:00
Store memory callstack data as 24-bit ints.
This reduces MemEvent size from 40 to 38 bytes. Memory usage reduction: chicken 2027 -> 2019 mem 6468 -> 6308 q3bsp-mt 5304 -> 5283
This commit is contained in:
parent
f0b957ec56
commit
65ea33a60f
@ -90,11 +90,6 @@ public:
|
|||||||
SetVal( val );
|
SetVal( val );
|
||||||
}
|
}
|
||||||
|
|
||||||
Int24( const Int24& ) = delete;
|
|
||||||
Int24( Int24&& ) = delete;
|
|
||||||
Int24& operator=( const Int24& ) = delete;
|
|
||||||
Int24& operator=( Int24&& ) = delete;
|
|
||||||
|
|
||||||
void SetVal( uint32_t val )
|
void SetVal( uint32_t val )
|
||||||
{
|
{
|
||||||
memcpy( m_val, &val, 3 );
|
memcpy( m_val, &val, 3 );
|
||||||
@ -220,8 +215,8 @@ struct MemEvent
|
|||||||
|
|
||||||
uint64_t ptr;
|
uint64_t ptr;
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
uint32_t csAlloc;
|
Int24 csAlloc;
|
||||||
uint32_t csFree;
|
Int24 csFree;
|
||||||
uint64_t _time_thread_alloc;
|
uint64_t _time_thread_alloc;
|
||||||
uint64_t _time_thread_free;
|
uint64_t _time_thread_free;
|
||||||
};
|
};
|
||||||
|
@ -10008,10 +10008,10 @@ void View::DrawMemoryAllocWindow()
|
|||||||
ImGui::TextDisabled( "(%s)", RealToString( tidAlloc, true ) );
|
ImGui::TextDisabled( "(%s)", RealToString( tidAlloc, true ) );
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
SmallColorBox( GetThreadColor( tidAlloc, 0 ) );
|
SmallColorBox( GetThreadColor( tidAlloc, 0 ) );
|
||||||
if( ev.csAlloc != 0 )
|
if( ev.csAlloc.Val() != 0 )
|
||||||
{
|
{
|
||||||
ImGui::SameLine(); ImGui::Spacing(); ImGui::SameLine();
|
ImGui::SameLine(); ImGui::Spacing(); ImGui::SameLine();
|
||||||
SmallCallstackButton( "Call stack", ev.csAlloc, idx );
|
SmallCallstackButton( "Call stack", ev.csAlloc.Val(), idx );
|
||||||
}
|
}
|
||||||
if( ev.TimeFree() < 0 )
|
if( ev.TimeFree() < 0 )
|
||||||
{
|
{
|
||||||
@ -10027,10 +10027,10 @@ void View::DrawMemoryAllocWindow()
|
|||||||
ImGui::TextDisabled( "(%s)", RealToString( tidFree, true ) );
|
ImGui::TextDisabled( "(%s)", RealToString( tidFree, true ) );
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
SmallColorBox( GetThreadColor( tidFree, 0 ) );
|
SmallColorBox( GetThreadColor( tidFree, 0 ) );
|
||||||
if( ev.csFree != 0 )
|
if( ev.csFree.Val() != 0 )
|
||||||
{
|
{
|
||||||
ImGui::SameLine(); ImGui::Spacing(); ImGui::SameLine();
|
ImGui::SameLine(); ImGui::Spacing(); ImGui::SameLine();
|
||||||
SmallCallstackButton( "Call stack", ev.csFree, idx );
|
SmallCallstackButton( "Call stack", ev.csFree.Val(), idx );
|
||||||
}
|
}
|
||||||
TextFocused( "Duration:", TimeToString( ev.TimeFree() - ev.TimeAlloc() ) );
|
TextFocused( "Duration:", TimeToString( ev.TimeFree() - ev.TimeAlloc() ) );
|
||||||
}
|
}
|
||||||
@ -11488,24 +11488,24 @@ void View::ListMemData( T ptr, T end, std::function<void(T&)> DrawAddress, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::NextColumn();
|
ImGui::NextColumn();
|
||||||
if( v->csAlloc == 0 )
|
if( v->csAlloc.Val() == 0 )
|
||||||
{
|
{
|
||||||
TextDisabledUnformatted( "[alloc]" );
|
TextDisabledUnformatted( "[alloc]" );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SmallCallstackButton( "alloc", v->csAlloc, idx );
|
SmallCallstackButton( "alloc", v->csAlloc.Val(), idx );
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if( v->csFree == 0 )
|
if( v->csFree.Val() == 0 )
|
||||||
{
|
{
|
||||||
TextDisabledUnformatted( "[free]" );
|
TextDisabledUnformatted( "[free]" );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SmallCallstackButton( "free", v->csFree, idx );
|
SmallCallstackButton( "free", v->csFree.Val(), idx );
|
||||||
}
|
}
|
||||||
ImGui::NextColumn();
|
ImGui::NextColumn();
|
||||||
ptr++;
|
ptr++;
|
||||||
@ -11549,14 +11549,14 @@ flat_hash_map<uint32_t, View::PathData, nohash<uint32_t>> View::GetCallstackPath
|
|||||||
{
|
{
|
||||||
for( auto& ev : mem.data )
|
for( auto& ev : mem.data )
|
||||||
{
|
{
|
||||||
if( ev.csAlloc == 0 ) continue;
|
if( ev.csAlloc.Val() == 0 ) continue;
|
||||||
if( ev.TimeAlloc() >= zvMid ) continue;
|
if( ev.TimeAlloc() >= zvMid ) continue;
|
||||||
if( onlyActive && ev.TimeFree() >= 0 && ev.TimeFree() < zvMid ) continue;
|
if( onlyActive && ev.TimeFree() >= 0 && ev.TimeFree() < zvMid ) continue;
|
||||||
|
|
||||||
auto it = pathSum.find( ev.csAlloc );
|
auto it = pathSum.find( ev.csAlloc.Val() );
|
||||||
if( it == pathSum.end() )
|
if( it == pathSum.end() )
|
||||||
{
|
{
|
||||||
pathSum.emplace( ev.csAlloc, PathData { 1, ev.size } );
|
pathSum.emplace( ev.csAlloc.Val(), PathData { 1, ev.size } );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -11569,13 +11569,13 @@ flat_hash_map<uint32_t, View::PathData, nohash<uint32_t>> View::GetCallstackPath
|
|||||||
{
|
{
|
||||||
for( auto& ev : mem.data )
|
for( auto& ev : mem.data )
|
||||||
{
|
{
|
||||||
if( ev.csAlloc == 0 ) continue;
|
if( ev.csAlloc.Val() == 0 ) continue;
|
||||||
if( onlyActive && ev.TimeFree() >= 0 ) continue;
|
if( onlyActive && ev.TimeFree() >= 0 ) continue;
|
||||||
|
|
||||||
auto it = pathSum.find( ev.csAlloc );
|
auto it = pathSum.find( ev.csAlloc.Val() );
|
||||||
if( it == pathSum.end() )
|
if( it == pathSum.end() )
|
||||||
{
|
{
|
||||||
pathSum.emplace( ev.csAlloc, PathData { 1, ev.size } );
|
pathSum.emplace( ev.csAlloc.Val(), PathData { 1, ev.size } );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -12196,7 +12196,7 @@ void View::DrawFrameTreeLevel( const flat_hash_map<uint64_t, CallstackFrameTree,
|
|||||||
m_memInfo.allocList.clear();
|
m_memInfo.allocList.clear();
|
||||||
for( size_t i=0; i<sz; i++ )
|
for( size_t i=0; i<sz; i++ )
|
||||||
{
|
{
|
||||||
if( v.callstacks.find( mem[i].csAlloc ) != v.callstacks.end() )
|
if( v.callstacks.find( mem[i].csAlloc.Val() ) != v.callstacks.end() )
|
||||||
{
|
{
|
||||||
m_memInfo.allocList.emplace_back( i );
|
m_memInfo.allocList.emplace_back( i );
|
||||||
}
|
}
|
||||||
|
@ -1110,7 +1110,7 @@ Worker::Worker( FileRead& f, EventType::Type eventMask, bool bgTasks )
|
|||||||
s_loadProgress.subTotal.store( sz, std::memory_order_relaxed );
|
s_loadProgress.subTotal.store( sz, std::memory_order_relaxed );
|
||||||
size_t fidx = 0;
|
size_t fidx = 0;
|
||||||
int64_t refTime = 0;
|
int64_t refTime = 0;
|
||||||
if( fileVer >= FileVersion( 0, 5, 2 ) )
|
if( fileVer >= FileVersion( 0, 5, 9 ) )
|
||||||
{
|
{
|
||||||
auto& frees = m_data.memory.frees;
|
auto& frees = m_data.memory.frees;
|
||||||
auto& active = m_data.memory.active;
|
auto& active = m_data.memory.active;
|
||||||
@ -1140,6 +1140,39 @@ Worker::Worker( FileRead& f, EventType::Type eventMask, bool bgTasks )
|
|||||||
mem++;
|
mem++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if( fileVer >= FileVersion( 0, 5, 2 ) )
|
||||||
|
{
|
||||||
|
auto& frees = m_data.memory.frees;
|
||||||
|
auto& active = m_data.memory.active;
|
||||||
|
|
||||||
|
for( uint64_t i=0; i<sz; i++ )
|
||||||
|
{
|
||||||
|
s_loadProgress.subProgress.store( i, std::memory_order_relaxed );
|
||||||
|
f.Read( mem, sizeof( MemEvent::ptr ) + sizeof( MemEvent::size ) + sizeof( MemEvent::csAlloc ) );
|
||||||
|
f.Skip( 1 );
|
||||||
|
f.Read( &mem->csFree, sizeof( MemEvent::csFree ) );
|
||||||
|
f.Skip( 1 );
|
||||||
|
int64_t timeAlloc, timeFree;
|
||||||
|
uint16_t threadAlloc, threadFree;
|
||||||
|
f.Read2( timeAlloc, timeFree );
|
||||||
|
f.Read2( threadAlloc, threadFree );
|
||||||
|
refTime += timeAlloc;
|
||||||
|
mem->SetTimeAlloc( refTime );
|
||||||
|
if( timeFree >= 0 )
|
||||||
|
{
|
||||||
|
mem->SetTimeFree( timeFree + refTime );
|
||||||
|
frees[fidx++] = i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mem->SetTimeFree( timeFree );
|
||||||
|
active.emplace( mem->ptr, i );
|
||||||
|
}
|
||||||
|
mem->SetThreadAlloc( threadAlloc );
|
||||||
|
mem->SetThreadFree( threadFree );
|
||||||
|
mem++;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if( fileVer >= FileVersion( 0, 4, 4 ) )
|
else if( fileVer >= FileVersion( 0, 4, 4 ) )
|
||||||
{
|
{
|
||||||
auto& frees = m_data.memory.frees;
|
auto& frees = m_data.memory.frees;
|
||||||
@ -1151,7 +1184,10 @@ Worker::Worker( FileRead& f, EventType::Type eventMask, bool bgTasks )
|
|||||||
f.Read( mem, sizeof( MemEvent::ptr ) + sizeof( MemEvent::size ) );
|
f.Read( mem, sizeof( MemEvent::ptr ) + sizeof( MemEvent::size ) );
|
||||||
int64_t timeAlloc, timeFree;
|
int64_t timeAlloc, timeFree;
|
||||||
f.Read2( timeAlloc, timeFree );
|
f.Read2( timeAlloc, timeFree );
|
||||||
f.Read( &mem->csAlloc, sizeof( MemEvent::csAlloc ) + sizeof( MemEvent::csFree ) );
|
f.Read( mem->csAlloc );
|
||||||
|
f.Skip( 1 );
|
||||||
|
f.Read( mem->csFree );
|
||||||
|
f.Skip( 1 );
|
||||||
uint16_t threadAlloc, threadFree;
|
uint16_t threadAlloc, threadFree;
|
||||||
f.Read2( threadAlloc, threadFree );
|
f.Read2( threadAlloc, threadFree );
|
||||||
refTime += timeAlloc;
|
refTime += timeAlloc;
|
||||||
@ -1181,7 +1217,10 @@ Worker::Worker( FileRead& f, EventType::Type eventMask, bool bgTasks )
|
|||||||
f.Read( mem, sizeof( MemEvent::ptr ) + sizeof( MemEvent::size ) );
|
f.Read( mem, sizeof( MemEvent::ptr ) + sizeof( MemEvent::size ) );
|
||||||
int64_t timeAlloc, timeFree;
|
int64_t timeAlloc, timeFree;
|
||||||
f.Read2( timeAlloc, timeFree );
|
f.Read2( timeAlloc, timeFree );
|
||||||
f.Read( &mem->csAlloc, sizeof( MemEvent::csAlloc ) + sizeof( MemEvent::csFree ) );
|
f.Read( mem->csAlloc );
|
||||||
|
f.Skip( 1 );
|
||||||
|
f.Read( mem->csFree );
|
||||||
|
f.Skip( 1 );
|
||||||
refTime += timeAlloc;
|
refTime += timeAlloc;
|
||||||
mem->SetTimeAlloc( refTime - m_data.baseTime );
|
mem->SetTimeAlloc( refTime - m_data.baseTime );
|
||||||
if( timeFree >= 0 )
|
if( timeFree >= 0 )
|
||||||
@ -1198,7 +1237,10 @@ Worker::Worker( FileRead& f, EventType::Type eventMask, bool bgTasks )
|
|||||||
f.Read( mem, sizeof( MemEvent::ptr ) + sizeof( MemEvent::size ) );
|
f.Read( mem, sizeof( MemEvent::ptr ) + sizeof( MemEvent::size ) );
|
||||||
int64_t timeAlloc, timeFree;
|
int64_t timeAlloc, timeFree;
|
||||||
f.Read2( timeAlloc, timeFree );
|
f.Read2( timeAlloc, timeFree );
|
||||||
f.Read( &mem->csAlloc, sizeof( MemEvent::csAlloc ) + sizeof( MemEvent::csFree ) );
|
f.Read( mem->csAlloc );
|
||||||
|
f.Skip( 1 );
|
||||||
|
f.Read( mem->csFree );
|
||||||
|
f.Skip( 1 );
|
||||||
mem->SetTimeAlloc( timeAlloc - m_data.baseTime );
|
mem->SetTimeAlloc( timeAlloc - m_data.baseTime );
|
||||||
if( timeFree >= 0 )
|
if( timeFree >= 0 )
|
||||||
{
|
{
|
||||||
@ -1248,21 +1290,21 @@ Worker::Worker( FileRead& f, EventType::Type eventMask, bool bgTasks )
|
|||||||
{
|
{
|
||||||
f.Skip( 2 * sizeof( uint64_t ) );
|
f.Skip( 2 * sizeof( uint64_t ) );
|
||||||
|
|
||||||
if( fileVer >= FileVersion( 0, 5, 2 ) )
|
if( fileVer >= FileVersion( 0, 5, 9 ) )
|
||||||
{
|
{
|
||||||
f.Skip( sz * ( sizeof( MemEvent::ptr ) + sizeof( MemEvent::size ) + sizeof( MemEvent::csAlloc ) + sizeof( MemEvent::csFree ) + sizeof( int64_t ) * 2 + sizeof( uint16_t ) * 2 ) );
|
f.Skip( sz * ( sizeof( MemEvent::ptr ) + sizeof( MemEvent::size ) + sizeof( MemEvent::csAlloc ) + sizeof( MemEvent::csFree ) + sizeof( int64_t ) * 2 + sizeof( uint16_t ) * 2 ) );
|
||||||
}
|
}
|
||||||
|
else if( fileVer >= FileVersion( 0, 5, 2 ) )
|
||||||
|
{
|
||||||
|
f.Skip( sz * ( sizeof( MemEvent::ptr ) + sizeof( MemEvent::size ) + sizeof( uint32_t ) + sizeof( uint32_t ) + sizeof( int64_t ) * 2 + sizeof( uint16_t ) * 2 ) );
|
||||||
|
}
|
||||||
else if( fileVer >= FileVersion( 0, 4, 4 ) )
|
else if( fileVer >= FileVersion( 0, 4, 4 ) )
|
||||||
{
|
{
|
||||||
f.Skip( sz * ( sizeof( MemEvent::ptr ) + sizeof( MemEvent::size ) + sizeof( int64_t ) + sizeof( int64_t ) + sizeof( MemEvent::csAlloc ) + sizeof( MemEvent::csFree ) + sizeof( uint16_t ) + sizeof( uint16_t ) ) );
|
f.Skip( sz * ( sizeof( MemEvent::ptr ) + sizeof( MemEvent::size ) + sizeof( int64_t ) + sizeof( int64_t ) + sizeof( uint32_t ) + sizeof( uint32_t ) + sizeof( uint16_t ) + sizeof( uint16_t ) ) );
|
||||||
}
|
|
||||||
else if( fileVer > FileVersion( 0, 4, 1 ) )
|
|
||||||
{
|
|
||||||
f.Skip( sz * ( sizeof( MemEvent::ptr ) + sizeof( MemEvent::size ) + sizeof( int64_t ) + sizeof( int64_t ) + sizeof( MemEvent::csAlloc ) + sizeof( MemEvent::csFree ) + 2 * sizeof( uint64_t ) ) );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
f.Skip( sz * ( sizeof( MemEvent::ptr ) + sizeof( MemEvent::size ) + sizeof( int64_t ) + sizeof( int64_t ) + sizeof( MemEvent::csAlloc ) + sizeof( MemEvent::csFree ) + 2 * sizeof( uint64_t ) ) );
|
f.Skip( sz * ( sizeof( MemEvent::ptr ) + sizeof( MemEvent::size ) + sizeof( int64_t ) + sizeof( int64_t ) + sizeof( uint32_t ) + sizeof( uint32_t ) + 2 * sizeof( uint64_t ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
f.Skip( sizeof( MemData::high ) + sizeof( MemData::low ) + sizeof( MemData::usage ) );
|
f.Skip( sizeof( MemData::high ) + sizeof( MemData::low ) + sizeof( MemData::usage ) );
|
||||||
@ -4087,8 +4129,8 @@ void Worker::ProcessMemAlloc( const QueueMemAlloc& ev )
|
|||||||
mem.SetThreadAlloc( CompressThread( ev.thread ) );
|
mem.SetThreadAlloc( CompressThread( ev.thread ) );
|
||||||
mem.SetTimeFree( -1 );
|
mem.SetTimeFree( -1 );
|
||||||
mem.SetThreadFree( 0 );
|
mem.SetThreadFree( 0 );
|
||||||
mem.csAlloc = 0;
|
mem.csAlloc.SetVal( 0 );
|
||||||
mem.csFree = 0;
|
mem.csFree.SetVal( 0 );
|
||||||
|
|
||||||
const auto low = m_data.memory.low;
|
const auto low = m_data.memory.low;
|
||||||
const auto high = m_data.memory.high;
|
const auto high = m_data.memory.high;
|
||||||
@ -4160,11 +4202,11 @@ void Worker::ProcessCallstackMemory( const QueueCallstackMemory& ev )
|
|||||||
auto& mem = m_data.memory.data[m_lastMemActionCallstack];
|
auto& mem = m_data.memory.data[m_lastMemActionCallstack];
|
||||||
if( m_lastMemActionWasAlloc )
|
if( m_lastMemActionWasAlloc )
|
||||||
{
|
{
|
||||||
mem.csAlloc = m_pendingCallstackId;
|
mem.csAlloc.SetVal( m_pendingCallstackId );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mem.csFree = m_pendingCallstackId;
|
mem.csFree.SetVal( m_pendingCallstackId );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user