如何在进程中配置和采样英特尔性能计数器

时间:2016-08-18 15:06:39

标签: linux x86 benchmarking perf intel-pmu

简而言之,我正在尝试在用户区基准测试过程中实现以下内容(伪代码,假设x86_64和UNIX系统):

results[] = ...
for (iteration = 0; iteration < num_iterations; iteration++) {
    pctr_start = sample_pctr();
    the_benchmark();
    pctr_stop = sample_pctr();
    results[iteration] = pctr_stop - pctr_start;
}

FWIW,我正在考虑使用的性能计数器是CPU_CLK_UNHALTED.THREAD_ALL,以读取与时钟频率变化无关的核心周期数(在earlier question我一直计划使用TSC寄存器这,但唉,这不是这个注册表所测量的内容。)

我的初衷是使用内联汇编程序首先使用WRMSR配置计数器,然后使用RDPMC内的sample_pctr()来读取计数器。

我偶然发现了第一道障碍,因为编写MSR需要内核权限。事实上你似乎可以从用户空间读取计数器(如果配置正确),但是配置计数器(带有MSR)的行为需要由内核。

有没有人知道要求内核从用户空间配置性能计数器的轻量级方法,以便我可以在我的基准测试工具中使用RDPMC

我已经研究过/想过:

  • 适用于Linux的Perf工具。似乎是为了在整个过程的生命周期内进行采样,而不是作为特定点(在每次迭代之前和之后)的过程中进行采样。
  • 直接使用perf系统调用(即perf_event_open)。看起来计数器值只会定期更新(使用采样率)或计数器超过阈值后。在我问的那一刻,我正好需要计数器值。这就是RDPMC看起来如此吸引人的原因。我想经常采样会使性能计数器读数产生偏差。
  • PAPI以perf为基础,因此可能会继承上述问题。
  • 编写内核模块 - 太费力,太容易出错。

理想情况下,我想要一个适用于OpenBSD和Linux的解决方案,但不知何故,我认为这是一个很高的订单。也许现在只适用于Linux。

非常感谢任何帮助。感谢。

编辑:我刚刚找到了Linux msr device node,这可能已经足够了。我会留下这个问题以防出现更好的答案。

1 个答案:

答案 0 :(得分:0)

对于Linux来说,似乎最好的方法是使用the msr device node

您只需打开一个设备节点,寻找所需的MSR地址,然后读取或写入8个字节。

OpenBSD更难,因为(在撰写本文时)MSR没有用户空间代理。因此,您需要编写内核模块或手动实现sysctl。