From 3eb73b8d43f51d479665bc296a750dfb8c8196fc Mon Sep 17 00:00:00 2001 From: Bartosz Taudul Date: Sun, 29 Apr 2018 13:40:04 +0200 Subject: [PATCH] Move memory plot reconstruction to a background thread. --- server/TracyWorker.cpp | 178 +++++++++++++++++++++++------------------ server/TracyWorker.hpp | 3 +- 2 files changed, 100 insertions(+), 81 deletions(-) diff --git a/server/TracyWorker.cpp b/server/TracyWorker.cpp index 47bbdc33..e4a1b723 100644 --- a/server/TracyWorker.cpp +++ b/server/TracyWorker.cpp @@ -504,9 +504,6 @@ Worker::Worker( FileRead& f, EventType::Type eventMask ) f.Read( &sz, sizeof( sz ) ); if( eventMask & EventType::Memory ) { - Vector> frees; - frees.reserve( sz ); - m_data.memory.data.reserve_and_use( sz ); auto mem = m_data.memory.data.data(); for( uint64_t i=0; iptr, i ); } - else - { - frees.push_back_no_space_check( std::make_pair( mem->timeFree, double( mem->size ) ) ); - } mem++; } @@ -539,75 +532,7 @@ Worker::Worker( FileRead& f, EventType::Type eventMask ) f.Read( &m_data.memory.low, sizeof( m_data.memory.low ) ); f.Read( &m_data.memory.usage, sizeof( m_data.memory.usage ) ); - pdqsort_branchless( frees.begin(), frees.end(), [] ( const auto& lhs, const auto& rhs ) { return lhs.first < rhs.first; } ); - - const auto psz = m_data.memory.data.size() + frees.size() + 1; - PlotData* plot = m_slab.AllocInit(); - plot->name = 0; - plot->type = PlotType::Memory; - plot->data.reserve_and_use( psz ); - m_data.plots.insert( m_data.plots.begin(), plot ); - - auto aptr = m_data.memory.data.begin(); - auto aend = m_data.memory.data.end(); - auto fptr = frees.begin(); - auto fend = frees.end(); - - double max = 0; - double usage = 0; - - auto ptr = plot->data.data(); - ptr->time = GetFrameBegin( 0 ); - ptr->val = 0; - ptr++; - - while( aptr != aend && fptr != fend ) - { - int64_t time; - if( aptr->timeAlloc < fptr->first ) - { - time = aptr->timeAlloc; - usage += int64_t( aptr->size ); - aptr++; - } - else - { - time = fptr->first; - usage -= fptr->second; - fptr++; - } - assert( usage >= 0 ); - if( max < usage ) max = usage; - ptr->time = time; - ptr->val = usage; - ptr++; - } - while( aptr != aend ) - { - assert( aptr->timeFree < 0 ); - int64_t time = aptr->timeAlloc; - usage += int64_t( aptr->size ); - assert( usage >= 0 ); - if( max < usage ) max = usage; - ptr->time = time; - ptr->val = usage; - ptr++; - aptr++; - } - while( fptr != fend ) - { - int64_t time = fptr->first; - usage -= fptr->second; - assert( usage >= 0 ); - assert( max >= usage ); - ptr->time = time; - ptr->val = usage; - ptr++; - fptr++; - } - - plot->min = 0; - plot->max = max; + m_loadThread = std::thread( [this] { ReconstructMemAllocPlot(); } ); } else { @@ -635,10 +560,10 @@ static inline void ZoneCleanup( Vector& vec ) Worker::~Worker() { Shutdown(); - if( m_thread.joinable() ) - { - m_thread.join(); - } + + if( m_thread.joinable() ) m_thread.join(); + if( m_loadThread.joinable() ) m_loadThread.join(); + delete[] m_buffer; LZ4_freeStreamDecode( m_stream ); @@ -1973,6 +1898,99 @@ void Worker::CreateMemAllocPlot() m_data.plots.push_back( m_data.memory.plot ); } +void Worker::ReconstructMemAllocPlot() +{ + Vector> frees; + frees.reserve( m_data.memory.data.size() ); + for( auto& v : m_data.memory.data ) + { + if( v.timeFree >= 0 ) + { + auto& f = frees.push_next_no_space_check(); + f.first = v.timeFree; + f.second = double( v.size ); + } + } + + pdqsort_branchless( frees.begin(), frees.end(), [] ( const auto& lhs, const auto& rhs ) { return lhs.first < rhs.first; } ); + + const auto psz = m_data.memory.data.size() + frees.size() + 1; + + PlotData* plot; + { + std::lock_guard lock( m_data.lock ); + plot = m_slab.AllocInit(); + } + + plot->name = 0; + plot->type = PlotType::Memory; + plot->data.reserve_and_use( psz ); + + auto aptr = m_data.memory.data.begin(); + auto aend = m_data.memory.data.end(); + auto fptr = frees.begin(); + auto fend = frees.end(); + + double max = 0; + double usage = 0; + + auto ptr = plot->data.data(); + ptr->time = GetFrameBegin( 0 ); + ptr->val = 0; + ptr++; + + while( aptr != aend && fptr != fend ) + { + int64_t time; + if( aptr->timeAlloc < fptr->first ) + { + time = aptr->timeAlloc; + usage += int64_t( aptr->size ); + aptr++; + } + else + { + time = fptr->first; + usage -= fptr->second; + fptr++; + } + assert( usage >= 0 ); + if( max < usage ) max = usage; + ptr->time = time; + ptr->val = usage; + ptr++; + } + while( aptr != aend ) + { + assert( aptr->timeFree < 0 ); + int64_t time = aptr->timeAlloc; + usage += int64_t( aptr->size ); + assert( usage >= 0 ); + if( max < usage ) max = usage; + ptr->time = time; + ptr->val = usage; + ptr++; + aptr++; + } + while( fptr != fend ) + { + int64_t time = fptr->first; + usage -= fptr->second; + assert( usage >= 0 ); + assert( max >= usage ); + ptr->time = time; + ptr->val = usage; + ptr++; + fptr++; + } + + plot->min = 0; + plot->max = max; + + std::lock_guard lock( m_data.lock ); + m_data.plots.insert( m_data.plots.begin(), plot ); +} + void Worker::ReadTimeline( FileRead& f, Vector& vec, uint16_t thread ) { uint64_t sz; diff --git a/server/TracyWorker.hpp b/server/TracyWorker.hpp index bfbfe42e..6e4b932d 100644 --- a/server/TracyWorker.hpp +++ b/server/TracyWorker.hpp @@ -210,6 +210,7 @@ private: tracy_force_inline void MemAllocChanged( int64_t time ); void CreateMemAllocPlot(); + void ReconstructMemAllocPlot(); void InsertMessageData( MessageData* msg, uint64_t thread ); @@ -253,7 +254,7 @@ private: Socket m_sock; std::string m_addr; - std::thread m_thread; + std::thread m_thread, m_loadThread; std::atomic m_connected; std::atomic m_hasData; std::atomic m_shutdown;