mirror of
https://github.com/wolfpld/tracy.git
synced 2024-11-26 16:04:34 +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()
|
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 );
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -7,7 +7,7 @@ namespace Version
|
|||||||
{
|
{
|
||||||
enum { Major = 0 };
|
enum { Major = 0 };
|
||||||
enum { Minor = 6 };
|
enum { Minor = 6 };
|
||||||
enum { Patch = 1 };
|
enum { Patch = 2 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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() );
|
||||||
|
@ -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();
|
||||||
|
@ -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 );
|
||||||
|
Loading…
Reference in New Issue
Block a user