【问题标题】:How can I perform a low-level analysis of a performance degradation?如何对性能下降执行低级别分析?
【发布时间】:2015-11-30 20:26:55
【问题描述】:

例如,我有一个大型线性函数(1 个基本块,~1000 条指令) 这被调用了很多次。在摆弄了一些编译器选项之后,我得到了 Cortex-A57 的性能意外下降了 10%。估计是由于 有点不同的指令调度。我想调查问题 更深入地找出哪些指令组合导致不必要的流水线 摊位。但我不知道我怎么能做到这一点。我想,我需要一个非常详细的 执行跟踪以了解发生了什么,尽管我不确定是否是 有可能得到这样的踪迹。

所以,问题是:我可以使用什么工具来调查这种低级别 性能问题?如何确定阻止 CPU 执行的原因 每个周期的最大指令数?

PS 我最感兴趣的是 Cortex-A57 内核,但我会很感激有用 有关任何其他核心甚至不同架构的信息。

PPS 函数访问内存,但预计几乎所有内存 访问命中缓存。该假设由perf stat -e r42,r43 确认 (L1D_CACHE_REFILL_LDL1D_CACHE_REFILL_ST 事件)。

【问题讨论】:

  • 您几乎已经回答了自己的问题 - 使用 perf 研究 microarchitectural PMU events 确实是最有用的事情之一。了解 A57,这可能是代码对齐方式的细微变化,使分支预测器的条件不理想。
  • PMU 有时可以说出问题所在,但 AFAIK 无法说出问题所在。此外,A57 的 PMU 事件列表比 A53 短得多。我希望 A57 支持“可归因的性能影响事件”,但似乎不支持。
  • 您只修改了编译器选项吗?或者您是否对代码进行了任何更改?
  • 无代码更改。事实上,在这两种情况下,所提到的功能都由相同数量的相同指令组成。唯一的区别是指令顺序、使用的寄存器和地址。

标签: performance arm cpu cpu-usage cpu-architecture


【解决方案1】:

工具:我最熟悉英特尔编译器和工具,但请注意,ARM 生态系统中有几个类似的工具。以下是我推荐的一些技巧。

使用您的编译器 它有许多选项可以让您很好地了解正在发生的事情。

  • 在编译原始代码时禁用任何优化(编译器选项)。这将告诉您问题是否与代码生成优化有关。
  • 执行 ASM 转储之前和之后,并进行比较。您可能会发现您已经知道的代码差异是可疑的。
  • 确保您没有包含任何调试信息。调试会插入检查点和其他可能影响代码性能的东西。这些代码位也会通过管道改变代码的执行
  • 一次更改一个编译器选项,以确定问题是否与数据或代码对齐强​​制等有关。我相信您已经这样做了,但为了完整性,我提一下。
  • 启用任何可以转储到日志文件的编译器性能监控选项。在编译器日志文件中可以找到很多有用的信息。另一方面,它们还包含只能由生活在更高层次的人(即编译器编写者)解释的信息。

使用转储 PMU 事件的工具

  • 我在那里看到了很多。很抱歉没有提供参考,但您可以进行简单的搜索 "tool arm pmu events"。这些可以非常复杂和强大,例如Intel VTune,或者非常基本但仍然非常强大,例如x86 的命令行 SEP。
  • 查看可供您使用的性能事件(PMU 事件)并找出您要监控的事件。您可以从 ARM Cortex-A57 处理器技术参考(第 11 章,性能监控单元)中获取这些事件。

使用 PMU 转储 SDK

  • 使用具有获取 ARM PMU 事件功能的 SDK。这些 SDK 为您提供用于选择和获取 PMU 事件的 API,为您提供非常精确的控制。插入此监控代码可能会影响代码的执行,因此请注意其位置。同样,您可以通过简单的搜索找到大量此类 SDK。

研究管道调试(如果您真的喜欢这种类型的东西)

  • 找到对管道的良好架构描述,包括保留站、ALU 数量等。
  • 找到一个很好的参考资料,了解如何弄清楚管道中发生了什么。 Here's an example for x86. ARM 是一个不同的野兽,但 x86 文章将为您提供需要分析的基础知识(以及更多内容),以及您可以利用发现的内容做什么。

祝你好运。管道调试可能很有趣但很耗时。

【讨论】:

  • 谢谢!这是一个很好的概述。
猜你喜欢
  • 1970-01-01
  • 2017-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-08
  • 2020-06-02
  • 2014-10-20
  • 1970-01-01
相关资源
最近更新 更多