diff --git a/profiler/src/profiler/TracyView.hpp b/profiler/src/profiler/TracyView.hpp index 8f71664a..b839a0af 100644 --- a/profiler/src/profiler/TracyView.hpp +++ b/profiler/src/profiler/TracyView.hpp @@ -440,6 +440,7 @@ private: void FindZones(); void FindZonesCompare(); + bool IsGpuSourceLocation( int16_t srcloc ) const; std::vector GetMemoryPages() const; diff --git a/profiler/src/profiler/TracyView_FindZone.cpp b/profiler/src/profiler/TracyView_FindZone.cpp index ef7ecc7a..518a15a7 100644 --- a/profiler/src/profiler/TracyView_FindZone.cpp +++ b/profiler/src/profiler/TracyView_FindZone.cpp @@ -23,10 +23,14 @@ void View::FindZones() m_findZone.match = m_worker.GetMatchingSourceLocation( m_findZone.pattern, m_findZone.ignoreCase ); if( m_findZone.match.empty() ) return; + const auto& gpuMap = m_worker.GetGpuSourceLocationZones(); auto it = m_findZone.match.begin(); while( it != m_findZone.match.end() ) { - if( m_worker.GetZonesForSourceLocation( *it ).zones.empty() ) + const bool hasCpu = !m_worker.GetZonesForSourceLocation( *it ).zones.empty(); + const auto gpu_it = gpuMap.find( *it ); + const bool hasGpu = gpu_it != gpuMap.end() && !gpu_it->second.zones.empty(); + if( !hasCpu && !hasGpu ) { it = m_findZone.match.erase( it ); } @@ -37,6 +41,14 @@ void View::FindZones() } } +bool View::IsGpuSourceLocation( int16_t srcloc ) const +{ + if( !m_worker.GetZonesForSourceLocation( srcloc ).zones.empty() ) return false; + const auto& gpuMap = m_worker.GetGpuSourceLocationZones(); + const auto it = gpuMap.find( srcloc ); + return it != gpuMap.end() && !it->second.zones.empty(); +} + uint64_t View::GetSelectionTarget( const Worker::ZoneThreadData& ev, FindZone::GroupBy groupBy ) const { switch( groupBy ) @@ -372,7 +384,17 @@ void View::DrawFindZone() for( auto& v : m_findZone.match ) { auto& srcloc = m_worker.GetSourceLocation( v ); - auto& zones = m_worker.GetZonesForSourceLocation( v ).zones; + const auto isGpuLoc = IsGpuSourceLocation( v ); + size_t zoneCnt; + if( isGpuLoc ) + { + const auto& gpuMap = m_worker.GetGpuSourceLocationZones(); + zoneCnt = gpuMap.find( v )->second.zones.size(); + } + else + { + zoneCnt = m_worker.GetZonesForSourceLocation( v ).zones.size(); + } SmallColorBox( GetSrcLocColor( srcloc, 0 ) ); ImGui::SameLine(); ImGui::PushID( idx ); @@ -390,7 +412,7 @@ void View::DrawFindZone() ImGui::SameLine(); } const auto fileName = m_worker.GetString( srcloc.file ); - ImGui::TextColored( ImVec4( 0.5, 0.5, 0.5, 1 ), "(%s) %s", RealToString( zones.size() ), LocationToString( fileName, srcloc.line ) ); + ImGui::TextColored( ImVec4( 0.5, 0.5, 0.5, 1 ), "(%s) %s%s", RealToString( zoneCnt ), isGpuLoc ? "[GPU] " : "", LocationToString( fileName, srcloc.line ) ); if( ImGui::IsItemHovered() ) { DrawSourceTooltip( fileName, srcloc.line, srcloc.line ); @@ -423,9 +445,27 @@ void View::DrawFindZone() ImGui::Separator(); - auto& zoneData = m_worker.GetZonesForSourceLocation( m_findZone.match[m_findZone.selMatch] ); - auto& zones = zoneData.zones; - zones.ensure_sorted(); + const auto matchSrcloc = m_findZone.match[m_findZone.selMatch]; + const bool isGpu = IsGpuSourceLocation( matchSrcloc ); + + size_t zsz; + int64_t rawTotal, selfTotal; + if( !isGpu ) + { + auto& zoneData = m_worker.GetZonesForSourceLocation( matchSrcloc ); + zoneData.zones.ensure_sorted(); + zsz = zoneData.zones.size(); + rawTotal = zoneData.total; + selfTotal = zoneData.selfTotal; + } + else + { + auto& zoneData = m_worker.GetGpuZonesForSourceLocation( matchSrcloc ); + zoneData.zones.ensure_sorted(); + zsz = zoneData.zones.size(); + rawTotal = zoneData.total; + selfTotal = zoneData.selfTotal; + } if( ImGui::TreeNodeEx( "Histogram", ImGuiTreeNodeFlags_DefaultOpen ) ) { const auto ty = ImGui::GetTextLineHeight(); @@ -434,109 +474,180 @@ void View::DrawFindZone() int64_t tmax = m_findZone.tmax; int64_t total = m_findZone.total; double sumSq = m_findZone.sumSq; - const auto zsz = zones.size(); if( m_findZone.sortedNum != zsz ) { auto& vec = m_findZone.sorted; const auto vszorig = vec.size(); vec.reserve( zsz ); size_t i; - if( m_findZone.runningTime ) + if( !isGpu ) { - if( m_findZone.range.active ) + auto& zoneData = m_worker.GetZonesForSourceLocation( matchSrcloc ); + auto& zones = zoneData.zones; + if( m_findZone.runningTime ) { - for( i=m_findZone.sortedNum; i rangeMax || zone.Start() < rangeMin ) continue; - const auto ctx = m_worker.GetContextSwitchData( m_worker.DecompressThread( zones[i].Thread() ) ); - if( !ctx ) break; - int64_t t; - if( !GetZoneRunningTime( ctx, zone, t ) ) break; - vec.push_back_no_space_check( t ); - total += t; - sumSq += double( t ) * t; - if( t < tmin ) tmin = t; - else if( t > tmax ) tmax = t; + for( i=m_findZone.sortedNum; i rangeMax || zone.Start() < rangeMin ) continue; + const auto ctx = m_worker.GetContextSwitchData( m_worker.DecompressThread( zones[i].Thread() ) ); + if( !ctx ) break; + int64_t t; + if( !GetZoneRunningTime( ctx, zone, t ) ) break; + vec.push_back_no_space_check( t ); + total += t; + sumSq += double( t ) * t; + if( t < tmin ) tmin = t; + else if( t > tmax ) tmax = t; + } + } + else + { + for( i=m_findZone.sortedNum; i tmax ) tmax = t; + } + } + } + else if( m_findZone.selfTime ) + { + tmin = zoneData.selfMin; + tmax = zoneData.selfMax; + if( m_findZone.range.active ) + { + for( i=m_findZone.sortedNum; i rangeMax || start < rangeMin ) continue; + const auto t = end - start - GetZoneChildTimeFast( zone ); + vec.push_back_no_space_check( t ); + total += t; + sumSq += double( t ) * t; + } + } + else + { + for( i=m_findZone.sortedNum; i tmax ) tmax = t; + for( i=m_findZone.sortedNum; i rangeMax || start < rangeMin ) continue; + const auto t = end - start; + vec.push_back_no_space_check( t ); + total += t; + sumSq += double( t ) * t; + } } - } - } - else if( m_findZone.selfTime ) - { - tmin = zoneData.selfMin; - tmax = zoneData.selfMax; - if( m_findZone.range.active ) - { - for( i=m_findZone.sortedNum; i rangeMax || start < rangeMin ) continue; - const auto t = end - start - GetZoneChildTimeFast( zone ); - vec.push_back_no_space_check( t ); - total += t; - sumSq += double( t ) * t; - } - } - else - { - for( i=m_findZone.sortedNum; i rangeMax || start < rangeMin ) continue; - const auto t = end - start; - vec.push_back_no_space_check( t ); - total += t; - sumSq += double( t ) * t; + for( i=m_findZone.sortedNum; i rangeMax || start < rangeMin ) continue; + const auto t = end - start - GetZoneChildTime( zone ); + vec.push_back_no_space_check( t ); + total += t; + sumSq += double( t ) * t; + } + } + else + { + for( i=m_findZone.sortedNum; i rangeMax || start < rangeMin ) continue; + const auto t = end - start; + vec.push_back_no_space_check( t ); + total += t; + sumSq += double( t ) * t; + } + } + else + { + for( i=m_findZone.sortedNum; isecond : empty; } +Worker::GpuSourceLocationZones& Worker::GetGpuZonesForSourceLocation( int16_t srcloc ) +{ + assert( AreGpuSourceLocationZonesReady() ); + static GpuSourceLocationZones empty; + auto it = m_data.gpuSourceLocationZones.find( srcloc ); + return it != m_data.gpuSourceLocationZones.end() ? it->second : empty; +} + +const Worker::GpuSourceLocationZones& Worker::GetGpuZonesForSourceLocation( int16_t srcloc ) const +{ + assert( AreGpuSourceLocationZonesReady() ); + static const GpuSourceLocationZones empty; + auto it = m_data.gpuSourceLocationZones.find( srcloc ); + return it != m_data.gpuSourceLocationZones.end() ? it->second : empty; +} + const SymbolStats* Worker::GetSymbolStats( uint64_t symAddr ) const { assert( AreCallstackSamplesReady() ); @@ -3603,6 +3619,31 @@ Worker::GpuSourceLocationZones* Worker::GetGpuSourceLocationZonesReal( uint16_t m_data.gpuZonesLast.second = &it->second; return &it->second; } + +int64_t Worker::GetGpuChildTime( const GpuEvent& zone ) +{ + int64_t time = 0; + if( zone.Child() >= 0 ) + { + auto& children = GetGpuChildren( zone.Child() ); + if( children.is_magic() ) + { + auto& vec = *(Vector*)&children; + for( auto& v : vec ) + { + time += std::max( int64_t( 0 ), v.GpuEnd() - v.GpuStart() ); + } + } + else + { + for( auto& v : children ) + { + time += std::max( int64_t( 0 ), v->GpuEnd() - v->GpuStart() ); + } + } + } + return time; +} #else uint64_t* Worker::GetSourceLocationZonesCntReal( uint16_t srcloc ) { @@ -6200,6 +6241,10 @@ void Worker::ProcessGpuTime( const QueueGpuTime& ev ) if( slz->max < timeSpan ) slz->max = timeSpan; slz->total += timeSpan; slz->sumSq += double( timeSpan ) * timeSpan; + const auto selfSpan = timeSpan - GetGpuChildTime( *zone ); + if( slz->selfMin > selfSpan ) slz->selfMin = selfSpan; + if( slz->selfMax < selfSpan ) slz->selfMax = selfSpan; + slz->selfTotal += selfSpan; } #else CountZoneStatistics( zone ); @@ -8118,6 +8163,10 @@ void Worker::ReconstructZoneStatistics( GpuEvent& zone, uint16_t thread ) if( slz.max < timeSpan ) slz.max = timeSpan; slz.total += timeSpan; slz.sumSq += double( timeSpan ) * timeSpan; + const auto selfSpan = timeSpan - GetGpuChildTime( zone ); + if( slz.selfMin > selfSpan ) slz.selfMin = selfSpan; + if( slz.selfMax < selfSpan ) slz.selfMax = selfSpan; + slz.selfTotal += selfSpan; } } #else diff --git a/server/TracyWorker.hpp b/server/TracyWorker.hpp index 1ad677e9..0547ed3b 100644 --- a/server/TracyWorker.hpp +++ b/server/TracyWorker.hpp @@ -224,6 +224,9 @@ private: int64_t max = std::numeric_limits::min(); int64_t total = 0; double sumSq = 0; + int64_t selfMin = std::numeric_limits::max(); + int64_t selfMax = std::numeric_limits::min(); + int64_t selfTotal = 0; }; struct CallstackFrameIdHash @@ -645,6 +648,8 @@ public: #ifndef TRACY_NO_STATISTICS SourceLocationZones& GetZonesForSourceLocation( int16_t srcloc ); const SourceLocationZones& GetZonesForSourceLocation( int16_t srcloc ) const; + GpuSourceLocationZones& GetGpuZonesForSourceLocation( int16_t srcloc ); + const GpuSourceLocationZones& GetGpuZonesForSourceLocation( int16_t srcloc ) const; const unordered_flat_map& GetSourceLocationZones() const { return m_data.sourceLocationZones; } const unordered_flat_map& GetGpuSourceLocationZones() const { return m_data.gpuSourceLocationZones; } bool AreSourceLocationZonesReady() const { return m_data.sourceLocationZonesReady; } @@ -933,6 +938,8 @@ private: return GetGpuSourceLocationZonesReal( srcloc ); } GpuSourceLocationZones* GetGpuSourceLocationZonesReal( uint16_t srcloc ); + + int64_t GetGpuChildTime( const GpuEvent& zone ); #else uint64_t* GetSourceLocationZonesCnt( uint16_t srcloc ) {