Transfer, display, save CPU topology data.

This commit is contained in:
Bartosz Taudul 2019-11-29 22:41:41 +01:00
parent 5148ecdc50
commit 712403e9fd
7 changed files with 156 additions and 9 deletions

View File

@ -2450,6 +2450,13 @@ void Profiler::CalibrateDelay()
void Profiler::ReportTopology() void Profiler::ReportTopology()
{ {
struct CpuData
{
uint32_t package;
uint32_t core;
uint32_t thread;
};
#if defined _WIN32 || defined __CYGWIN__ #if defined _WIN32 || defined __CYGWIN__
# ifdef UNICODE # ifdef UNICODE
t_GetLogicalProcessorInformationEx _GetLogicalProcessorInformationEx = (t_GetLogicalProcessorInformationEx)GetProcAddress( GetModuleHandle( L"kernel32" ), "GetLogicalProcessorInformationEx" ); t_GetLogicalProcessorInformationEx _GetLogicalProcessorInformationEx = (t_GetLogicalProcessorInformationEx)GetProcAddress( GetModuleHandle( L"kernel32" ), "GetLogicalProcessorInformationEx" );
@ -2475,13 +2482,6 @@ void Profiler::ReportTopology()
GetSystemInfo( &sysinfo ); GetSystemInfo( &sysinfo );
const uint32_t numcpus = sysinfo.dwNumberOfProcessors; const uint32_t numcpus = sysinfo.dwNumberOfProcessors;
struct CpuData
{
uint32_t package;
uint32_t core;
uint32_t thread;
};
auto cpuData = (CpuData*)tracy_malloc( sizeof( CpuData ) * numcpus ); auto cpuData = (CpuData*)tracy_malloc( sizeof( CpuData ) * numcpus );
for( uint32_t i=0; i<numcpus; i++ ) cpuData[i].thread = i; for( uint32_t i=0; i<numcpus; i++ ) cpuData[i].thread = i;
@ -2521,6 +2521,26 @@ void Profiler::ReportTopology()
idx++; idx++;
} }
Magic magic;
auto token = GetToken();
for( uint32_t i=0; i<numcpus; i++ )
{
auto& data = cpuData[i];
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin( magic );
MemWrite( &item->hdr.type, QueueType::CpuTopology );
MemWrite( &item->cpuTopology.package, data.package );
MemWrite( &item->cpuTopology.core, data.core );
MemWrite( &item->cpuTopology.thread, data.thread );
#ifdef TRACY_ON_DEMAND
DeferItem( *item );
#endif
tail.store( magic + 1, std::memory_order_release );
}
tracy_free( cpuData ); tracy_free( cpuData );
tracy_free( coreInfo ); tracy_free( coreInfo );
tracy_free( packageInfo ); tracy_free( packageInfo );

View File

@ -9,7 +9,7 @@ namespace tracy
constexpr unsigned Lz4CompressBound( unsigned isize ) { return isize + ( isize / 255 ) + 16; } constexpr unsigned Lz4CompressBound( unsigned isize ) { return isize + ( isize / 255 ) + 16; }
enum : uint32_t { ProtocolVersion = 24 }; enum : uint32_t { ProtocolVersion = 25 };
enum : uint32_t { BroadcastVersion = 0 }; enum : uint32_t { BroadcastVersion = 0 };
using lz4sz_t = uint32_t; using lz4sz_t = uint32_t;

View File

@ -68,6 +68,7 @@ enum class QueueType : uint8_t
TidToPid, TidToPid,
PlotConfig, PlotConfig,
ParamSetup, ParamSetup,
CpuTopology,
StringData, StringData,
ThreadName, ThreadName,
CustomStringData, CustomStringData,
@ -357,6 +358,13 @@ struct QueueParamSetup
int32_t val; int32_t val;
}; };
struct QueueCpuTopology
{
uint32_t package;
uint32_t core;
uint32_t thread;
};
struct QueueHeader struct QueueHeader
{ {
union union
@ -407,6 +415,7 @@ struct QueueItem
QueueTidToPid tidToPid; QueueTidToPid tidToPid;
QueuePlotConfig plotConfig; QueuePlotConfig plotConfig;
QueueParamSetup paramSetup; QueueParamSetup paramSetup;
QueueCpuTopology cpuTopology;
}; };
}; };
#pragma pack() #pragma pack()
@ -476,6 +485,7 @@ static const size_t QueueDataSize[] = {
sizeof( QueueHeader ) + sizeof( QueueTidToPid ), sizeof( QueueHeader ) + sizeof( QueueTidToPid ),
sizeof( QueueHeader ) + sizeof( QueuePlotConfig ), sizeof( QueueHeader ) + sizeof( QueuePlotConfig ),
sizeof( QueueHeader ) + sizeof( QueueParamSetup ), sizeof( QueueHeader ) + sizeof( QueueParamSetup ),
sizeof( QueueHeader ) + sizeof( QueueCpuTopology ),
// keep all QueueStringTransfer below // keep all QueueStringTransfer below
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // string data sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // string data
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // thread name sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // thread name

View File

@ -7,7 +7,7 @@ namespace Version
{ {
enum { Major = 0 }; enum { Major = 0 };
enum { Minor = 6 }; enum { Minor = 6 };
enum { Patch = 1 }; enum { Patch = 2 };
} }
} }

View File

@ -11390,6 +11390,59 @@ void View::DrawInfo()
ImGui::TreePop(); ImGui::TreePop();
} }
auto& topology = m_worker.GetCpuTopology();
if( !topology.empty() )
{
if( ImGui::TreeNode( "CPU topology" ) )
{
std::vector<decltype(topology.begin())> tsort;
tsort.reserve( topology.size() );
for( auto it = topology.begin(); it != topology.end(); ++it ) tsort.emplace_back( it );
std::sort( tsort.begin(), tsort.end(), [] ( const auto& l, const auto& r ) { return l->first < r->first; } );
char buf[128];
for( auto& package : tsort )
{
#ifdef TRACY_EXTENDED_FONT
sprintf( buf, ICON_FA_BOX " Package %i", package->first );
#else
sprintf( buf, "Package %i", package->first );
#endif
if( ImGui::TreeNodeEx( buf, ImGuiTreeNodeFlags_DefaultOpen ) )
{
std::vector<decltype(package->second.begin())> csort;
csort.reserve( package->second.size() );
for( auto it = package->second.begin(); it != package->second.end(); ++it ) csort.emplace_back( it );
std::sort( csort.begin(), csort.end(), [] ( const auto& l, const auto& r ) { return l->first < r->first; } );
for( auto& core : csort )
{
#ifdef TRACY_EXTENDED_FONT
sprintf( buf, ICON_FA_MICROCHIP " Core %i", core->first );
#else
sprintf( buf, "Core %i", core->first );
#endif
if( ImGui::TreeNodeEx( buf, ImGuiTreeNodeFlags_DefaultOpen ) )
{
ImGui::Indent();
for( auto& thread : core->second )
{
#ifdef TRACY_EXTENDED_FONT
sprintf( buf, ICON_FA_RANDOM " Thread %i", thread );
#else
sprintf( buf, "Thread %i", thread );
#endif
ImGui::TextUnformatted( buf );
}
ImGui::Unindent();
ImGui::TreePop();
}
}
ImGui::TreePop();
}
}
ImGui::TreePop();
}
}
ImGui::Separator(); ImGui::Separator();
TextFocused( "PID:", RealToString( m_worker.GetPid(), true ) ); TextFocused( "PID:", RealToString( m_worker.GetPid(), true ) );
TextFocused( "Host info:", m_worker.GetHostInfo().c_str() ); TextFocused( "Host info:", m_worker.GetHostInfo().c_str() );

View File

@ -343,6 +343,34 @@ Worker::Worker( FileRead& f, EventType::Type eventMask, bool bgTasks )
m_hostInfo = std::string( tmp, tmp+sz ); m_hostInfo = std::string( tmp, tmp+sz );
} }
if( fileVer >= FileVersion( 0, 6, 2 ) )
{
f.Read( sz );
m_data.cpuTopology.reserve( sz );
for( uint64_t i=0; i<sz; i++ )
{
uint32_t packageId;
uint64_t psz;
f.Read2( packageId, psz );
auto& package = *m_data.cpuTopology.emplace( packageId, flat_hash_map<uint32_t, std::vector<uint32_t>> {} ).first;
package.second.reserve( psz );
for( uint64_t j=0; j<psz; j++ )
{
uint32_t coreId;
uint64_t csz;
f.Read2( coreId, csz );
auto& core = *package.second.emplace( coreId, std::vector<uint32_t> {} ).first;
core.second.reserve( csz );
for( uint64_t k=0; k<csz; k++ )
{
uint32_t thread;
f.Read( thread );
core.second.emplace_back( thread );
}
}
}
}
f.Read( &m_data.crashEvent, sizeof( m_data.crashEvent ) ); f.Read( &m_data.crashEvent, sizeof( m_data.crashEvent ) );
f.Read( sz ); f.Read( sz );
@ -3238,6 +3266,9 @@ bool Worker::Process( const QueueItem& ev )
case QueueType::ParamSetup: case QueueType::ParamSetup:
ProcessParamSetup( ev.paramSetup ); ProcessParamSetup( ev.paramSetup );
break; break;
case QueueType::CpuTopology:
ProcessCpuTopology( ev.cpuTopology );
break;
default: default:
assert( false ); assert( false );
break; break;
@ -4584,6 +4615,15 @@ void Worker::ProcessParamSetup( const QueueParamSetup& ev )
m_params.push_back( Parameter { ev.idx, StringRef( StringRef::Ptr, ev.name ), bool( ev.isBool ), ev.val } ); m_params.push_back( Parameter { ev.idx, StringRef( StringRef::Ptr, ev.name ), bool( ev.isBool ), ev.val } );
} }
void Worker::ProcessCpuTopology( const QueueCpuTopology& ev )
{
auto package = m_data.cpuTopology.find( ev.package );
if( package == m_data.cpuTopology.end() ) package = m_data.cpuTopology.emplace( ev.package, flat_hash_map<uint32_t, std::vector<uint32_t>> {} ).first;
auto core = package->second.find( ev.core );
if( core == package->second.end() ) core = package->second.emplace( ev.core, std::vector<uint32_t> {} ).first;
core->second.emplace_back( ev.thread );
}
void Worker::MemAllocChanged( int64_t time ) void Worker::MemAllocChanged( int64_t time )
{ {
const auto val = (double)m_data.memory.usage; const auto val = (double)m_data.memory.usage;
@ -5171,6 +5211,25 @@ void Worker::Write( FileWrite& f )
f.Write( &sz, sizeof( sz ) ); f.Write( &sz, sizeof( sz ) );
f.Write( m_hostInfo.c_str(), sz ); f.Write( m_hostInfo.c_str(), sz );
sz = m_data.cpuTopology.size();
f.Write( &sz, sizeof( sz ) );
for( auto& package : m_data.cpuTopology )
{
sz = package.second.size();
f.Write( &package.first, sizeof( package.first ) );
f.Write( &sz, sizeof( sz ) );
for( auto& core : package.second )
{
sz = core.second.size();
f.Write( &core.first, sizeof( core.first ) );
f.Write( &sz, sizeof( sz ) );
for( auto& thread : core.second )
{
f.Write( &thread, sizeof( thread ) );
}
}
}
f.Write( &m_data.crashEvent, sizeof( m_data.crashEvent ) ); f.Write( &m_data.crashEvent, sizeof( m_data.crashEvent ) );
sz = m_data.frames.Data().size(); sz = m_data.frames.Data().size();

View File

@ -228,6 +228,8 @@ private:
Vector<ContextSwitchUsage> ctxUsage; Vector<ContextSwitchUsage> ctxUsage;
bool ctxUsageReady = false; bool ctxUsageReady = false;
#endif #endif
flat_hash_map<uint32_t, flat_hash_map<uint32_t, std::vector<uint32_t>>> cpuTopology;
}; };
struct MbpsBlock struct MbpsBlock
@ -422,6 +424,8 @@ public:
const Vector<Parameter>& GetParameters() const { return m_params; } const Vector<Parameter>& GetParameters() const { return m_params; }
void SetParameter( size_t paramIdx, int32_t val ); void SetParameter( size_t paramIdx, int32_t val );
const decltype(DataBlock::cpuTopology)& GetCpuTopology() const { return m_data.cpuTopology; }
private: private:
void Network(); void Network();
void Exec(); void Exec();
@ -483,6 +487,7 @@ private:
tracy_force_inline void ProcessThreadWakeup( const QueueThreadWakeup& ev ); tracy_force_inline void ProcessThreadWakeup( const QueueThreadWakeup& ev );
tracy_force_inline void ProcessTidToPid( const QueueTidToPid& ev ); tracy_force_inline void ProcessTidToPid( const QueueTidToPid& ev );
tracy_force_inline void ProcessParamSetup( const QueueParamSetup& ev ); tracy_force_inline void ProcessParamSetup( const QueueParamSetup& ev );
tracy_force_inline void ProcessCpuTopology( const QueueCpuTopology& ev );
tracy_force_inline ZoneEvent* AllocZoneEvent(); tracy_force_inline ZoneEvent* AllocZoneEvent();
tracy_force_inline void ProcessZoneBeginImpl( ZoneEvent* zone, const QueueZoneBegin& ev ); tracy_force_inline void ProcessZoneBeginImpl( ZoneEvent* zone, const QueueZoneBegin& ev );