2

我写了一个程序,它读取英特尔芯片上的 APERF/MPERF 计数器( http://www.intel.com/content/dam/doc/manual/64-ia-32-architectures-software-developer-vol上的第 2 页-3b-part-2-manual.pdf)。

这些计数器可通过 readmsr/writemsr 指令读取/写入,我目前只是通过 Windows 7 中的设备驱动程序定期读取它们。计数器是 64 位,并且随着每个处理器时钟大约递增,所以你预计它们会在很长一段时间内溢出,但是当我读取计数器时,它们的值会跳跃,就好像它们正在被另一个程序重置一样。

有什么方法可以追踪哪些程序会重置计数器?其他东西会导致读取不正确的值吗?我正在使用的相关程序集和相应的 C 函数附在下面。rdmsr 的 64 位结果保存到 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
4

2 回答 2

2

I was not able to figure out what was resetting my counters, but I was able to determine the frequency. The Intel docs state that when one counter overflows, the other counter also will. So even though the counters are constantly resetting, the ratio of aperf and mperf still does represent the processor's frequency.

于 2012-09-07T19:45:23.770 回答
0

It seems that Windows 7 and Windows 8 read and reset the writeable APERF/MPERF counters on AMD processors. So, you want to access the read-only APERF/MPERF counters at registers 0xc00000E7/E8.

But there is a new issue. On some of the latest AMD processors (Family 0x16 processors), those registers are not always supported. To determine if those registers are supported, you have to read the EffFreqRO bit in CPUID Fn8000_0007_EDX. As stated before, all this applies only to AMD processors.

于 2013-02-19T16:40:51.647 回答