1

我正在尝试使用RDPMC指令来计算已停用的指令,并且正如英特尔软件开发人员手册第 3 卷附录 A(在性能监控部分)提到的那样:

• Instructions Retired — 事件选择 C0H,Umask 00H 此事件计算退出时的指令数。对于由多个微操作组成的指令,此事件计算指令的最后一个微操作的退出。带有 REP 前缀的指令算作一条指令(不是每次迭代)。多操作指令的最后一个微操作退出之前的故障不计算在内。

我使用此处的答案来启用 Linux Kernel-Mode 模块的性能计数器。

这里可以看到(描述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 C0H和和有什么区别?Umask 00H我想知道如何使用C0H00H
4

1 回答 1

1

我把 0 放到 RAX 并执行 RDPMC

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

如何在用户模式下计算特定进程的退休指令?

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

我经常用perf stat -etask-clock,context-switches,cpu-migrations,page-faults,cycles,branches,instructions,uops_issued.any,uops_executed.thread ./a.out. (例如,查看Can x86 的 MOV 中的输出真的是“免费的”吗?为什么我根本不能重现这个?)。

Perf 的instructions事件使用 Instructions Retired 计数器。(实际上,它使用该事件的固定计数器,而不是使用可编程计数器之一上的插槽。)

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

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

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


除了 Linux 中庞大的复杂perf子系统之外,已经有一些开源库用于编程性能计数器以设置从用户空间读取它们。请参阅Perf overcounting simple CPU-bound loop:神秘的内核工作?for libpfc,其中包括一个演示。

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

于 2018-07-15T11:00:46.510 回答