問題は次のとおりです。IOCTL サンプル スケルトンに基づいて、カーネル モードの WDM ドライバー内で CPU 周波数を計算しようとしていますが、QueryPerformanceFrequency または QueryPerformanceCounter を使用しようとするとコンパイルされません。おそらく、カーネルモードドライバーであるため、これらのメソッドを含む Windows.h を含めることができないため、代わりに Ntddk.h を使用する必要があるように感じます。
通常、Win32 コンソール アプリケーションでこの関数を使用してこの情報を計算しますが、Intel CPU のターボ ブーストを考慮していないため、不正確です。
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);
}
Intel チップの CPU 周波数の実際の式は、最大周波数にチップ自体の 2 つの CPU レジスタ (APERF と MPERF) から取得できる比率を掛けたものです。
frequency = maximumFrequency * APERF / MPERF;
これは次のコードに変換されます。
frequency = maximumFrequency * __readmsr(232) / __readmsr(231);
QueryPerformanceFrequency から maximumFrequency を取得できることを望んでいましたが、それを含めることができないため、どうすれば最大周波数を取得できますか?