【问题标题】:Are there any performance test results for usage of likely/unlikely hints?是否有任何使用可能/不太可能提示的性能测试结果?
【发布时间】:2011-11-28 07:25:06
【问题描述】:

gcc 功能 likely/unlikely hints 帮助编译器生成具有更好分支预测的机器代码。

是否有关于正确使用或未使用这些提示如何影响某些真实系统上真实代码性能的数据?

【问题讨论】:

  • 我认为不会有强大的指标,因为它是一个微优化,它取决于提示正确与否的频率、@ 中二进制代码的大小987654322@ 块,甚至可能是月相
  • 基本上这映射到 CPU 的分支预测器;二进制代码的大小无关紧要。
  • 对于性能我没有基准,但我可以说由 gcc 生成的带有此类提示的汇编程序要清晰得多。
  • @Jens Gustedt:AFAIK 提示只会导致交换分支。代码如何变得更简洁?
  • 正是如此。跟随主分支要容易得多,因为这是连续的,然后,被认为“不喜欢”的部分被交换到后面,看不见。

标签: c++ c optimization gcc micro-optimization


【解决方案1】:

问题有所不同,但this question 上的Peter Cordes's answer 给出了明确的提示;)。现代 CPU 忽略静态提示,使用动态分支预测。

【讨论】:

  • 看起来它不仅仅是关于提示 - hyhtech.blogspot.com/2008/08/… - 它会影响哪个分支代码放置在 CPU 第一次执行代码时默认的路径上并且不知道该代码如何行为还没有。
【解决方案2】:

我不知道对这些特定提示的任何彻底分析。在任何情况下,这将是极其特定于 CPU 的。通常,如果您确定可能性(例如 > 90%),那么添加此类注释可能是值得的,尽管改进会因特定用例而有很大差异。

现代台式机 CPU 往往具有非常好的分支预测。如果您的代码无论如何都在热路径上,动态分支预测器将很快发现分支本身是有偏差的。此类提示主要用于帮助静态预测器在没有动态分支信息可用时启动。

在 x86 上,静态预测器预测要采用 not 的前向分支和要采用的后向分支(因为它们通常表示循环)。因此,编译器将调整静态代码布局以匹配预测。 (这也可能有助于将热路径放在相邻的缓存行上,这可能会有所帮助。)

在 PPC 上,一些跳转指令可以预测它们的可能性。我不知道编译器是否也会重新排列代码。

我不知道 ARM CPU 是如何预测分支的。作为低功耗设备,它的分支预测可能不太复杂,而静态预测可能会产生更大的影响。

【讨论】:

    【解决方案3】:

    可能/不太可能的提示通过使用程序员认为通常正确的分支代码预加载 ICache 来工作。分支预测器本质上依赖于有限的历史数据,仅在循环(或小型代码库)中有效,并且在分支性能方面,循环并不总是问题 - 例如,在实时模拟或游戏中,其中需要以非常高的速率处理大量对象的大量模拟/游戏逻辑。分支预测器在这种情况下无法有效运行,这对 sim 开发人员来说是一个严重的性能问题。这种逻辑实际上可以由每帧数千个不同的、不重复的条件组成,从而完全禁用分支预测器有效运行的能力。

    在回答原始问题时,编译器在生成预加载 Icache 的代码时倾向于假设条件为假。您应该检查代码中的程序集输出以验证这一点,然后如果您不想构建代码以适应特定的处理器架构,则可以为要以高性能方式预加载的条件编写宏.

    一些研究估计,现代处理器上的现代游戏引擎将 60-80% 的时间用于缓存未命中,而分支错误预测约占这些未命中的 15%。为了适应现代游戏引擎,分支预测器需要整个游戏逻辑框架的历史数据——每个管道可能涉及数 MB 的数据。

    【讨论】:

    • “预加载 I-cache”的机制实际上只是将预期路径放在分支之后,作为失败案例。而不是跳到其他地方(可能足够远,可以在不同的缓存行中)。您听起来好像有 asm 指令可以明确地将软件预取到 I-cache 中。没有(在大多数 ISA 上)。它也大多与硬件动态分支预测分开。即使预测正确,未采用的分支也往往更有效,因为前端不必丢弃它在连续块中获取的任何指令字节。
    猜你喜欢
    • 2010-10-24
    • 1970-01-01
    • 2012-06-10
    • 2011-02-13
    • 2015-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    相关资源
    最近更新 更多