KWSys 2025-06-05 (9953c411)

Code extracted from:

    https://gitlab.kitware.com/utils/kwsys.git

at commit 9953c411cdff6fbc02e6ddaa3fa0b954016cf365 (master).

Upstream Shortlog
-----------------

Clemens Wasser (1):
      430818af SystemInformation: Optimize CPU clock speed detection on Windows
This commit is contained in:
KWSys Upstream
2025-06-05 09:39:01 -04:00
committed by Brad King
parent bbe52677df
commit 0792fe05f6
2 changed files with 49 additions and 25 deletions
+1 -1
View File
@@ -774,7 +774,7 @@ if(KWSYS_C_SRCS OR KWSYS_CXX_SRCS)
if(KWSYS_USE_SystemInformation) if(KWSYS_USE_SystemInformation)
if(WIN32) if(WIN32)
target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} ws2_32) target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} ws2_32 PowrProf)
# link in dbghelp.dll for symbol lookup if MSVC 1800 or later # link in dbghelp.dll for symbol lookup if MSVC 1800 or later
# Note that the dbghelp runtime is part of MS Windows OS # Note that the dbghelp runtime is part of MS Windows OS
if(MSVC_VERSION AND NOT MSVC_VERSION VERSION_LESS 1800) if(MSVC_VERSION AND NOT MSVC_VERSION VERSION_LESS 1800)
+48 -24
View File
@@ -61,6 +61,7 @@
# if !defined(siginfo_t) # if !defined(siginfo_t)
using siginfo_t = int; using siginfo_t = int;
# endif # endif
# include <powerbase.h>
#else #else
# include <sys/types.h> # include <sys/types.h>
@@ -2489,40 +2490,63 @@ bool SystemInformationImplementation::RetrieveClassicalCPUCacheDetails()
#endif #endif
} }
#if defined(_WIN32)
typedef struct _PROCESSOR_POWER_INFORMATION
{
ULONG Number;
ULONG MaxMhz;
ULONG CurrentMhz;
ULONG MhzLimit;
ULONG MaxIdleState;
ULONG CurrentIdleState;
} PROCESSOR_POWER_INFORMATION, *PPROCESSOR_POWER_INFORMATION;
#endif
/** */ /** */
bool SystemInformationImplementation::RetrieveCPUClockSpeed() bool SystemInformationImplementation::RetrieveCPUClockSpeed()
{ {
bool retrieved = false; bool retrieved = false;
#if defined(_WIN32) #if defined(_WIN32)
unsigned int uiRepetitions = 1; PROCESSOR_POWER_INFORMATION powerInfo[64];
unsigned int uiMSecPerRepetition = 50; NTSTATUS status =
__int64 i64Total = 0; CallNtPowerInformation(ProcessorInformation, nullptr, 0, powerInfo,
__int64 i64Overhead = 0; sizeof(PROCESSOR_POWER_INFORMATION) * 64);
// Check if the TSC implementation works at all
if (this->Features.HasTSC &&
GetCyclesDifference(SystemInformationImplementation::Delay,
uiMSecPerRepetition) > 0) {
for (unsigned int nCounter = 0; nCounter < uiRepetitions; nCounter++) {
i64Total += GetCyclesDifference(SystemInformationImplementation::Delay,
uiMSecPerRepetition);
i64Overhead += GetCyclesDifference(
SystemInformationImplementation::DelayOverhead, uiMSecPerRepetition);
}
// Calculate the MHz speed.
i64Total -= i64Overhead;
i64Total /= uiRepetitions;
i64Total /= uiMSecPerRepetition;
i64Total /= 1000;
// Save the CPU speed.
this->CPUSpeedInMHz = (float)i64Total;
if (status == 0) {
this->CPUSpeedInMHz = (float)powerInfo[0].MaxMhz;
retrieved = true; retrieved = true;
} }
if (!retrieved) {
unsigned int uiRepetitions = 1;
unsigned int uiMSecPerRepetition = 50;
__int64 i64Total = 0;
__int64 i64Overhead = 0;
// Check if the TSC implementation works at all
if (this->Features.HasTSC &&
GetCyclesDifference(SystemInformationImplementation::Delay,
uiMSecPerRepetition) > 0) {
for (unsigned int nCounter = 0; nCounter < uiRepetitions; nCounter++) {
i64Total += GetCyclesDifference(SystemInformationImplementation::Delay,
uiMSecPerRepetition);
i64Overhead += GetCyclesDifference(
SystemInformationImplementation::DelayOverhead, uiMSecPerRepetition);
}
// Calculate the MHz speed.
i64Total -= i64Overhead;
i64Total /= uiRepetitions;
i64Total /= uiMSecPerRepetition;
i64Total /= 1000;
// Save the CPU speed.
this->CPUSpeedInMHz = (float)i64Total;
retrieved = true;
}
}
// If RDTSC is not supported, we fallback to trying to read this value // If RDTSC is not supported, we fallback to trying to read this value
// from the registry: // from the registry:
if (!retrieved) { if (!retrieved) {