The problem is this: I'm trying to calculate CPU frequency within a kernel-mode WDM driver based on the IOCTL sample skeleton but it doesn't want to compile if I try to use QueryPerformanceFrequency or QueryPerformanceCounter. I feel like maybe because its a kernel-mode driver it won't let me include Windows.h, which contains these methods - it forces me to use Ntddk.h instead.
Normally I'd use this function in a Win32 Console Application to calculate this information, but its inaccurate because it doesn't factor in Turbo Boost on Intel CPUs:
float GetCoreFrequency()
{
// __rdtsc: Returns the processor time stamp which records the number of clock cycles since the last reset.
// QueryPerformanceCounter: Returns a high resolution time stamp that can be used for time-interval measurements.
// Get the frequency which defines the step size of the QueryPerformanceCounter method.
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
// Get the number of cycles before we start.
ULONG cyclesBefore = __rdtsc();
// Get the start time.
LARGE_INTEGER startTime;
QueryPerformanceCounter(&startTime);
ULONG cyclesAfter;
LARGE_INTEGER endTime;
// Get the number of cycles over some arbitrary but short enough period of time.
do
{
cyclesAfter = __rdtsc();
QueryPerformanceCounter(&endTime);
} while ((endTime.QuadPart - startTime.QuadPart) / frequency.QuadPart < 1);
// Return the number of MHz.
return (cyclesAfter - cyclesBefore)*pow(10, -6) / ((endTime.QuadPart - startTime.QuadPart) / frequency.QuadPart);
}
The actual formula for CPU frequency on Intel chips is the maximum frequency multiplied by a ratio that can be obtained from two CPU registers in the chip itself (APERF and MPERF):
frequency = maximumFrequency * APERF / MPERF;
Which translates into this code:
frequency = maximumFrequency * __readmsr(232) / __readmsr(231);
I was hoping to be able to get maximumFrequency from QueryPerformanceFrequency, but since I can't get that to be included, how can I get the maximum frequency?