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
{
Vector<MemEvent*> data;
flat_hash_map<uint64_t, MemEvent*, nohash<uint64_t>> active;
Vector<MemEvent> data;
flat_hash_map<uint64_t, size_t, nohash<uint64_t>> active;
uint64_t high = std::numeric_limits<uint64_t>::min();
uint64_t low = std::numeric_limits<uint64_t>::max();
uint64_t usage = 0;

View File

@ -94,6 +94,12 @@ public:
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 )
{
assert( it >= m_ptr && it <= m_ptr + m_size );

View File

@ -3658,7 +3658,7 @@ void View::DrawStatistics()
}
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::Columns( 7 );
@ -3858,15 +3858,15 @@ void View::DrawMemory()
{
if( m_memInfo.ptrFind != 0 )
{
std::vector<MemEvent*> match;
std::vector<const MemEvent*> match;
match.reserve( mem.active.size() ); // heuristic
if( m_memInfo.restrictTime )
{
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 )
{
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" ) )
{
uint64_t total = 0;
std::vector<MemEvent*> items;
std::vector<const MemEvent*> items;
items.reserve( mem.active.size() );
if( m_memInfo.restrictTime )
{
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 );
total += v->size;
items.emplace_back( &v );
total += v.size;
}
}
}
else
{
auto ptr = mem.data.data();
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; } );
total = mem.usage;
@ -4051,14 +4052,14 @@ Vector<Vector<int8_t>> View::GetMemoryPages() const
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 a1 = a0 + alloc->size;
const auto a0 = alloc.ptr - mem.low;
const auto a1 = a0 + alloc.size;
const auto p0 = a0 >> 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 )
{

View File

@ -78,7 +78,7 @@ private:
void DrawMemory();
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 DrawZoneInfoWindow();

View File

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