diff --git a/client/TracyProfiler.cpp b/client/TracyProfiler.cpp index 04a4a246..fd7aa189 100644 --- a/client/TracyProfiler.cpp +++ b/client/TracyProfiler.cpp @@ -80,6 +80,7 @@ #if defined _WIN32 || defined __CYGWIN__ # include extern "C" typedef LONG (WINAPI *t_RtlGetVersion)( PRTL_OSVERSIONINFOW ); +extern "C" typedef BOOL (WINAPI *t_GetLogicalProcessorInformationEx)( LOGICAL_PROCESSOR_RELATIONSHIP, PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX, PDWORD ); #else # include # include @@ -1070,6 +1071,7 @@ Profiler::Profiler() CalibrateTimer(); CalibrateDelay(); + ReportTopology(); #ifndef TRACY_NO_EXIT const char* noExitEnv = getenv( "TRACY_NO_EXIT" ); @@ -2446,6 +2448,85 @@ void Profiler::CalibrateDelay() #endif } +void Profiler::ReportTopology() +{ +#if defined _WIN32 || defined __CYGWIN__ +# ifdef UNICODE + t_GetLogicalProcessorInformationEx _GetLogicalProcessorInformationEx = (t_GetLogicalProcessorInformationEx)GetProcAddress( GetModuleHandle( L"kernel32" ), "GetLogicalProcessorInformationEx" ); +# else + t_GetLogicalProcessorInformationEx _GetLogicalProcessorInformationEx = (t_GetLogicalProcessorInformationEx)GetProcAddress( GetModuleHandle( "kernel32" ), "GetLogicalProcessorInformationEx" ); +# endif + + if( !_GetLogicalProcessorInformationEx ) return; + + DWORD psz = 0; + _GetLogicalProcessorInformationEx( RelationProcessorPackage, nullptr, &psz ); + auto packageInfo = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)tracy_malloc( psz ); + auto res = _GetLogicalProcessorInformationEx( RelationProcessorPackage, packageInfo, &psz ); + assert( res ); + + DWORD csz = 0; + _GetLogicalProcessorInformationEx( RelationProcessorCore, nullptr, &csz ); + auto coreInfo = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)tracy_malloc( csz ); + res = _GetLogicalProcessorInformationEx( RelationProcessorCore, coreInfo, &csz ); + assert( res ); + + SYSTEM_INFO sysinfo; + 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; iRelationship == RelationProcessorPackage ); + // FIXME account for GroupCount + auto mask = ptr->Processor.GroupMask[0].Mask; + int core = 0; + while( mask != 0 ) + { + if( mask & 1 ) cpuData[core].package = idx; + core++; + mask >>= 1; + } + ptr = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)(((char*)ptr) + ptr->Size); + idx++; + } + + idx = 0; + ptr = coreInfo; + while( (char*)ptr < ((char*)coreInfo) + csz ) + { + assert( ptr->Relationship == RelationProcessorCore ); + // FIXME account for GroupCount + auto mask = ptr->Processor.GroupMask[0].Mask; + int core = 0; + while( mask != 0 ) + { + if( mask & 1 ) cpuData[core].core = idx; + core++; + mask >>= 1; + } + ptr = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)(((char*)ptr) + ptr->Size); + idx++; + } + + tracy_free( cpuData ); + tracy_free( coreInfo ); + tracy_free( packageInfo ); +#endif +} + void Profiler::SendCallstack( int depth, const char* skipBefore ) { #ifdef TRACY_HAS_CALLSTACK diff --git a/client/TracyProfiler.hpp b/client/TracyProfiler.hpp index e3f39495..254e07fe 100644 --- a/client/TracyProfiler.hpp +++ b/client/TracyProfiler.hpp @@ -515,6 +515,7 @@ private: void CalibrateTimer(); void CalibrateDelay(); + void ReportTopology(); static tracy_force_inline void SendCallstackMemory( void* ptr ) {