2013-02-22 29 views
10

假设我有一个由三个函数A,B和C组成的编译单元.A从编译单元的外部函数(例如它是一个入口点或回调函数)调用一次; B被A多次调用(例如它在一个紧密循环中被调用);每调用一次B就调用一次C(例如,它是一个库函数)。通过A(通过B和C)的整个路径对性能至关重要,尽管A本身的性能并不重要(因为大部分时间都花在B和C上)。GCC热属性的语义

__attribute__ ((hot))注释来影响这条路径的更积极的优化的最小函数集是什么?假设我们不能使用-fprofile-generate

等价地:__attribute__ ((hot))意思是“优化这个函数体”,“优化对这个函数的调用”,“优化所有的后代调用这个函数使得”,或者它们的某些组合?

海湾合作委员会信息页面没有明确地解决这些问题。

+0

使用'__attribute__((热))'可​​能会获得你一些东西,但是你可能会从首先制作B和C'静态内联'并使用'-O3'优化来获得更好的结果。 – twalberg 2013-02-22 17:03:01

+0

我假设这些步骤已经完成。 – 2013-03-06 20:26:20

回答

13

Official documentation

hot 上的函数的热属性用于通知编译器该函数是已编译的程序的一个热点。该功能进行了更为积极的优化,并将其放置在文本部分的特殊部分中,以便将所有热门功能紧密结合在一起,从而改善局部性。 当配置文件反馈可用时,通过-fprofile-use,自动检测热功能,并忽略此属性。

函数的热属性在4.3之前的GCC版本中没有实现。

标签上的热属性用于通知编译器跟随标签的路径比没有如此注释的路径更可能。该属性用于不能使用__builtin_expect的情况下,例如计算出的goto或asm goto。

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

2007

​​

提示所标记的功能是“热”和应更aggresively优化和/或放置在靠近其他“热”的功能(缓存局部性)。

Gilad Ben-Yossef

顾名思义,这些功能属性被用来暗示相应的函数被调用经常在你的代码(热)或很少叫(冷)的编译器。

然后,编译器可以对分支中的代码(如if语句)进行排序,以支持调用这些热门函数的分支和不利于函数的冷函数,假设更有可能分支将被采用调用热门功能,而不太可能调用冷门功能。

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

适用于hot属性的好候选项是在您的代码库中经常调用的核心函数。冷属性的好候选者是内部错误处理函数,只有在错误的情况下才会调用它。

因此,根据这些来源,__attribute__ ((hot))指:

  • 优化调用此函数
  • 优化这个功能
  • 放体这一功能的身体.hot部分(到基所有热点代码在一个位置)

经过源代码分析后,我们可以说“热”属性与(lookup_attribute ("hot", DECL_ATTRIBUTES (current_function_decl))检查;并且如果属实,功能node->frequency设置为NODE_FREQUENCY_HOTpredict.c, compute_function_frequency())。

如果函数具有频率NODE_FREQUENCY_HOT

  • 如果没有配置文件信息,并在树枝上没有likely/unlikelymaybe_hot_frequency_p将为函数返回true(==” ...频率FREQ被认为热“。)。这会将函数中所有基本块(BB)的值变为“真”(“BB可能是CPU密集型的,应该针对最大性能进行优化”),并且maybe_hot_edge_p对于函数中的所有边都成立。反过来,在非-Os模式这些BB和边缘和循环将优化速度,而不是大小。

  • 对于此函数的所有出站呼叫边缘,cgraph_maybe_hot_edge_p将返回true(“如果呼叫可能很热,则返回true”)。这个标志在IPA(IPA-inline.c,IPA-cp.c,IPA-直列analysis.c)和影响力在线和克隆的决定

+0

不要这样想。这是不完整的,需要一些实验。我认为,热也可能影响代码,从热功能调用。 – osgx 2013-02-27 19:31:24

+1

您现在或将来可以期待gcc将函数的热度传播给它的祖先和后代分支,以及它们调用gcc可以确定调用图的函数。 – codeshot 2016-06-01 01:29:00

+0

@codeshot如果这是盲目地对所有的祖先和后代完成的,那么大部分时间整个程序都会被标记为热,否?在功能有多个祖先并且只有一个经常使用的情况下,这也是一种浪费。 – Jeevaka 2016-07-12 13:30:40