使用valgrind测量缓存未命中

时间:2015-09-12 18:17:37

标签: c++ performance optimization cpu valgrind

我有一条关键路径,它在一个线程中执行,固定在一个核心上。

我有兴趣确定缓存未命中的位置。环顾四周后,valgrind的cachegrind工具似乎对我有所帮助。但是,我对此方案中工具的功能有一些疑问:

  1. 提供缓存未命中的位置有多详细?它输出变量名吗?
  2. 我可以只分析一个帖子吗?
  3. 是否可以分析代码的特定部分?
  4. 测量缓存未命中的所有功能,它们是否同样适用于TLB未命中?
  5. 我可以将cachegrind与我的发布/优化代码一起使用吗?
  6. 我理解valgrind使用虚拟机进行采样。这种方法有多准确?
  7. 问题1是最重要的。

    最值得赞赏的是命令行参数的任何帮助。

1 个答案:

答案 0 :(得分:0)

cachegrind不是读取CPU性能计数器的唯一方法。 Linux perf和英特尔VTune被广泛使用,并且存在各种其他前端。

我还没有使用过cachegrind,只有perf,但它的输出看起来很像使用perf计数器来记录缓存未命中和导致它们的指令。

  

提供缓存未命中的位置有多具体?它输出变量名吗?

通过机器代码地址,即特定指令。不同的前端将帮助你弄清楚加载或存储实际上在做什么,而不必读取asm并找出CPU在哪些寄存器中有哪些指针。 (他们可以记录计数器触发时使用的地址,以识别哪个缓存行。)

在编译器执行了一些严重的循环转换,或者在内联计算每个函数的函数后从循环中拉出一个常量表达式时,从指令地址到C ++源代码行的映射并不总是显而易见的呼叫。一般情况下,我建议分析优化代码。如果您只是在寻找缓存未命中,那么用于本地优化代码的额外堆栈将保留在寄存器中可能不会从缓存中驱逐许多行,并且在每次使用后将可变存储器加载/存储到内存中触摸已经很热的缓存行。尽管如此,如果您一直在查看分析输出,那么注意CPU时间热点作为流程的一部分仅在优化代码中有用。这是特别的。对于C ++来说是正确的,其中大量的模板代码需要内联和优化。

  

是否可以分析代码的特定部分?

是的,应该可以在perf计数器触发时检查调用链,并且只有在当前函数最终被您感兴趣的函数之一调用时才计算它。或者,在进入时启用计数感兴趣的功能。 IDK,如果cachegrind有一个很好的方法来做到这一点。

  

测量缓存未命中的所有功能是否同样适用于TLB未命中?

是的,有用于TLB未命中和页面遍历的硬件性能计数器,以及时钟周期,uops退役等。

英特尔Sandybridge拥有11个PMU计数器,因此您可以在一次运行中以完全准确的方式对11种不同的东西进行采样(即不需要分时计数器)。