mirror of
https://github.com/wolfpld/tracy.git
synced 2024-11-30 01:04:36 +00:00
Transfer, display, save CPU topology data.
This commit is contained in:
parent
5148ecdc50
commit
712403e9fd
@ -2450,6 +2450,13 @@ void Profiler::CalibrateDelay()
|
||||
|
||||
void Profiler::ReportTopology()
|
||||
{
|
||||
struct CpuData
|
||||
{
|
||||
uint32_t package;
|
||||
uint32_t core;
|
||||
uint32_t thread;
|
||||
};
|
||||
|
||||
#if defined _WIN32 || defined __CYGWIN__
|
||||
# ifdef UNICODE
|
||||
t_GetLogicalProcessorInformationEx _GetLogicalProcessorInformationEx = (t_GetLogicalProcessorInformationEx)GetProcAddress( GetModuleHandle( L"kernel32" ), "GetLogicalProcessorInformationEx" );
|
||||
@ -2475,13 +2482,6 @@ void Profiler::ReportTopology()
|
||||
GetSystemInfo( &sysinfo );
|
||||
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 );
|
||||
for( uint32_t i=0; i<numcpus; i++ ) cpuData[i].thread = i;
|
||||
|
||||
@ -2521,6 +2521,26 @@ void Profiler::ReportTopology()
|
||||
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( coreInfo );
|
||||
tracy_free( packageInfo );
|
||||
|
@ -9,7 +9,7 @@ namespace tracy
|
||||
|
||||
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 };
|
||||
|
||||
using lz4sz_t = uint32_t;
|
||||
|
@ -68,6 +68,7 @@ enum class QueueType : uint8_t
|
||||
TidToPid,
|
||||
PlotConfig,
|
||||
ParamSetup,
|
||||
CpuTopology,
|
||||
StringData,
|
||||
ThreadName,
|
||||
CustomStringData,
|
||||
@ -357,6 +358,13 @@ struct QueueParamSetup
|
||||
int32_t val;
|
||||
};
|
||||
|
||||
struct QueueCpuTopology
|
||||
{
|
||||
uint32_t package;
|
||||
uint32_t core;
|
||||
uint32_t thread;
|
||||
};
|
||||
|
||||
struct QueueHeader
|
||||
{
|
||||
union
|
||||
@ -407,6 +415,7 @@ struct QueueItem
|
||||
QueueTidToPid tidToPid;
|
||||
QueuePlotConfig plotConfig;
|
||||
QueueParamSetup paramSetup;
|
||||
QueueCpuTopology cpuTopology;
|
||||
};
|
||||
};
|
||||
#pragma pack()
|
||||
@ -476,6 +485,7 @@ static const size_t QueueDataSize[] = {
|
||||
sizeof( QueueHeader ) + sizeof( QueueTidToPid ),
|
||||
sizeof( QueueHeader ) + sizeof( QueuePlotConfig ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueParamSetup ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueCpuTopology ),
|
||||
// keep all QueueStringTransfer below
|
||||
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // string data
|
||||
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // thread name
|
||||
|
@ -7,7 +7,7 @@ namespace Version
|
||||
{
|
||||
enum { Major = 0 };
|
||||
enum { Minor = 6 };
|
||||
enum { Patch = 1 };
|
||||
enum { Patch = 2 };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11390,6 +11390,59 @@ void View::DrawInfo()
|
||||
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();
|
||||
TextFocused( "PID:", RealToString( m_worker.GetPid(), true ) );
|
||||
TextFocused( "Host info:", m_worker.GetHostInfo().c_str() );
|
||||
|
@ -343,6 +343,34 @@ Worker::Worker( FileRead& f, EventType::Type eventMask, bool bgTasks )
|
||||
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( sz );
|
||||
@ -3238,6 +3266,9 @@ bool Worker::Process( const QueueItem& ev )
|
||||
case QueueType::ParamSetup:
|
||||
ProcessParamSetup( ev.paramSetup );
|
||||
break;
|
||||
case QueueType::CpuTopology:
|
||||
ProcessCpuTopology( ev.cpuTopology );
|
||||
break;
|
||||
default:
|
||||
assert( false );
|
||||
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 } );
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
const auto val = (double)m_data.memory.usage;
|
||||
@ -5171,6 +5211,25 @@ void Worker::Write( FileWrite& f )
|
||||
f.Write( &sz, sizeof( 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 ) );
|
||||
|
||||
sz = m_data.frames.Data().size();
|
||||
|
@ -228,6 +228,8 @@ private:
|
||||
Vector<ContextSwitchUsage> ctxUsage;
|
||||
bool ctxUsageReady = false;
|
||||
#endif
|
||||
|
||||
flat_hash_map<uint32_t, flat_hash_map<uint32_t, std::vector<uint32_t>>> cpuTopology;
|
||||
};
|
||||
|
||||
struct MbpsBlock
|
||||
@ -422,6 +424,8 @@ public:
|
||||
const Vector<Parameter>& GetParameters() const { return m_params; }
|
||||
void SetParameter( size_t paramIdx, int32_t val );
|
||||
|
||||
const decltype(DataBlock::cpuTopology)& GetCpuTopology() const { return m_data.cpuTopology; }
|
||||
|
||||
private:
|
||||
void Network();
|
||||
void Exec();
|
||||
@ -483,6 +487,7 @@ private:
|
||||
tracy_force_inline void ProcessThreadWakeup( const QueueThreadWakeup& ev );
|
||||
tracy_force_inline void ProcessTidToPid( const QueueTidToPid& 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 void ProcessZoneBeginImpl( ZoneEvent* zone, const QueueZoneBegin& ev );
|
||||
|
Loading…
Reference in New Issue
Block a user