From d9c323846267298babd3ab50ec0830fdd00fd18b Mon Sep 17 00:00:00 2001 From: Bartosz Taudul Date: Sun, 3 Nov 2019 14:50:11 +0100 Subject: [PATCH] Save 2 bytes per PlotItem. Memory savings: android 2614 MB -> 2487 MB (95%) chicken 1932 MB -> 1852 MB (95%) mem 6067 MB -> 5747 MB (94%) q3bsp-mt 5059 MB -> 5017 MB (99%) q3bsp-st 1211 MB -> 1171 MB (96%) --- server/TracyEvent.hpp | 15 ++++++----- server/TracyView.cpp | 59 ++++++++++-------------------------------- server/TracyWorker.cpp | 41 +++++++++++++++-------------- 3 files changed, 45 insertions(+), 70 deletions(-) diff --git a/server/TracyEvent.hpp b/server/TracyEvent.hpp index 56cb12f9..cecbf837 100644 --- a/server/TracyEvent.hpp +++ b/server/TracyEvent.hpp @@ -386,6 +386,15 @@ struct MessageData enum { MessageDataSize = sizeof( MessageData ) }; + +struct PlotItem +{ + Int48 time; + double val; +}; + +enum { PlotItemSize = sizeof( PlotItem ) }; + #pragma pack() @@ -452,12 +461,6 @@ struct LockHighlight bool blocked; }; -struct PlotItem -{ - int64_t time; - double val; -}; - enum class PlotType : uint8_t { User, diff --git a/server/TracyView.cpp b/server/TracyView.cpp index efb8d3a2..ad0208fb 100644 --- a/server/TracyView.cpp +++ b/server/TracyView.cpp @@ -4812,8 +4812,8 @@ int View::DrawPlots( int offset, double pxns, const ImVec2& wpos, bool hover, fl ImGui::Text( "Plot \"%s\"", txt ); ImGui::Separator(); - const auto first = v->data.front().time; - const auto last = v->data.back().time; + const auto first = v->data.front().time.Val(); + const auto last = v->data.back().time.Val(); const auto activity = last - first; const auto traceLen = m_worker.GetLastTime(); @@ -4829,8 +4829,8 @@ int View::DrawPlots( int offset, double pxns, const ImVec2& wpos, bool hover, fl TextFocused( "Max value:", FormatPlotValue( v->max, v->type ) ); TextFocused( "Data/second:", RealToString( double( v->data.size() ) / activity * 1000000000ll, true ) ); - const auto it = std::lower_bound( v->data.begin(), v->data.end(), last - 1000000000ll * 10, [] ( const auto& l, const auto& r ) { return l.time < r; } ); - const auto tr10 = last - it->time; + const auto it = std::lower_bound( v->data.begin(), v->data.end(), last - 1000000000ll * 10, [] ( const auto& l, const auto& r ) { return l.time.Val() < r; } ); + const auto tr10 = last - it->time.Val(); if( tr10 != 0 ) { TextFocused( "D/s (10s):", RealToString( double( std::distance( it, v->data.end() ) ) / tr10 * 1000000000ll, true ) ); @@ -4896,8 +4896,8 @@ int View::DrawPlots( int offset, double pxns, const ImVec2& wpos, bool hover, fl } } - auto it = std::lower_bound( vec.begin(), vec.end(), m_vd.zvStart - m_worker.GetDelay(), [] ( const auto& l, const auto& r ) { return l.time < r; } ); - auto end = std::lower_bound( it, vec.end(), m_vd.zvEnd + m_worker.GetResolution(), [] ( const auto& l, const auto& r ) { return l.time < r; } ); + auto it = std::lower_bound( vec.begin(), vec.end(), m_vd.zvStart - m_worker.GetDelay(), [] ( const auto& l, const auto& r ) { return l.time.Val() < r; } ); + auto end = std::lower_bound( it, vec.end(), m_vd.zvEnd + m_worker.GetResolution(), [] ( const auto& l, const auto& r ) { return l.time.Val() < r; } ); if( end != vec.end() ) end++; if( it != vec.begin() ) it--; @@ -4915,42 +4915,11 @@ int View::DrawPlots( int offset, double pxns, const ImVec2& wpos, bool hover, fl auto tmp = it; ++tmp; const auto sz = end - tmp; -#ifdef __AVX2__ - __m256d vmin = _mm256_set1_pd( min ); - __m256d vmax = vmin; - const auto ssz = sz / 4; - for( ptrdiff_t i=0; i max ? tmp[i].val : max; - } -#else for( ptrdiff_t i=0; i max ? tmp[i].val : max; } -#endif } if( min == max ) { @@ -4987,7 +4956,7 @@ int View::DrawPlots( int offset, double pxns, const ImVec2& wpos, bool hover, fl if( it == vec.begin() ) { - const auto x = ( it->time - m_vd.zvStart ) * pxns; + const auto x = ( it->time.Val() - m_vd.zvStart ) * pxns; const auto y = PlotHeight - ( it->val - min ) * revrange * PlotHeight; DrawPlotPoint( wpos, x, y, offset, 0xFF44DDDD, hover, false, it, 0, false, v->type, PlotHeight ); } @@ -4998,8 +4967,8 @@ int View::DrawPlots( int offset, double pxns, const ImVec2& wpos, bool hover, fl ptrdiff_t skip = 0; while( it < end ) { - const auto x0 = ( prevx->time - m_vd.zvStart ) * pxns; - const auto x1 = ( it->time - m_vd.zvStart ) * pxns; + const auto x0 = ( prevx->time.Val() - m_vd.zvStart ) * pxns; + const auto x1 = ( it->time.Val() - m_vd.zvStart ) * pxns; const auto y0 = PlotHeight - ( prevy->val - min ) * revrange * PlotHeight; const auto y1 = PlotHeight - ( it->val - min ) * revrange * PlotHeight; @@ -5007,7 +4976,7 @@ int View::DrawPlots( int offset, double pxns, const ImVec2& wpos, bool hover, fl const auto rx = skip == 0 ? 2.0 : ( skip == 1 ? 2.5 : 4.0 ); - auto range = std::upper_bound( it, end, int64_t( it->time + nspx * rx ), [] ( const auto& l, const auto& r ) { return l < r.time; } ); + auto range = std::upper_bound( it, end, int64_t( it->time.Val() + nspx * rx ), [] ( const auto& l, const auto& r ) { return l < r.time.Val(); } ); assert( range > it ); const auto rsz = std::distance( it, range ); if( rsz == 1 ) @@ -5174,8 +5143,8 @@ void View::DrawPlotPoint( const ImVec2& wpos, float x, float y, int offset, uint const MemEvent* ev = nullptr; if( change > 0 ) { - auto it = std::lower_bound( mem.data.begin(), mem.data.end(), item->time, [] ( const auto& lhs, const auto& rhs ) { return lhs.TimeAlloc() < rhs; } ); - if( it != mem.data.end() && it->TimeAlloc() == item->time ) + auto it = std::lower_bound( mem.data.begin(), mem.data.end(), item->time.Val(), [] ( const auto& lhs, const auto& rhs ) { return lhs.TimeAlloc() < rhs; } ); + if( it != mem.data.end() && it->TimeAlloc() == item->time.Val() ) { ev = it; } @@ -5183,8 +5152,8 @@ void View::DrawPlotPoint( const ImVec2& wpos, float x, float y, int offset, uint else { const auto& data = mem.data; - auto it = std::lower_bound( mem.frees.begin(), mem.frees.end(), item->time, [&data] ( const auto& lhs, const auto& rhs ) { return data[lhs].TimeFree() < rhs; } ); - if( it != mem.frees.end() && data[*it].TimeFree() == item->time ) + auto it = std::lower_bound( mem.frees.begin(), mem.frees.end(), item->time.Val(), [&data] ( const auto& lhs, const auto& rhs ) { return data[lhs].TimeFree() < rhs; } ); + if( it != mem.frees.end() && data[*it].TimeFree() == item->time.Val() ) { ev = &data[*it]; } diff --git a/server/TracyWorker.cpp b/server/TracyWorker.cpp index 905a2fac..2291cf40 100644 --- a/server/TracyWorker.cpp +++ b/server/TracyWorker.cpp @@ -1062,7 +1062,7 @@ Worker::Worker( FileRead& f, EventType::Type eventMask, bool bgTasks ) int64_t refTime = 0; for( uint64_t j=0; jdata[j].time = ReadTimeOffset( f, refTime ); + pd->data[j].time.SetVal( ReadTimeOffset( f, refTime ) ); f.Read( pd->data[j].val ); } } @@ -1071,16 +1071,19 @@ Worker::Worker( FileRead& f, EventType::Type eventMask, bool bgTasks ) int64_t refTime = -m_data.baseTime; for( uint64_t j=0; jdata[j].time = ReadTimeOffset( f, refTime ); + pd->data[j].time.SetVal( ReadTimeOffset( f, refTime ) ); f.Read( pd->data[j].val ); } } else { - f.Read( pd->data.data(), psz * sizeof( PlotItem ) ); for( uint64_t j=0; jdata[j].time -= m_data.baseTime; + uint64_t t; + f.Read( t ); + t -= m_data.baseTime; + pd->data[j].time.SetVal( t ); + f.Read( pd->data[j].val ); } } m_data.plots.Data().push_back_no_space_check( pd ); @@ -1100,7 +1103,7 @@ Worker::Worker( FileRead& f, EventType::Type eventMask, bool bgTasks ) } uint64_t psz; f.Read( psz ); - f.Skip( psz * sizeof( PlotItem ) ); + f.Skip( psz * ( sizeof( uint64_t ) + sizeof( double ) ) ); } } @@ -3223,13 +3226,13 @@ void Worker::InsertPlot( PlotData* plot, int64_t time, double val ) { plot->min = val; plot->max = val; - plot->data.push_back( { time, val } ); + plot->data.push_back( { Int48( time ), val } ); } - else if( plot->data.back().time < time ) + else if( plot->data.back().time.Val() < time ) { if( plot->min > val ) plot->min = val; else if( plot->max < val ) plot->max = val; - plot->data.push_back_non_empty( { time, val } ); + plot->data.push_back_non_empty( { Int48( time ), val } ); } else { @@ -3238,11 +3241,11 @@ void Worker::InsertPlot( PlotData* plot, int64_t time, double val ) if( plot->postpone.empty() ) { plot->postponeTime = std::chrono::duration_cast( std::chrono::high_resolution_clock::now().time_since_epoch() ).count(); - plot->postpone.push_back( { time, val } ); + plot->postpone.push_back( { Int48( time ), val } ); } else { - plot->postpone.push_back_non_empty( { time, val } ); + plot->postpone.push_back_non_empty( { Int48( time ), val } ); } } } @@ -3253,7 +3256,7 @@ void Worker::HandlePlotName( uint64_t name, char* str, size_t sz ) m_data.plots.StringDiscovered( name, sl, m_data.strings, [this] ( PlotData* dst, PlotData* src ) { for( auto& v : src->data ) { - InsertPlot( dst, v.time, v.val ); + InsertPlot( dst, v.time.Val(), v.val ); } } ); } @@ -3277,16 +3280,16 @@ void Worker::HandlePostponedPlots() if( std::chrono::duration_cast( std::chrono::high_resolution_clock::now().time_since_epoch() ).count() - plot->postponeTime < 100 ) continue; auto& dst = plot->data; #ifdef MY_LIBCPP_SUCKS - pdqsort_branchless( src.begin(), src.end(), [] ( const auto& l, const auto& r ) { return l.time < r.time; } ); + pdqsort_branchless( src.begin(), src.end(), [] ( const auto& l, const auto& r ) { return l.time.Val() < r.time.Val(); } ); #else - std::sort( std::execution::par_unseq, src.begin(), src.end(), [] ( const auto& l, const auto& r ) { return l.time < r.time; } ); + std::sort( std::execution::par_unseq, src.begin(), src.end(), [] ( const auto& l, const auto& r ) { return l.time.Val() < r.time.Val(); } ); #endif - const auto ds = std::lower_bound( dst.begin(), dst.end(), src.front().time, [] ( const auto& l, const auto& r ) { return l.time < r; } ); + const auto ds = std::lower_bound( dst.begin(), dst.end(), src.front().time.Val(), [] ( const auto& l, const auto& r ) { return l.time.Val() < r; } ); const auto dsd = std::distance( dst.begin(), ds ) ; - const auto de = std::lower_bound( ds, dst.end(), src.back().time, [] ( const auto& l, const auto& r ) { return l.time < r; } ); + const auto de = std::lower_bound( ds, dst.end(), src.back().time.Val(), [] ( const auto& l, const auto& r ) { return l.time.Val() < r; } ); const auto ded = std::distance( dst.begin(), de ); dst.insert( de, src.begin(), src.end() ); - std::inplace_merge( dst.begin() + dsd, dst.begin() + ded, dst.begin() + ded + src.size(), [] ( const auto& l, const auto& r ) { return l.time < r.time; } ); + std::inplace_merge( dst.begin() + dsd, dst.begin() + ded, dst.begin() + ded + src.size(), [] ( const auto& l, const auto& r ) { return l.time.Val() < r.time.Val(); } ); src.clear(); } } @@ -4596,7 +4599,7 @@ void Worker::ProcessSysTime( const QueueSysTime& ev ) else { assert( !m_sysTimePlot->data.empty() ); - assert( m_sysTimePlot->data.back().time <= time ); + assert( m_sysTimePlot->data.back().time.Val() <= time ); if( m_sysTimePlot->min > val ) m_sysTimePlot->min = val; else if( m_sysTimePlot->max < val ) m_sysTimePlot->max = val; m_sysTimePlot->data.push_back_non_empty( { time, val } ); @@ -4741,7 +4744,7 @@ void Worker::MemAllocChanged( int64_t time ) else { assert( !m_data.memory.plot->data.empty() ); - assert( m_data.memory.plot->data.back().time <= time ); + assert( m_data.memory.plot->data.back().time.Val() <= time ); if( m_data.memory.plot->min > val ) m_data.memory.plot->min = val; else if( m_data.memory.plot->max < val ) m_data.memory.plot->max = val; m_data.memory.plot->data.push_back_non_empty( { time, val } ); @@ -5576,7 +5579,7 @@ void Worker::Write( FileWrite& f ) f.Write( &sz, sizeof( sz ) ); for( auto& v : plot->data ) { - WriteTimeOffset( f, refTime, v.time ); + WriteTimeOffset( f, refTime, v.time.Val() ); f.Write( &v.val, sizeof( v.val ) ); } }