Simplify context switch precalculation.

This commit is contained in:
Bartosz Taudul 2023-03-25 00:18:53 +01:00
parent 734753a941
commit efa095e25f
No known key found for this signature in database
GPG Key ID: B7FE2008B7575DF3
5 changed files with 68 additions and 98 deletions

View File

@ -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;

View File

@ -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;
} }

View File

@ -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 );

View File

@ -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,12 +255,16 @@ 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 ) );
if( num == 1 )
{
DrawLine( draw, dpos + ImVec2( px0, offset + ty05 - 0.5f ), dpos + ImVec2( minpx, offset + ty05 - 0.5f ), 0xFF22DD22, lineSize ); DrawLine( draw, dpos + ImVec2( px0, offset + ty05 - 0.5f ), dpos + ImVec2( minpx, offset + ty05 - 0.5f ), 0xFF22DD22, lineSize );
if( hover && ImGui::IsMouseHoveringRect( wpos + ImVec2( px0, offset ), wpos + ImVec2( minpx, offset + ty + 1 ) ) ) if( hover && ImGui::IsMouseHoveringRect( wpos + ImVec2( px0, offset ), wpos + ImVec2( minpx, offset + ty + 1 ) ) )
{ {
@ -286,20 +291,15 @@ void View::DrawContextSwitchList( const TimelineContext& ctx, const std::vector<
ZoomToRange( ev.Start(), end ); ZoomToRange( ev.Start(), end );
} }
} }
break;
} }
case ContextSwitchDrawType::FoldedMulti: else
{ {
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 ); 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 ) ) ) if( hover && ImGui::IsMouseHoveringRect( wpos + ImVec2( px0, offset ), wpos + ImVec2( minpx, offset + ty + 1 ) ) )
{ {
ImGui::BeginTooltip(); ImGui::BeginTooltip();
TextFocused( isFiber ? "Fiber is" : "Thread is", "changing activity multiple times" ); TextFocused( isFiber ? "Fiber is" : "Thread is", "changing activity multiple times" );
TextFocused( "Number of running regions:", RealToString( v.folded.num ) ); TextFocused( "Number of running regions:", RealToString( num ) );
TextFocused( "Time:", TimeToString( end - ev.Start() ) ); TextFocused( "Time:", TimeToString( end - ev.Start() ) );
ImGui::EndTooltip(); ImGui::EndTooltip();
@ -308,6 +308,7 @@ void View::DrawContextSwitchList( const TimelineContext& ctx, const std::vector<
ZoomToRange( ev.Start(), end ); ZoomToRange( ev.Start(), end );
} }
} }
}
break; break;
} }
case ContextSwitchDrawType::Running: case ContextSwitchDrawType::Running:

View File

@ -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 )
{ {