diff --git a/server/TracyView.cpp b/server/TracyView.cpp index fcdc0cf9..ab09a86e 100644 --- a/server/TracyView.cpp +++ b/server/TracyView.cpp @@ -5941,49 +5941,51 @@ int View::DrawCpuData( int offset, double pxns, const ImVec2& wpos, bool hover, const auto cpuUsageHeight = floor( 30.f * ImGui::GetTextLineHeight() / 15.f ); if( wpos.y + offset + cpuUsageHeight + 3 >= yMin && wpos.y + offset <= yMax ) { + const auto iw = (size_t)w; + m_worker.GetCpuUsage( m_vd.zvStart, nspxdbl, iw, m_cpuUsageBuf ); + const float cpuCntRev = 1.f / cpuCnt; float pos = 0; - int usageOwn, usageOther; + auto usage = m_cpuUsageBuf.begin(); while( pos < w ) { - m_worker.GetCpuUsageAtTime( m_vd.zvStart + pos * nspxdbl, usageOwn, usageOther ); float base; - if( usageOwn != 0 ) + if( usage->first != 0 ) { - base = dpos.y + offset + ( 1.f - usageOwn * cpuCntRev ) * cpuUsageHeight; + base = dpos.y + offset + ( 1.f - usage->first * cpuCntRev ) * cpuUsageHeight; DrawLine( draw, ImVec2( dpos.x + pos, dpos.y + offset + cpuUsageHeight ), ImVec2( dpos.x + pos, base ), 0xFF55BB55 ); } else { base = dpos.y + offset + cpuUsageHeight; } - if( usageOther != 0 ) + if( usage->second != 0 ) { - int usageTotal = usageOwn + usageOther; + int usageTotal = usage->first + usage->second; DrawLine( draw, ImVec2( dpos.x + pos, base ), ImVec2( dpos.x + pos, dpos.y + offset + ( 1.f - usageTotal * cpuCntRev ) * cpuUsageHeight ), 0xFF666666 ); } pos++; + usage++; } DrawLine( draw, dpos + ImVec2( 0, offset+cpuUsageHeight+2 ), dpos + ImVec2( w, offset+cpuUsageHeight+2 ), 0x22DD88DD ); if( hover && ImGui::IsMouseHoveringRect( ImVec2( wpos.x, wpos.y + offset ), ImVec2( wpos.x + w, wpos.y + offset + cpuUsageHeight ), true ) ) { - const auto mt = m_vd.zvStart + ( ImGui::GetIO().MousePos.x - wpos.x ) * nspxdbl; - int usageOwn, usageOther; - m_worker.GetCpuUsageAtTime( mt, usageOwn, usageOther ); + const auto& usage = m_cpuUsageBuf[ImGui::GetIO().MousePos.x - wpos.x]; ImGui::BeginTooltip(); - TextFocused( "Cores used by profiled program:", RealToString( usageOwn ) ); + TextFocused( "Cores used by profiled program:", RealToString( usage.first ) ); ImGui::SameLine(); char buf[64]; - PrintStringPercent( buf, usageOwn * cpuCntRev * 100 ); + PrintStringPercent( buf, usage.first * cpuCntRev * 100 ); TextDisabledUnformatted( buf ); - TextFocused( "Cores used by other programs:", RealToString( usageOther ) ); + TextFocused( "Cores used by other programs:", RealToString( usage.second ) ); ImGui::SameLine(); - PrintStringPercent( buf, usageOther * cpuCntRev * 100 ); + PrintStringPercent( buf, usage.second * cpuCntRev * 100 ); TextDisabledUnformatted( buf ); TextFocused( "Number of cores:", RealToString( cpuCnt ) ); - if( usageOwn + usageOther != 0 ) + if( usage.first + usage.second != 0 ) { + const auto mt = m_vd.zvStart + ( ImGui::GetIO().MousePos.x - wpos.x ) * nspxdbl; ImGui::Separator(); for( int i=0; i> m_cpuUsageBuf; }; } diff --git a/server/TracyWorker.cpp b/server/TracyWorker.cpp index 8ced6772..731c3928 100644 --- a/server/TracyWorker.cpp +++ b/server/TracyWorker.cpp @@ -2129,48 +2129,68 @@ uint64_t Worker::GetPidFromTid( uint64_t tid ) const return it->second; } -void Worker::GetCpuUsageAtTime( int64_t time, int& own, int& other ) const +void Worker::GetCpuUsage( int64_t t0, double tstep, size_t num, std::vector>& out ) { - own = other = 0; - if( time < 0 || time > m_data.lastTime ) return; + if( out.size() < num ) out.resize( num ); -#ifndef TRACY_NO_STATISTICS - // Remove this check when real-time ctxUsage contruction is implemented. - if( !m_data.ctxUsage.empty() ) + auto ptr = out.data(); + for( size_t i=0; iOwn(); - other = it->Other(); - return; - } -#endif - - int cntOwn = 0; - int cntOther = 0; - for( int i=0; i m_data.lastTime ) { - auto it = std::lower_bound( cs.begin(), cs.end(), time, [] ( const auto& l, const auto& r ) { return (uint64_t)l.End() < (uint64_t)r; } ); - if( it != cs.end() && it->IsEndValid() && it->Start() <= time ) + ptr->first = 0; + ptr->second = 0; + } + else + { +#ifndef TRACY_NO_STATISTICS + if( !m_data.ctxUsage.empty() ) { - if( GetPidFromTid( DecompressThreadExternal( it->Thread() ) ) == m_pid ) + const auto test = ( time << 16 ) | 0xFFFF; + auto it = std::upper_bound( m_data.ctxUsage.begin(), m_data.ctxUsage.end(), test, [] ( const auto& l, const auto& r ) { return l < r._time_other_own; } ); + if( it == m_data.ctxUsage.begin() || it == m_data.ctxUsage.end() ) { - cntOwn++; + ptr->first = 0; + ptr->second = 0; } else { - cntOther++; + --it; + ptr->first = it->Own(); + ptr->second = it->Other(); } } + else +#endif + { + int cntOwn = 0; + int cntOther = 0; + for( int i=0; iIsEndValid() && it->Start() <= time ) + { + if( GetPidFromTid( DecompressThreadExternal( it->Thread() ) ) == m_pid ) + { + cntOwn++; + } + else + { + cntOther++; + } + } + } + } + ptr->first = cntOwn; + ptr->second = cntOther; + } } + ptr++; } - own = cntOwn; - other = cntOther; } const ContextSwitch* const Worker::GetContextSwitchDataImpl( uint64_t thread ) diff --git a/server/TracyWorker.hpp b/server/TracyWorker.hpp index 39f96277..0994ca11 100644 --- a/server/TracyWorker.hpp +++ b/server/TracyWorker.hpp @@ -468,7 +468,7 @@ public: int GetCpuDataCpuCount() const { return m_data.cpuDataCount; } uint64_t GetPidFromTid( uint64_t tid ) const; const unordered_flat_map& GetCpuThreadData() const { return m_data.cpuThreadData; } - void GetCpuUsageAtTime( int64_t time, int& own, int& other ) const; + void GetCpuUsage( int64_t t0, double tstep, size_t num, std::vector>& out ); const unordered_flat_map& GetSourceFileCache() const { return m_data.sourceFileCache; } uint64_t GetSourceFileCacheCount() const { return m_data.sourceFileCache.size(); } uint64_t GetSourceFileCacheSize() const;