Optimization GCC热属性的语义

Optimization GCC热属性的语义,optimization,gcc,Optimization,Gcc,假设我有一个由三个函数组成的编译单元,a、B和C。a从编译单元外部的函数调用一次(例如,它是入口点或回调);B被A多次调用(例如,在紧密循环中调用);每次调用B(例如,它是一个库函数)都会调用C一次 通过A的整个路径(通过B和C)是性能关键的,尽管A本身的性能不是关键的(因为大部分时间都花在B和C上) 应该用\uuuuu attribute\uuuu((hot))注释的最小函数集是什么,以便对该路径进行更积极的优化?假设我们不能使用-fprofile generate 等价地:\uuuuu属性(

假设我有一个由三个函数组成的编译单元,a、B和C。a从编译单元外部的函数调用一次(例如,它是入口点或回调);B被A多次调用(例如,在紧密循环中调用);每次调用B(例如,它是一个库函数)都会调用C一次

通过A的整个路径(通过B和C)是性能关键的,尽管A本身的性能不是关键的(因为大部分时间都花在B和C上)

应该用
\uuuuu attribute\uuuu((hot))
注释的最小函数集是什么,以便对该路径进行更积极的优化?假设我们不能使用
-fprofile generate

等价地:
\uuuuu属性(hot))
是指“优化此函数的主体”、“优化此函数的调用”、“优化此函数所做的所有子代调用”还是其组合

GCC信息页面没有明确说明这些问题。

hot
函数的hot属性用于通知编译器该函数是已编译程序的热点。该函数进行了更积极的优化,在许多目标上,它被放置在文本部分的特殊小节中,因此所有热门函数看起来都很接近,以提高局部性。 当配置文件反馈可用时,通过-fprofile use自动检测热函数,并忽略此属性

函数的hot属性未在4.3之前的GCC版本中实现

标签上的hot属性用于通知编译器,标签后面的路径比没有注释的路径更有可能出现。此属性用于无法使用_ubuiltin_uexpect的情况,例如与computed goto或asm goto一起使用

标签上的热属性在4.8之前的GCC版本中未实现

:

提示标记的函数为“热”函数,应更积极地进行优化和/或放置在其他“热”函数附近(用于缓存局部性)

:

顾名思义,这些函数属性用于提示编译器在代码中经常调用(热)或很少调用(冷)

然后,编译器可以对分支(如if语句)中的代码进行排序,以支持调用这些热函数的分支,而不支持调用冷函数的分支,前提是所采用的分支更可能调用热函数,而不太可能调用冷函数

此外,编译器可以选择在生成的二进制文件的一个特殊部分中将标记为hot的函数组合在一起,前提是,由于数据和指令缓存基于位置或相关代码和数据的相对距离工作,将所有经常调用的函数放在一起,可以更好地缓存整个应用程序的代码

hot属性的好候选者是核心函数,它们在代码库中经常被调用。cold属性的最佳候选对象是内部错误处理函数,这些函数仅在发生错误时调用

因此,根据这些来源,
\uuuuuuuuuuuuu属性((热))
意味着:

  • 优化对此函数的调用
  • 优化此函数的主体
  • 将此函数的主体放入
    .hot
    部分(将所有热代码分组到一个位置)
在源代码分析之后,我们可以说用
(lookup_attribute(“hot”,DECL_ATTRIBUTES(current_function_DECL))
检查了“hot”属性;如果为true,则函数的
节点->频率设置为
节点频率\u hot

如果功能的频率为
节点\u频率\u热

  • 如果没有配置文件信息且分支上没有
    可能/不可能的
    ,则函数将返回true(=“…频率被认为是热的。”)。这将函数中所有基本块(BB)的值转换为true(“BB可能是CPU密集型的,应优化以获得最大性能。”)在非
    -Os
    -模式下,这些BB和边以及循环将针对速度而不是大小进行优化

  • 对于此函数的所有出站呼叫边缘,将返回true(“如果呼叫可能是热的,则返回true”)。此标志用于IPA(IPA inline.c、IPA-cp.c、IPA inline analysis.c)中,并影响内联和克隆决策


    • \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
      可能会给您带来一些好处,但首先使B和C
      都是静态内联的
      并使用
      -O3
      进行优化,您可能会得到更好的结果。我假设已经采取了这些步骤。不要这样认为。这是不完整的,需要进行一些实验。我认为,hot也可能会影响从hot函数调用的代码。您可以体验t gcc现在或将来将函数的热性传播到它的祖先和后代分支,以及它们调用的函数,gcc可以确定调用图。@代码快照如果对所有祖先和后代盲目地这样做,那么大多数时候整个程序都会被标记为热,否?同样在函数这取决于你对“盲”的定义,但多个祖先的观点是好的。我在此暂停我的期望,等待进一步的了解。我想了想,是的,如果“盲目”是指“不考虑分支”这将是一件荒谬的事情。但我肯定希望gcc实现者,无论是现在还是将来,至少将热度传播到最近的分支。如果分支被注释为“可能”,那么我希望他们通过分支传播热度-向下和向上,因为“可能”表示极端概率
       __attribute__((hot))