特定处理器上的性能监视计数器(RDPMC)

时间:2018-07-15 08:11:28

标签: assembly x86 intel performancecounter

我正在尝试使用RDPMC指令对已退休的指令进行计数,并且正如《英特尔软件开发人员手册》第3卷的附录A(“性能监控”部分)所述:

  

•退休说明—事件选择C0H,Umask 00H   此事件计算退休时的指令数。对于包含多个微操作的说明,   该事件计算了指令的最后一个微操作的退出。带有REP前缀的指令计数   作为一条指令(不是每次迭代)。多操作指令的最后一个微操作退出之前的故障   不计算在内。

我使用了here的答案来启用Linux内核模式模块的性能计数器。

here(对RDPMC的描述中可以看到):

  

将ECX寄存器中指定的40位性能监视计数器的内容加载到寄存器EDX:EAX中。 EDX寄存器装入计数器的高8位,而EAX寄存器装入计数器的低32位。 Pentium®Pro处理器有两个性能监视计数器(0和1),分别通过在ECX寄存器中放置0000H或0001H来指定。

此后,我将0放置到RAX上并执行RDPMC(以用户模式),但是在RDPMC执行了多次之后,EDX:EAX仍然为零。 >

所以我的问题是:

  1. 如何在用户模式下计算特定过程中的淘汰说明?
  2. Event select C0HUmask 00H有什么区别,我想知道如何使用C0H00H

1 个答案:

答案 0 :(得分:1)

  

我将0放入RAX并执行RDPMC

选择器进入ECX,而不是EAX。

  

如何在用户模式下计算特定过程中的退役指令?

如果您希望Linux虚拟化上下文切换和CPU迁移上的性能计数器,以按进程而不是按CPU跟踪事物,请使用perf stat ./a.out。或者,如果您正在手动编程性能计数器,请确保将过程固定到核心。

我经常用perf stat -etask-clock,context-switches,cpu-migrations,page-faults,cycles,branches,instructions,uops_issued.any,uops_executed.thread ./a.out来描述内容。 (例如,查看Can x86's MOV really be "free"? Why can't I reproduce this at all?中的输出)。

Perf的instructions事件使用“已退休指令”计数器。 (实际上,该事件使用固定计数器,而不是在其中一个可编程计数器上占用插槽。)

非通用的特定于uarch的事件的符号名称,例如uops_issued.any过去仅在ocperf.py包装脚本中可用,但是Arch Linux上的perf 4.15.gd8a5b8直接支持它们。我认为此更改是最近的。

  

事件选择C0H和Umask 00H有什么区别,我想知道如何使用C0H和00H?

您必须使用正确的事件和单位掩码对可编程计数器进行编程。 umask通常选择一些相关事物的变体。有关每个事件的umask值在Haswell上执行的操作的列表,请参见http://oprofile.sourceforge.net/docs/intel-haswell-events.php


除了Linux中的大型复杂perf子系统外,已经有一些开源库,用于对perf计数器进行编程以设置为从用户空间读取它们。请参见Perf overcounting simple CPU-bound loop: mysterious kernel work?中的libpfc,其中包括一个演示。

如果您只想使用它,您真的不需要自己编写。