【问题标题】:How can a GCC instrumented executable be faster than the non-instrumented?GCC 检测的可执行文件如何比非检测的更快?
【发布时间】:2013-01-31 22:16:17
【问题描述】:

我正在 SPEC 基准测试中对 GCC Profile-Guided Optimization 的开销进行基准测试。我在一些基准测试中得到了一些奇怪的结果。事实上,我的两个基准测试在检测时运行得更快。

正常的可执行文件编译时使用:-g -O2 -march=native

检测的可执行文件使用以下命令编译:-g -O2 -march=native -fprofile-generate -fno-vpt

我正在使用 GCC 4.7(准确地说是 Google 分支)。运行基准测试的计算机具有 Intel(R) Xeon(R) CPU E5-2650 0 @ 2.00GHz。

bwaves 是 Fortran 基准和 libquantum

结果如下:

bwaves-normal: 712.14 
bwaves-instrumented: 697.22 
  => ~2% faster 

libquantum-normal: 463.88
libquantum-instrumented: 449.05
  => ~3.2% faster

我多次运行基准测试,认为这可能是 ma 机器上的问题,但每次我都确认它们。

我会理解某些程序的开销很小,但我看不出有任何改进的理由。

所以我的问题是:GCC 检测的可执行文件如何比优化的普通可执行文件更快?

谢谢

【问题讨论】:

  • 我认为这不能在我们可以构建和试验的小测试用例上重现?
  • 很遗憾,我不能分享 SPEC 的源代码/可执行文件,因为它是商业的 :(
  • 可能你的性能是由缓存效果决定的。添加代码将更改哪些缓存行被命中;如果您在没有仪器的情况下受到严重干扰,您可以看到这一点。有什么理由相信您的程序会触及大量缓存?
  • 我不太清楚,但我知道某些基准测试非常占用内存。也许这就是这种情况。事实上,它可以改变记忆效应。
  • 关于@IraBaxter 建议的缓存效果,您在该代码中是否有预取指令?添加代码通常不会消除缓存问题(缓存大小、内存 b/w 和延迟不会神奇地改变,额外的代码可能会“免费”运行)但可能确实会给缓存带来更大的压力。但是,预取是另一回事,如果没有足够早地完成(或使用错误的访问提示),它实际上可能比不做要慢。在这种情况下,“一些更多的代码”会稍微延迟执行因此可以想象真的让它运行​​得更快。

标签: optimization gcc compiler-construction instrumentation pgo


【解决方案1】:

我能想到两种可能性,都与缓存有关。

一个是计数器增量“温暖”了一些重要的缓存行。 其次是添加检测所需的结构会导致一些频繁使用的数组或变量落入不同的缓存行。

另一个问题是,在 for 循环中不必每次都进行分析/增加计数器 - 如果循环中没有“中断”或“返回”,则允许编译器优化增量循环。

【讨论】:

    【解决方案2】:

    查看 GCC 文档,-fprofile-generate 似乎确实激活了一些特定的代码转换以使分析更容易/更便宜,因此检测代码并不是真正的原始代码 + 检测。这些更改可以使代码更快,添加代码也会使缓存行为发生变化。没有看到有问题的代码就很难知道。并且从我(很久以前)与LCC 混在一起的情况来看,当智能分析完成时,它涉及的代码更改非常少。

    只是好奇:与上述相比,考虑配置文件编译的代码如何?

    【讨论】:

    • 对于 bwaves,PGO 编译的速度快了 3.5%,对于 libquantum,它快了将近 15%。
    猜你喜欢
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-22
    • 2015-08-25
    相关资源
    最近更新 更多