Time distribution may now only include running time.

This commit is contained in:
Bartosz Taudul 2019-10-09 22:13:52 +02:00
parent 6ced346e08
commit 0a358ac1f0
2 changed files with 115 additions and 48 deletions

View File

@ -5252,20 +5252,20 @@ struct ZoneTimeData
uint64_t count; uint64_t count;
}; };
void CalcZoneTimeData( flat_hash_map<int16_t, ZoneTimeData, nohash<uint16_t>>& data, flat_hash_map<int16_t, ZoneTimeData, nohash<uint16_t>>::iterator zit, const ZoneEvent& zone, Worker& worker ) void View::CalcZoneTimeData( flat_hash_map<int16_t, ZoneTimeData, nohash<uint16_t>>& data, flat_hash_map<int16_t, ZoneTimeData, nohash<uint16_t>>::iterator zit, const ZoneEvent& zone )
{ {
assert( zone.Child() >= 0 ); assert( zone.Child() >= 0 );
const auto& children = worker.GetZoneChildren( zone.Child() ); const auto& children = m_worker.GetZoneChildren( zone.Child() );
for( auto& child : children ) for( auto& child : children )
{ {
const auto t = worker.GetZoneEnd( *child ) - child->Start(); const auto t = m_worker.GetZoneEnd( *child ) - child->Start();
zit->second.time -= t; zit->second.time -= t;
} }
for( auto& child : children ) for( auto& child : children )
{ {
const auto srcloc = child->SrcLoc(); const auto srcloc = child->SrcLoc();
const auto t = worker.GetZoneEnd( *child ) - child->Start(); const auto t = m_worker.GetZoneEnd( *child ) - child->Start();
auto it = data.find( srcloc ); auto it = data.find( srcloc );
if( it == data.end() ) if( it == data.end() )
{ {
@ -5276,7 +5276,41 @@ void CalcZoneTimeData( flat_hash_map<int16_t, ZoneTimeData, nohash<uint16_t>>& d
it->second.time += t; it->second.time += t;
it->second.count++; it->second.count++;
} }
if( child->Child() >= 0 ) CalcZoneTimeData( data, it, *child, worker ); if( child->Child() >= 0 ) CalcZoneTimeData( data, it, *child );
}
}
void View::CalcZoneTimeData( const ContextSwitch* ctx, flat_hash_map<int16_t, ZoneTimeData, nohash<uint16_t>>& data, flat_hash_map<int16_t, ZoneTimeData, nohash<uint16_t>>::iterator zit, const ZoneEvent& zone )
{
assert( zone.Child() >= 0 );
const auto& children = m_worker.GetZoneChildren( zone.Child() );
for( auto& child : children )
{
int64_t t;
uint64_t cnt;
const auto res = GetZoneRunningTime( ctx, *child, t, cnt );
assert( res );
zit->second.time -= t;
}
for( auto& child : children )
{
const auto srcloc = child->SrcLoc();
int64_t t;
uint64_t cnt;
const auto res = GetZoneRunningTime( ctx, *child, t, cnt );
assert( res );
auto it = data.find( srcloc );
if( it == data.end() )
{
it = data.emplace( srcloc, ZoneTimeData { t, 1 } ).first;
}
else
{
it->second.time += t;
it->second.count++;
}
if( child->Child() >= 0 ) CalcZoneTimeData( ctx, data, it, *child );
} }
} }
@ -6084,59 +6118,87 @@ void View::DrawZoneInfoWindow()
bool expand = ImGui::TreeNode( "Time distribution" ); bool expand = ImGui::TreeNode( "Time distribution" );
if( expand ) if( expand )
{ {
ImGui::SameLine();
if( ctx )
{
SmallCheckbox( "Running time", &m_timeDist.runningTime );
}
flat_hash_map<int16_t, ZoneTimeData, nohash<uint16_t>> data; flat_hash_map<int16_t, ZoneTimeData, nohash<uint16_t>> data;
auto it = data.emplace( ev.SrcLoc(), ZoneTimeData{ ztime, 1 } ).first; float fztime;
CalcZoneTimeData( data, it, ev, m_worker ); if( m_timeDist.runningTime )
std::vector<flat_hash_map<int16_t, ZoneTimeData, nohash<uint16_t>>::const_iterator> vec;
vec.reserve( data.size() );
for( auto it = data.cbegin(); it != data.cend(); ++it ) vec.emplace_back( it );
static bool widthSet = false;
ImGui::Columns( 3 );
if( !widthSet )
{ {
widthSet = true; assert( ctx );
const auto w = ImGui::GetWindowWidth(); int64_t time;
ImGui::SetColumnWidth( 0, w * 0.57f ); uint64_t cnt;
ImGui::SetColumnWidth( 1, w * 0.25f ); if( !GetZoneRunningTime( ctx, ev, time, cnt ) )
ImGui::SetColumnWidth( 2, w * 0.18f ); {
TextDisabledUnformatted( "Incomplete context switch data." );
}
else
{
auto it = data.emplace( ev.SrcLoc(), ZoneTimeData{ time, 1 } ).first;
CalcZoneTimeData( ctx, data, it, ev );
}
fztime = 100.f / time;
} }
if( ImGui::SmallButton( "Zone" ) ) m_timeDist.sortBy = TimeDistribution::SortBy::Count; else
ImGui::NextColumn();
if( ImGui::SmallButton( "Time" ) ) m_timeDist.sortBy = TimeDistribution::SortBy::Time;
ImGui::NextColumn();
if( ImGui::SmallButton( "MTPC" ) ) m_timeDist.sortBy = TimeDistribution::SortBy::Mtpc;
ImGui::NextColumn();
ImGui::Separator();
switch( m_timeDist.sortBy )
{ {
case TimeDistribution::SortBy::Count: auto it = data.emplace( ev.SrcLoc(), ZoneTimeData{ ztime, 1 } ).first;
pdqsort_branchless( vec.begin(), vec.end(), []( const auto& lhs, const auto& rhs ) { return lhs->second.count > rhs->second.count; } ); CalcZoneTimeData( data, it, ev );
break; fztime = 100.f / ztime;
case TimeDistribution::SortBy::Time:
pdqsort_branchless( vec.begin(), vec.end(), []( const auto& lhs, const auto& rhs ) { return lhs->second.time > rhs->second.time; } );
break;
case TimeDistribution::SortBy::Mtpc:
pdqsort_branchless( vec.begin(), vec.end(), []( const auto& lhs, const auto& rhs ) { return float( lhs->second.time ) / lhs->second.count > float( rhs->second.time ) / rhs->second.count; } );
break;
default:
assert( false );
break;
} }
const auto fztime = 100.f / ztime; if( !data.empty() )
for( auto& v : vec )
{ {
ImGui::TextUnformatted( m_worker.GetZoneName( m_worker.GetSourceLocation( v->first ) ) ); std::vector<flat_hash_map<int16_t, ZoneTimeData, nohash<uint16_t>>::const_iterator> vec;
ImGui::SameLine(); vec.reserve( data.size() );
ImGui::TextDisabled( "(\xc3\x97%s)", RealToString( v->second.count, true ) ); for( auto it = data.cbegin(); it != data.cend(); ++it ) vec.emplace_back( it );
static bool widthSet = false;
ImGui::Columns( 3 );
if( !widthSet )
{
widthSet = true;
const auto w = ImGui::GetWindowWidth();
ImGui::SetColumnWidth( 0, w * 0.57f );
ImGui::SetColumnWidth( 1, w * 0.25f );
ImGui::SetColumnWidth( 2, w * 0.18f );
}
if( ImGui::SmallButton( "Zone" ) ) m_timeDist.sortBy = TimeDistribution::SortBy::Count;
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::TextUnformatted( TimeToString( v->second.time ) ); if( ImGui::SmallButton( "Time" ) ) m_timeDist.sortBy = TimeDistribution::SortBy::Time;
ImGui::SameLine();
ImGui::TextDisabled( "(%.2f%%)", v->second.time * fztime );
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::TextUnformatted( TimeToString( v->second.time / v->second.count ) ); if( ImGui::SmallButton( "MTPC" ) ) m_timeDist.sortBy = TimeDistribution::SortBy::Mtpc;
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::Separator();
switch( m_timeDist.sortBy )
{
case TimeDistribution::SortBy::Count:
pdqsort_branchless( vec.begin(), vec.end(), []( const auto& lhs, const auto& rhs ) { return lhs->second.count > rhs->second.count; } );
break;
case TimeDistribution::SortBy::Time:
pdqsort_branchless( vec.begin(), vec.end(), []( const auto& lhs, const auto& rhs ) { return lhs->second.time > rhs->second.time; } );
break;
case TimeDistribution::SortBy::Mtpc:
pdqsort_branchless( vec.begin(), vec.end(), []( const auto& lhs, const auto& rhs ) { return float( lhs->second.time ) / lhs->second.count > float( rhs->second.time ) / rhs->second.count; } );
break;
default:
assert( false );
break;
}
for( auto& v : vec )
{
ImGui::TextUnformatted( m_worker.GetZoneName( m_worker.GetSourceLocation( v->first ) ) );
ImGui::SameLine();
ImGui::TextDisabled( "(\xc3\x97%s)", RealToString( v->second.count, true ) );
ImGui::NextColumn();
ImGui::TextUnformatted( TimeToString( v->second.time ) );
ImGui::SameLine();
ImGui::TextDisabled( "(%.2f%%)", v->second.time * fztime );
ImGui::NextColumn();
ImGui::TextUnformatted( TimeToString( v->second.time / v->second.count ) );
ImGui::NextColumn();
}
ImGui::EndColumns();
} }
ImGui::EndColumns();
ImGui::TreePop(); ImGui::TreePop();
} }
} }

View File

@ -28,6 +28,7 @@ struct MemoryPage;
struct QueueItem; struct QueueItem;
class FileRead; class FileRead;
class TextEditor; class TextEditor;
struct ZoneTimeData;
class View class View
{ {
@ -208,6 +209,9 @@ private:
int64_t GetZoneSelfTime( const GpuEvent& zone ); int64_t GetZoneSelfTime( const GpuEvent& zone );
bool GetZoneRunningTime( const ContextSwitch* ctx, const ZoneEvent& ev, int64_t& time, uint64_t& cnt ); bool GetZoneRunningTime( const ContextSwitch* ctx, const ZoneEvent& ev, int64_t& time, uint64_t& cnt );
void CalcZoneTimeData( flat_hash_map<int16_t, ZoneTimeData, nohash<uint16_t>>& data, flat_hash_map<int16_t, ZoneTimeData, nohash<uint16_t>>::iterator zit, const ZoneEvent& zone );
void CalcZoneTimeData( const ContextSwitch* ctx, flat_hash_map<int16_t, ZoneTimeData, nohash<uint16_t>>& data, flat_hash_map<int16_t, ZoneTimeData, nohash<uint16_t>>::iterator zit, const ZoneEvent& zone );
void SetPlaybackFrame( uint32_t idx ); void SetPlaybackFrame( uint32_t idx );
flat_hash_map<const void*, VisData, nohash<const void*>> m_visData; flat_hash_map<const void*, VisData, nohash<const void*>> m_visData;
@ -565,6 +569,7 @@ private:
struct TimeDistribution { struct TimeDistribution {
enum class SortBy : int { Count, Time, Mtpc }; enum class SortBy : int { Count, Time, Mtpc };
SortBy sortBy = SortBy::Time; SortBy sortBy = SortBy::Time;
bool runningTime = false;
} m_timeDist; } m_timeDist;
}; };