【问题标题】:Hardware Processor Counters Incorrectly Resetting硬件处理器计数器重置不正确
【发布时间】:2012-07-09 01:54:19
【问题描述】:

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

这些计数器可通过 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

【问题讨论】:

  • 您是在特定 CPU 上还是在当前的 CPU 上读取这些寄存器?
  • 这是一个很好的观点,我在任何最新的核心上运行代码。 (我使用 i5 和 i7 机器作为测试机器)。另一方面,我希望 rdx 寄存器最终在其中一个 CPU 上从 0 递增,而不是始终保持为零。
  • 另外,是否可以只运行一个特定内核的驱动程序?
  • 您可以使用KeSetSystemAffinityThreadEx()将当前线程移动到特定的CPU。

标签: c assembly x86 msr


【解决方案1】:

我无法弄清楚是什么在重置我的计数器,但我能够确定频率。英特尔文档指出,当一个计数器溢出时,另一个计数器也会溢出。因此,即使计数器不断重置,aperf 和 mperf 的比率仍然代表处理器的频率。

【讨论】:

    【解决方案2】:

    Windows 7 和 Windows 8 似乎读取和重置 AMD 处理器上的可写 APERF/MPERF 计数器。因此,您希望访问寄存器 0x​​c00000E7/E8 处的只读 APERF/MPERF 计数器。

    但是有一个新问题。在一些最新的 AMD 处理器(0x16 系列处理器)上,这些寄存器并不总是受支持。要确定是否支持这些寄存器,您必须读取 CPUID Fn8000_0007_EDX 中的 EffFreqRO 位。如前所述,所有这些仅适用于 AMD 处理器。

    【讨论】:

      猜你喜欢
      • 2016-05-03
      • 1970-01-01
      • 1970-01-01
      • 2017-05-18
      • 1970-01-01
      • 2012-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多