2

問題は次のとおりです。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 を取得できることを望んでいましたが、それを含めることができないため、どうすれば最大周波数を取得できますか?

4

0 に答える 0