mirror of
https://github.com/wolfpld/tracy.git
synced 2024-11-29 08:54:34 +00:00
Simplify context switch precalculation.
This commit is contained in:
parent
734753a941
commit
efa095e25f
@ -30,40 +30,25 @@ struct TimelineDraw
|
|||||||
enum class ContextSwitchDrawType : uint8_t
|
enum class ContextSwitchDrawType : uint8_t
|
||||||
{
|
{
|
||||||
Waiting,
|
Waiting,
|
||||||
FoldedOne,
|
Folded,
|
||||||
FoldedMulti,
|
|
||||||
Running
|
Running
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ContextSwitchDrawFolded
|
|
||||||
{
|
|
||||||
Int48 rend;
|
|
||||||
int num;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ContextSwitchDrawWaiting
|
|
||||||
{
|
|
||||||
short_ptr<ContextSwitchData> prev;
|
|
||||||
uint32_t waitStack;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ContextSwitchDraw
|
struct ContextSwitchDraw
|
||||||
{
|
{
|
||||||
ContextSwitchDrawType type;
|
ContextSwitchDrawType type;
|
||||||
short_ptr<ContextSwitchData> ev;
|
uint32_t idx;
|
||||||
union
|
uint32_t data; // Folded: number of items -OR- Waiting: wait stack
|
||||||
{
|
|
||||||
ContextSwitchDrawFolded folded;
|
|
||||||
ContextSwitchDrawWaiting waiting;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct SamplesDraw
|
struct SamplesDraw
|
||||||
{
|
{
|
||||||
uint32_t num;
|
uint32_t num;
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct MessagesDraw
|
struct MessagesDraw
|
||||||
{
|
{
|
||||||
short_ptr<MessageData> msg;
|
short_ptr<MessageData> msg;
|
||||||
|
@ -469,7 +469,7 @@ void TimelineItemThread::PreprocessContextSwitches( const TimelineContext& ctx,
|
|||||||
if( it == citend ) return;
|
if( it == citend ) return;
|
||||||
if( citend != vec.end() ) ++citend;
|
if( citend != vec.end() ) ++citend;
|
||||||
|
|
||||||
const auto MinCtxNs = MinCtxSize * nspx;
|
const auto MinCtxNs = int64_t( round( GetScale() * MinCtxSize * nspx ) );
|
||||||
const auto& sampleData = m_thread->samples;
|
const auto& sampleData = m_thread->samples;
|
||||||
|
|
||||||
auto pit = citend;
|
auto pit = citend;
|
||||||
@ -492,50 +492,32 @@ void TimelineItemThread::PreprocessContextSwitches( const TimelineContext& ctx,
|
|||||||
}
|
}
|
||||||
if( found ) waitStack = sdit->callstack.Val();
|
if( found ) waitStack = sdit->callstack.Val();
|
||||||
}
|
}
|
||||||
|
m_ctxDraw.emplace_back( ContextSwitchDraw { ContextSwitchDrawType::Waiting, uint32_t( it - vec.begin() ), waitStack } );
|
||||||
auto& ref = m_ctxDraw.emplace_back( ContextSwitchDraw { ContextSwitchDrawType::Waiting, &ev } );
|
|
||||||
ref.waiting.prev = pit;
|
|
||||||
ref.waiting.waitStack = waitStack;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto end = ev.IsEndValid() ? ev.End() : m_worker.GetLastTime();
|
const auto end = ev.IsEndValid() ? ev.End() : m_worker.GetLastTime();
|
||||||
const auto zsz = end - ev.Start();
|
const auto zsz = end - ev.Start();
|
||||||
if( zsz < MinCtxNs )
|
if( zsz < MinCtxNs )
|
||||||
{
|
{
|
||||||
int num = 0;
|
|
||||||
auto px1ns = end - vStart;
|
|
||||||
auto rend = end;
|
|
||||||
auto nextTime = end + MinCtxNs;
|
auto nextTime = end + MinCtxNs;
|
||||||
|
auto next = it + 1;
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
const auto prevIt = it;
|
next = std::lower_bound( next, citend, nextTime, [] ( const auto& l, const auto& r ) { return (uint64_t)l.End() < (uint64_t)r; } );
|
||||||
it = std::lower_bound( it, citend, nextTime, [] ( const auto& l, const auto& r ) { return (uint64_t)l.End() < (uint64_t)r; } );
|
if( next == citend ) break;
|
||||||
if( it == prevIt ) ++it;
|
auto prev = next - 1;
|
||||||
num += std::distance( prevIt, it );
|
const auto pt = prev->IsEndValid() ? prev->End() : m_worker.GetLastTime();
|
||||||
if( it == citend ) break;
|
const auto nt = next->IsEndValid() ? next->End() : m_worker.GetLastTime();
|
||||||
const auto nend = it->IsEndValid() ? it->End() : m_worker.GetLastTime();
|
if( nt - pt >= MinCtxNs ) break;
|
||||||
const auto nsnext = nend - vStart;
|
nextTime = nt + MinCtxNs;
|
||||||
if( nsnext - px1ns >= MinCtxNs * 2 ) break;
|
|
||||||
px1ns = nsnext;
|
|
||||||
rend = nend;
|
|
||||||
nextTime = nend + nspx;
|
|
||||||
}
|
|
||||||
if( num == 1 )
|
|
||||||
{
|
|
||||||
auto& ref = m_ctxDraw.emplace_back( ContextSwitchDraw { ContextSwitchDrawType::FoldedOne, &ev } );
|
|
||||||
ref.folded.rend = rend;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto& ref = m_ctxDraw.emplace_back( ContextSwitchDraw { ContextSwitchDrawType::FoldedMulti, &ev } );
|
|
||||||
ref.folded.rend = rend;
|
|
||||||
ref.folded.num = num;
|
|
||||||
}
|
}
|
||||||
|
m_ctxDraw.emplace_back( ContextSwitchDraw { ContextSwitchDrawType::Folded, uint32_t( it - vec.begin() ), uint32_t( next - it ) } );
|
||||||
|
it = next;
|
||||||
pit = it-1;
|
pit = it-1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_ctxDraw.emplace_back( ContextSwitchDraw { ContextSwitchDrawType::Running, &ev } );
|
m_ctxDraw.emplace_back( ContextSwitchDraw { ContextSwitchDrawType::Running, uint32_t( it - vec.begin() ) } );
|
||||||
pit = it;
|
pit = it;
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
@ -212,7 +212,7 @@ private:
|
|||||||
void DrawTimeline();
|
void DrawTimeline();
|
||||||
void DrawSampleList( const TimelineContext& ctx, const std::vector<SamplesDraw>& drawList, const Vector<SampleData>& vec, int offset );
|
void DrawSampleList( const TimelineContext& ctx, const std::vector<SamplesDraw>& drawList, const Vector<SampleData>& vec, int offset );
|
||||||
void DrawZoneList( const TimelineContext& ctx, const std::vector<TimelineDraw>& drawList, int offset, uint64_t tid );
|
void DrawZoneList( const TimelineContext& ctx, const std::vector<TimelineDraw>& drawList, int offset, uint64_t tid );
|
||||||
void DrawContextSwitchList( const TimelineContext& ctx, const std::vector<ContextSwitchDraw>& drawList, int offset, int endOffset, bool isFiber );
|
void DrawContextSwitchList( const TimelineContext& ctx, const std::vector<ContextSwitchDraw>& drawList, const Vector<ContextSwitchData>& ctxSwitch, int offset, int endOffset, bool isFiber );
|
||||||
int DispatchGpuZoneLevel( const Vector<short_ptr<GpuEvent>>& vec, bool hover, double pxns, int64_t nspx, const ImVec2& wpos, int offset, int depth, uint64_t thread, float yMin, float yMax, int64_t begin, int drift );
|
int DispatchGpuZoneLevel( const Vector<short_ptr<GpuEvent>>& vec, bool hover, double pxns, int64_t nspx, const ImVec2& wpos, int offset, int depth, uint64_t thread, float yMin, float yMax, int64_t begin, int drift );
|
||||||
template<typename Adapter, typename V>
|
template<typename Adapter, typename V>
|
||||||
int DrawGpuZoneLevel( const V& vec, bool hover, double pxns, int64_t nspx, const ImVec2& wpos, int offset, int depth, uint64_t thread, float yMin, float yMax, int64_t begin, int drift );
|
int DrawGpuZoneLevel( const V& vec, bool hover, double pxns, int64_t nspx, const ImVec2& wpos, int offset, int depth, uint64_t thread, float yMin, float yMax, int64_t begin, int drift );
|
||||||
|
@ -134,7 +134,7 @@ const char* View::DecodeContextSwitchState( uint8_t state )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void View::DrawContextSwitchList( const TimelineContext& ctx, const std::vector<ContextSwitchDraw>& drawList, int offset, int endOffset, bool isFiber )
|
void View::DrawContextSwitchList( const TimelineContext& ctx, const std::vector<ContextSwitchDraw>& drawList, const Vector<ContextSwitchData>& ctxSwitch, int offset, int endOffset, bool isFiber )
|
||||||
{
|
{
|
||||||
constexpr float MinCtxSize = 4;
|
constexpr float MinCtxSize = 4;
|
||||||
|
|
||||||
@ -154,12 +154,13 @@ void View::DrawContextSwitchList( const TimelineContext& ctx, const std::vector<
|
|||||||
|
|
||||||
for( auto& v : drawList )
|
for( auto& v : drawList )
|
||||||
{
|
{
|
||||||
const auto& ev = *v.ev;
|
const auto it = ctxSwitch.begin() + v.idx;
|
||||||
|
const auto& ev = *it;
|
||||||
switch( v.type )
|
switch( v.type )
|
||||||
{
|
{
|
||||||
case ContextSwitchDrawType::Waiting:
|
case ContextSwitchDrawType::Waiting:
|
||||||
{
|
{
|
||||||
const auto& prev = *v.waiting.prev;
|
const auto& prev = *(it-1);
|
||||||
const bool migration = prev.Cpu() != ev.Cpu();
|
const bool migration = prev.Cpu() != ev.Cpu();
|
||||||
const auto px0 = std::max( { ( prev.End() - vStart ) * pxns, -10.0, double( minpx ) } );
|
const auto px0 = std::max( { ( prev.End() - vStart ) * pxns, -10.0, double( minpx ) } );
|
||||||
const auto pxw = ( ev.WakeupVal() - vStart ) * pxns;
|
const auto pxw = ( ev.WakeupVal() - vStart ) * pxns;
|
||||||
@ -238,7 +239,7 @@ void View::DrawContextSwitchList( const TimelineContext& ctx, const std::vector<
|
|||||||
}
|
}
|
||||||
if( tooltip )
|
if( tooltip )
|
||||||
{
|
{
|
||||||
const auto waitStack = v.waiting.waitStack;
|
const auto waitStack = v.data;
|
||||||
if( waitStack )
|
if( waitStack )
|
||||||
{
|
{
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
@ -254,58 +255,58 @@ void View::DrawContextSwitchList( const TimelineContext& ctx, const std::vector<
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ContextSwitchDrawType::FoldedOne:
|
case ContextSwitchDrawType::Folded:
|
||||||
{
|
{
|
||||||
|
const auto num = v.data;
|
||||||
const auto px0 = std::max( ( ev.Start() - vStart ) * pxns, -10.0 );
|
const auto px0 = std::max( ( ev.Start() - vStart ) * pxns, -10.0 );
|
||||||
const auto end = v.folded.rend.Val();
|
const auto eit = it + num - 1;
|
||||||
|
const auto end = eit->IsEndValid() ? eit->End() : m_worker.GetLastTime();
|
||||||
const auto px1ns = end - vStart;
|
const auto px1ns = end - vStart;
|
||||||
minpx = std::min( std::max( px1ns * pxns, px0+MinCtxSize ), double( w + 10 ) );
|
minpx = std::min( std::max( px1ns * pxns, px0+MinCtxSize ), double( w + 10 ) );
|
||||||
DrawLine( draw, dpos + ImVec2( px0, offset + ty05 - 0.5f ), dpos + ImVec2( minpx, offset + ty05 - 0.5f ), 0xFF22DD22, lineSize );
|
if( num == 1 )
|
||||||
if( hover && ImGui::IsMouseHoveringRect( wpos + ImVec2( px0, offset ), wpos + ImVec2( minpx, offset + ty + 1 ) ) )
|
|
||||||
{
|
{
|
||||||
ImGui::BeginTooltip();
|
DrawLine( draw, dpos + ImVec2( px0, offset + ty05 - 0.5f ), dpos + ImVec2( minpx, offset + ty05 - 0.5f ), 0xFF22DD22, lineSize );
|
||||||
if( isFiber )
|
if( hover && ImGui::IsMouseHoveringRect( wpos + ImVec2( px0, offset ), wpos + ImVec2( minpx, offset + ty + 1 ) ) )
|
||||||
{
|
{
|
||||||
const auto tid = m_worker.DecompressThread( ev.Thread() );
|
ImGui::BeginTooltip();
|
||||||
TextFocused( "Fiber is", "running" );
|
if( isFiber )
|
||||||
TextFocused( "Activity time:", TimeToString( end - ev.Start() ) );
|
{
|
||||||
TextFocused( "Thread:", m_worker.GetThreadName( tid ) );
|
const auto tid = m_worker.DecompressThread( ev.Thread() );
|
||||||
ImGui::SameLine();
|
TextFocused( "Fiber is", "running" );
|
||||||
ImGui::TextDisabled( "(%s)", RealToString( tid ) );
|
TextFocused( "Activity time:", TimeToString( end - ev.Start() ) );
|
||||||
}
|
TextFocused( "Thread:", m_worker.GetThreadName( tid ) );
|
||||||
else
|
ImGui::SameLine();
|
||||||
{
|
ImGui::TextDisabled( "(%s)", RealToString( tid ) );
|
||||||
TextFocused( "Thread is", "running" );
|
}
|
||||||
TextFocused( "Activity time:", TimeToString( end - ev.Start() ) );
|
else
|
||||||
TextFocused( "CPU:", RealToString( ev.Cpu() ) );
|
{
|
||||||
}
|
TextFocused( "Thread is", "running" );
|
||||||
ImGui::EndTooltip();
|
TextFocused( "Activity time:", TimeToString( end - ev.Start() ) );
|
||||||
|
TextFocused( "CPU:", RealToString( ev.Cpu() ) );
|
||||||
|
}
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
|
||||||
if( IsMouseClicked( 2 ) )
|
if( IsMouseClicked( 2 ) )
|
||||||
{
|
{
|
||||||
ZoomToRange( ev.Start(), end );
|
ZoomToRange( ev.Start(), end );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
else
|
||||||
}
|
|
||||||
case ContextSwitchDrawType::FoldedMulti:
|
|
||||||
{
|
|
||||||
const auto px0 = std::max( ( ev.Start() - vStart ) * pxns, -10.0 );
|
|
||||||
const auto end = v.folded.rend.Val();
|
|
||||||
const auto px1ns = end - vStart;
|
|
||||||
minpx = std::min( std::max( px1ns * pxns, px0+MinCtxSize ), double( w + 10 ) );
|
|
||||||
DrawZigZag( draw, wpos + ImVec2( 0, offset + ty05 ), px0, minpx, ty/4, 0xFF888888, 1.5 );
|
|
||||||
if( hover && ImGui::IsMouseHoveringRect( wpos + ImVec2( px0, offset ), wpos + ImVec2( minpx, offset + ty + 1 ) ) )
|
|
||||||
{
|
{
|
||||||
ImGui::BeginTooltip();
|
DrawZigZag( draw, wpos + ImVec2( 0, offset + ty05 ), px0, minpx, ty/4, 0xFF888888, 1.5 );
|
||||||
TextFocused( isFiber ? "Fiber is" : "Thread is", "changing activity multiple times" );
|
if( hover && ImGui::IsMouseHoveringRect( wpos + ImVec2( px0, offset ), wpos + ImVec2( minpx, offset + ty + 1 ) ) )
|
||||||
TextFocused( "Number of running regions:", RealToString( v.folded.num ) );
|
|
||||||
TextFocused( "Time:", TimeToString( end - ev.Start() ) );
|
|
||||||
ImGui::EndTooltip();
|
|
||||||
|
|
||||||
if( IsMouseClicked( 2 ) )
|
|
||||||
{
|
{
|
||||||
ZoomToRange( ev.Start(), end );
|
ImGui::BeginTooltip();
|
||||||
|
TextFocused( isFiber ? "Fiber is" : "Thread is", "changing activity multiple times" );
|
||||||
|
TextFocused( "Number of running regions:", RealToString( num ) );
|
||||||
|
TextFocused( "Time:", TimeToString( end - ev.Start() ) );
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
|
||||||
|
if( IsMouseClicked( 2 ) )
|
||||||
|
{
|
||||||
|
ZoomToRange( ev.Start(), end );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -69,7 +69,9 @@ void View::DrawThread( const TimelineContext& ctx, const ThreadData& thread, con
|
|||||||
|
|
||||||
if( hasCtxSwitch )
|
if( hasCtxSwitch )
|
||||||
{
|
{
|
||||||
DrawContextSwitchList( ctx, ctxDraw, ctxOffset, offset, thread.isFiber );
|
auto ctxSwitch = m_worker.GetContextSwitchData( thread.id );
|
||||||
|
assert( ctxSwitch );
|
||||||
|
DrawContextSwitchList( ctx, ctxDraw, ctxSwitch->v, ctxOffset, offset, thread.isFiber );
|
||||||
}
|
}
|
||||||
if( hasSamples )
|
if( hasSamples )
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user