如何使用英特尔性能计数器监视器监视特定进程的执行(即分支跟踪存储中的分支(,同时过滤掉其他进程的信息?
您应该知道 BTS(分支跟踪存储(和性能监视事件/计数器(在 CPU 内部,其 PMU 块(是非常不同的东西。
分支跟踪存储是 CPU 的功能,当它确实将每个获取的分支(eip 对 - 分支指令的第一个和分支目标的第二个;每个对还添加一个标志字(记录在内存的特殊区域中时。它的结果非常像单步执行代码块(基本块(的顺序。这就像在编译器的帮助下进行代码覆盖一样,当编译器检测每个分支时。
BTS只是MSR_DEBUGCTLA MSR中的一点点(它是Intel x86寄存器(;我几乎可以肯定这个寄存器是特定于线程的(就像在 Linux 中一样(,所以你不需要钩住调度程序。有一些在窗口中使用此 MSR 的示例;但使用了不同的位。另外,不要忘记正确设置DS_AREA。因此,如果您真的想要 BTS,请获取一份英特尔 Arch 手册(第 3b 卷,"调试和性能监控"部分,"19.7.8 分支跟踪存储 (BTS("部分(并手动对 BTS 进行编程。最困难的部分是处理 DS 区域溢出(您需要自定义中断处理程序(。
如果你想知道的不是执行代码的痕迹,而是程序的统计数据(执行了多少指令;分支预测得有多好;这里有多少间接分支......(,你应该使用性能监控事件,也就是"基于事件的精确采样"(PEBS(。英特尔 Vtune 就是这样做的;应该有一些其他工具,甚至是您链接的英特尔 PBS。唯一的问题(使用免费工具有点困难(是找到您想要的事件名称。基于指令执行的事件始终绑定到某个线程。
基于事件的采样是什么意思:您可以设置一些限制,例如某些事件的 1000,例如。BR_INST_EXEC。COND ("有条件的数量执行的近分支指令"(或BR_INST_EXEC。DIRECT("所有无条件的近分支指令,不包括呼叫和间接分支"(,一次最多 2-4 个事件。然后CPU将计算与此事件相对应的每个情况。当出现第 1000 种情况时,将为安装弹性公网IP生成事件(中断(。通过采样,可以轻松获得代码行为的详细统计信息。如果您将限制设置为非常低的值,并且不对 eip 的事件求和,您将获得跟踪;)
使用 PEBS,您可以知道您的代码对 CPU 有多糟糕、预测错误的分支位于何处、哪些指令等待来自缓存的数据等。有100多个事件(第3b卷附录A(。
PS 有一些防弹少年团/赢的代码:http://blog.csdn.net/quincy_hu/article/details/4053163
PPS 对 PMU 编程的概述较短,包括 PEBS 和 BTS。 software.intel.com/file/30320 这是给尼哈勒姆的,但即使是桑迪也可以是实际的。
我们被迫构建自己的检测探查器,直接读取 MSR 以获取此信息。性能计数器监视器的源代码演示如何生成读取它们的内核驱动程序。
以前我们使用 VTune,但是在我们的应用程序上运行时它会崩溃。 (当我们在 Linux 版本上尝试 OProfile 时,它实际上使整个内核崩溃并迫使我们重新启动机器,这很有趣。
查看 https://github.com/andikleen/pmu-tools/blob/master/toplev.py
例子:toplev.py -L2 程序在程序运行时以级别 2 测量整个系统