我正在尝试使用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
仍然为零。 >
所以我的问题是:
Event select C0H
和Umask 00H
有什么区别,我想知道如何使用C0H
和00H
?答案 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
,其中包括一个演示。
如果您只想使用它,您真的不需要自己编写。