【发布时间】:2016-12-25 14:08:04
【问题描述】:
简而言之,我试图在用户态基准测试过程中实现以下目标(伪代码,假设 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 配置一个计数器,然后在sample_pctr() 中使用RDPMC 读取计数器。
我遇到了第一个障碍,因为编写 MSR 需要内核权限。实际上,您似乎可以从用户空间读取计数器(如果配置正确),但是配置计数器(使用 MSR)的行为需要由内核。
有谁知道一种轻量级的方法来要求内核从用户空间配置性能计数器,以便我可以在我的基准测试工具中使用RDPMC?
我研究过/思考过的东西:
- Linux 的性能工具。似乎已准备好在流程的整个生命周期内进行采样,而不是在流程中作为特定点(每次迭代之前和之后)进行采样。
- 直接使用 perf 系统调用(即
perf_event_open)。看起来计数器值只会定期更新(使用采样率)或在计数器超过阈值后更新。在我问的那一刻,我正好需要计数器值。这就是为什么RDPMC看起来如此吸引人的原因。我想频繁采样本身会扭曲性能计数器读数。 - PAPI 基于 perf,因此可能继承了上述问题。
- 编写内核模块 -- 太费力,太容易出错。
理想情况下,我想要一个适用于 OpenBSD 和 Linux 的解决方案,但不知何故,我认为这是一项艰巨的任务。也许现在只适用于 Linux。
非常感谢任何帮助。谢谢。
编辑:我刚刚找到Linux msr device node,这可能就足够了。如果有更好的答案出现,我会留下问题。
【问题讨论】:
-
您可以从用户空间对计数器进行编程,但您可能希望将线程固定到内核,因为 PMC 不会在上下文切换时保存/恢复。请参阅agner.org/optimize 了解已编写的 Linux 内核模块,该模块可让您访问 PMC,还请参阅stackoverflow.com/questions/38848914/… 了解有关使用它们的一些讨论。
-
谢谢!您能否评论一下 perf 的采样模型会施加多少开销?这些 perf 例程本身会包含在我的任何读数中吗?
-
不知道;我只是使用
perf,通过将我想要进行微基准测试的循环放入它自己的独立程序并使用perf stat。
标签: linux x86 benchmarking perf intel-pmu