Счетчики аппаратного процессора неправильно сбрасываются

Я написал программу, которая считывает счетчики APERF/MPERF на чипе Intel (стр. 2 на http://www.intel.com/content/dam/doc/manual/64-ia-32-architectures-software-developer-vol-3b-part-2-manual.pdf).

Эти счетчики доступны для чтения / записи с помощью инструкций readmsr/writemsr, и в настоящее время я просто читаю их через регулярные промежутки времени с помощью драйвера устройства в Windows 7. Счетчики являются 64-битными и увеличиваются примерно с каждым тактом процессора, так что вы ' Я ожидал, что они переполнятся в течение очень долгого времени, но когда я читаю счетчики, их значение меняется, как если бы они сбрасывались другой программой.

Есть ли способ отследить, какая программа будет сбрасывать счетчики? Может ли что-то еще вызывать чтение неверных значений? Соответствующая сборка и соответствующие функции C, которые я использую, прилагаются ниже. 64-битный результат rdmsr сохраняется в eax:edx, поэтому, чтобы убедиться, что я не пропустил ни одного числа в регистрах r_x, я запускаю команду несколько раз, чтобы проверить их все.

C:

long long test1, test2, test3, test4;
test1 = TST1();
test2 = TST2();
test3 = TST3();
test4 = TST4();
status = RtlStringCbPrintfA(buffer, sizeof(buffer), "Value: %llu %llu %llu %llu\n", test1, test2, test3, test4);

Монтаж:

;;;;;;;;;;;;;;;;;;;
PUBLIC TST1 
TST1 proc
    mov ecx, 231 ; 0xE7
    rdmsr
    ret ; returns rax
TST1 endp

;;;;;;;;;;;;;;;;;;;
PUBLIC TST2 
TST2 proc
    mov ecx, 231 ; 0xE7
    rdmsr
    mov rax, rbx
    ret ; returns rax
TST2 endp

;;;;;;;;;;;;;;;;;;;
PUBLIC TST3 
TST3 proc
    mov ecx, 231 ; 0xE7
    rdmsr
    mov rax, rcx
    ret ; returns rax
TST3 endp

;;;;;;;;;;;;;;;;;;;
PUBLIC TST4 
TST4  proc
    mov ecx, 231 ; 0xE7
    rdmsr
    mov rax, rdx
    ret ; returns rax
TST4 endp

Результат, который выводится, выглядит примерно так, как показано ниже, но единственный регистр, который когда-либо изменяется, это регистр rax, и он не увеличивается монотонно (может прыгать):

Value: 312664 37 231 0
Value: 252576 37 231 0
Value: 1051857 37 231 0

2 ответа

Решение

Я не смог выяснить, что сбрасывало мои счетчики, но я смог определить частоту. Документы Intel утверждают, что когда один счетчик переполняется, другой счетчик также будет. Таким образом, несмотря на то, что счетчики постоянно сбрасываются, соотношение aperf и mperf все же отражает частоту процессора.

Похоже, что Windows 7 и Windows 8 считывают и сбрасывают записываемые счетчики APERF/MPERF на процессорах AMD. Итак, вы хотите получить доступ к счетчикам APERF/MPERF только для чтения в регистрах 0xc00000E7/E8.

Но есть новая проблема. На некоторых новейших процессорах AMD (процессоры семейства 0x16) эти регистры не всегда поддерживаются. Чтобы определить, поддерживаются ли эти регистры, вы должны прочитать бит EffFreqRO в CPUID Fn8000_0007_EDX. Как уже говорилось ранее, все это относится только к процессорам AMD.

Другие вопросы по тегам