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

View File

@@ -774,7 +774,7 @@ if(KWSYS_C_SRCS OR KWSYS_CXX_SRCS)
if(KWSYS_USE_SystemInformation)
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
# Note that the dbghelp runtime is part of MS Windows OS
if(MSVC_VERSION AND NOT MSVC_VERSION VERSION_LESS 1800)

View File

@@ -61,6 +61,7 @@
# if !defined(siginfo_t)
using siginfo_t = int;
# endif
# include <powerbase.h>
#else
# include <sys/types.h>
@@ -2489,40 +2490,63 @@ bool SystemInformationImplementation::RetrieveClassicalCPUCacheDetails()
#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 retrieved = false;
#if defined(_WIN32)
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;
PROCESSOR_POWER_INFORMATION powerInfo[64];
NTSTATUS status =
CallNtPowerInformation(ProcessorInformation, nullptr, 0, powerInfo,
sizeof(PROCESSOR_POWER_INFORMATION) * 64);
if (status == 0) {
this->CPUSpeedInMHz = (float)powerInfo[0].MaxMhz;
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
// from the registry:
if (!retrieved) {