Store MemEvents directly in the vector.

This commit is contained in:
Bartosz Taudul 2018-04-03 14:17:51 +02:00
parent bc27c99a1e
commit bf99bff87d
5 changed files with 55 additions and 48 deletions

View File

@ -224,8 +224,8 @@ struct PlotData
struct MemData struct MemData
{ {
Vector<MemEvent*> data; Vector<MemEvent> data;
flat_hash_map<uint64_t, MemEvent*, nohash<uint64_t>> active; flat_hash_map<uint64_t, size_t, nohash<uint64_t>> active;
uint64_t high = std::numeric_limits<uint64_t>::min(); uint64_t high = std::numeric_limits<uint64_t>::min();
uint64_t low = std::numeric_limits<uint64_t>::max(); uint64_t low = std::numeric_limits<uint64_t>::max();
uint64_t usage = 0; uint64_t usage = 0;

View File

@ -94,6 +94,12 @@ public:
m_ptr[m_size++] = std::move( v ); m_ptr[m_size++] = std::move( v );
} }
T& push_next()
{
if( m_size == Capacity() ) AllocMore();
return m_ptr[m_size++];
}
T* insert( T* it, const T& v ) T* insert( T* it, const T& v )
{ {
assert( it >= m_ptr && it <= m_ptr + m_size ); assert( it >= m_ptr && it <= m_ptr + m_size );

View File

@ -3658,7 +3658,7 @@ void View::DrawStatistics()
} }
template<class T> template<class T>
void View::ListMemData( T ptr, T end, std::function<MemEvent*(T&)> DrawAddress ) void View::ListMemData( T ptr, T end, std::function<const MemEvent*(T&)> DrawAddress )
{ {
ImGui::BeginChild( "##memScroll", ImVec2( 0, std::max( 200.f, ImGui::GetContentRegionAvail().y ) ) ); ImGui::BeginChild( "##memScroll", ImVec2( 0, std::max( 200.f, ImGui::GetContentRegionAvail().y ) ) );
ImGui::Columns( 7 ); ImGui::Columns( 7 );
@ -3858,15 +3858,15 @@ void View::DrawMemory()
{ {
if( m_memInfo.ptrFind != 0 ) if( m_memInfo.ptrFind != 0 )
{ {
std::vector<MemEvent*> match; std::vector<const MemEvent*> match;
match.reserve( mem.active.size() ); // heuristic match.reserve( mem.active.size() ); // heuristic
if( m_memInfo.restrictTime ) if( m_memInfo.restrictTime )
{ {
for( auto& v : mem.data ) for( auto& v : mem.data )
{ {
if( v->ptr <= m_memInfo.ptrFind && v->ptr + v->size > m_memInfo.ptrFind && v->timeAlloc < zvMid ) if( v.ptr <= m_memInfo.ptrFind && v.ptr + v.size > m_memInfo.ptrFind && v.timeAlloc < zvMid )
{ {
match.emplace_back( v ); match.emplace_back( &v );
} }
} }
} }
@ -3874,9 +3874,9 @@ void View::DrawMemory()
{ {
for( auto& v : mem.data ) for( auto& v : mem.data )
{ {
if( v->ptr <= m_memInfo.ptrFind && v->ptr + v->size > m_memInfo.ptrFind ) if( v.ptr <= m_memInfo.ptrFind && v.ptr + v.size > m_memInfo.ptrFind )
{ {
match.emplace_back( v ); match.emplace_back( &v );
} }
} }
} }
@ -3910,24 +3910,25 @@ void View::DrawMemory()
if( ImGui::TreeNode( "Active allocations" ) ) if( ImGui::TreeNode( "Active allocations" ) )
{ {
uint64_t total = 0; uint64_t total = 0;
std::vector<MemEvent*> items; std::vector<const MemEvent*> items;
items.reserve( mem.active.size() ); items.reserve( mem.active.size() );
if( m_memInfo.restrictTime ) if( m_memInfo.restrictTime )
{ {
for( auto& v : mem.data ) for( auto& v : mem.data )
{ {
if( v->timeAlloc < zvMid && ( v->timeFree > zvMid || v->timeFree < 0 ) ) if( v.timeAlloc < zvMid && ( v.timeFree > zvMid || v.timeFree < 0 ) )
{ {
items.emplace_back( v ); items.emplace_back( &v );
total += v->size; total += v.size;
} }
} }
} }
else else
{ {
auto ptr = mem.data.data();
for( auto& v : mem.active ) for( auto& v : mem.active )
{ {
items.emplace_back( v.second ); items.emplace_back( ptr + v.second );
} }
pdqsort_branchless( items.begin(), items.end(), []( const auto& lhs, const auto& rhs ) { return lhs->timeAlloc < rhs->timeAlloc; } ); pdqsort_branchless( items.begin(), items.end(), []( const auto& lhs, const auto& rhs ) { return lhs->timeAlloc < rhs->timeAlloc; } );
total = mem.usage; total = mem.usage;
@ -4051,14 +4052,14 @@ Vector<Vector<int8_t>> View::GetMemoryPages() const
for( auto& alloc : mem.data ) for( auto& alloc : mem.data )
{ {
if( m_memInfo.restrictTime && alloc->timeAlloc > zvMid ) continue; if( m_memInfo.restrictTime && alloc.timeAlloc > zvMid ) continue;
const auto a0 = alloc->ptr - mem.low; const auto a0 = alloc.ptr - mem.low;
const auto a1 = a0 + alloc->size; const auto a1 = a0 + alloc.size;
const auto p0 = a0 >> PageChunkBits; const auto p0 = a0 >> PageChunkBits;
const auto p1 = a1 >> PageChunkBits; const auto p1 = a1 >> PageChunkBits;
int8_t val = alloc->timeFree < 0 ? 1 : ( m_memInfo.restrictTime ? ( alloc->timeFree > zvMid ? 1 : -1 ) : -1 ); int8_t val = alloc.timeFree < 0 ? 1 : ( m_memInfo.restrictTime ? ( alloc.timeFree > zvMid ? 1 : -1 ) : -1 );
if( p0 == p1 ) if( p0 == p1 )
{ {

View File

@ -78,7 +78,7 @@ private:
void DrawMemory(); void DrawMemory();
template<class T> template<class T>
void ListMemData( T ptr, T end, std::function<MemEvent*(T&)> DrawAddress ); void ListMemData( T ptr, T end, std::function<const MemEvent*(T&)> DrawAddress );
void DrawInfoWindow(); void DrawInfoWindow();
void DrawZoneInfoWindow(); void DrawZoneInfoWindow();

View File

@ -248,10 +248,10 @@ Worker::Worker( FileRead& f )
if( f.IsEOF() ) return; if( f.IsEOF() ) return;
f.Read( &sz, sizeof( sz ) ); f.Read( &sz, sizeof( sz ) );
m_data.memory.data.reserve( sz ); m_data.memory.data.reserve_and_use( sz );
auto mem = m_data.memory.data.data();
for( uint64_t i=0; i<sz; i++ ) for( uint64_t i=0; i<sz; i++ )
{ {
auto mem = m_slab.Alloc<MemEvent>();
f.Read( &mem->ptr, sizeof( mem->ptr ) ); f.Read( &mem->ptr, sizeof( mem->ptr ) );
f.Read( &mem->size, sizeof( mem->size ) ); f.Read( &mem->size, sizeof( mem->size ) );
f.Read( &mem->timeAlloc, sizeof( mem->timeAlloc ) ); f.Read( &mem->timeAlloc, sizeof( mem->timeAlloc ) );
@ -261,12 +261,13 @@ Worker::Worker( FileRead& f )
mem->threadAlloc = CompressThread( t ); mem->threadAlloc = CompressThread( t );
f.Read( &t, sizeof( t ) ); f.Read( &t, sizeof( t ) );
mem->threadFree = CompressThread( t ); mem->threadFree = CompressThread( t );
m_data.memory.data.push_back_no_space_check( mem );
if( mem->timeFree < 0 ) if( mem->timeFree < 0 )
{ {
m_data.memory.active.emplace( mem->ptr, mem ); m_data.memory.active.emplace( mem->ptr, i );
} }
mem++;
} }
f.Read( &m_data.memory.high, sizeof( m_data.memory.high ) ); f.Read( &m_data.memory.high, sizeof( m_data.memory.high ) );
f.Read( &m_data.memory.low, sizeof( m_data.memory.low ) ); f.Read( &m_data.memory.low, sizeof( m_data.memory.low ) );
@ -1663,34 +1664,33 @@ void Worker::ProcessMemAlloc( const QueueMemAlloc& ev )
{ {
const auto time = TscTime( ev.time ); const auto time = TscTime( ev.time );
auto mem = m_slab.Alloc<MemEvent>();
mem->ptr = ev.ptr;
mem->size = 0;
memcpy( &mem->size, ev.size, 6 );
mem->timeAlloc = time;
mem->threadAlloc = CompressThread( ev.thread );
mem->timeFree = -1;
mem->threadFree = 0;
m_data.memory.low = std::min( m_data.memory.low, mem->ptr );
m_data.memory.high = std::max( m_data.memory.high, mem->ptr + mem->size );
m_data.memory.usage += mem->size;
assert( m_data.memory.active.find( ev.ptr ) == m_data.memory.active.end() ); assert( m_data.memory.active.find( ev.ptr ) == m_data.memory.active.end() );
m_data.memory.active.emplace( ev.ptr, mem ); assert( m_data.memory.data.empty() || m_data.memory.data.back().timeAlloc <= time );
assert( m_data.memory.data.empty() || m_data.memory.data.back()->timeAlloc <= time ); m_data.memory.active.emplace( ev.ptr, m_data.memory.data.size() );
m_data.memory.data.push_back( mem );
auto& mem = m_data.memory.data.push_next();
mem.ptr = ev.ptr;
mem.size = 0;
memcpy( &mem.size, ev.size, 6 );
mem.timeAlloc = time;
mem.threadAlloc = CompressThread( ev.thread );
mem.timeFree = -1;
mem.threadFree = 0;
m_data.memory.low = std::min( m_data.memory.low, mem.ptr );
m_data.memory.high = std::max( m_data.memory.high, mem.ptr + mem.size );
m_data.memory.usage += mem.size;
} }
void Worker::ProcessMemFree( const QueueMemFree& ev ) void Worker::ProcessMemFree( const QueueMemFree& ev )
{ {
auto it = m_data.memory.active.find( ev.ptr ); auto it = m_data.memory.active.find( ev.ptr );
assert( it != m_data.memory.active.end() ); assert( it != m_data.memory.active.end() );
auto mem = it->second; auto& mem = m_data.memory.data[it->second];
mem->timeFree = TscTime( ev.time ); mem.timeFree = TscTime( ev.time );
mem->threadFree = CompressThread( ev.thread ); mem.threadFree = CompressThread( ev.thread );
m_data.memory.usage -= mem->size; m_data.memory.usage -= mem.size;
m_data.memory.active.erase( it ); m_data.memory.active.erase( it );
} }
@ -1912,13 +1912,13 @@ void Worker::Write( FileWrite& f )
f.Write( &sz, sizeof( sz ) ); f.Write( &sz, sizeof( sz ) );
for( auto& mem : m_data.memory.data ) for( auto& mem : m_data.memory.data )
{ {
f.Write( &mem->ptr, sizeof( mem->ptr ) ); f.Write( &mem.ptr, sizeof( mem.ptr ) );
f.Write( &mem->size, sizeof( mem->size ) ); f.Write( &mem.size, sizeof( mem.size ) );
f.Write( &mem->timeAlloc, sizeof( mem->timeAlloc ) ); f.Write( &mem.timeAlloc, sizeof( mem.timeAlloc ) );
f.Write( &mem->timeFree, sizeof( mem->timeFree ) ); f.Write( &mem.timeFree, sizeof( mem.timeFree ) );
uint64_t t = DecompressThread( mem->threadAlloc ); uint64_t t = DecompressThread( mem.threadAlloc );
f.Write( &t, sizeof( t ) ); f.Write( &t, sizeof( t ) );
t = DecompressThread( mem->threadFree ); t = DecompressThread( mem.threadFree );
f.Write( &t, sizeof( t ) ); f.Write( &t, sizeof( t ) );
} }
f.Write( &m_data.memory.high, sizeof( m_data.memory.high ) ); f.Write( &m_data.memory.high, sizeof( m_data.memory.high ) );