假设我有一个由三个函数A,B和C组成的编译单元.A从编译单元外部的函数调用一次(例如,它是一个入口点或回调函数); A被A多次调用(例如,它在紧密循环中被调用);每次调用B都会调用一次C(例如,它是一个库函数)。
通过A(通过B和C)的整个路径对性能至关重要,尽管A本身的性能不重要(因为大部分时间花在B和C上)。
应该使用__attribute__ ((hot))
注释的最小函数集是什么,以实现对此路径的更积极的优化?假设我们无法使用-fprofile-generate
。
等价:__attribute__ ((hot))
是否意味着“优化此函数的主体”,“优化对此函数的调用”,“优化此函数所做的所有后代调用”,或其某些组合?
GCC信息页面没有明确解决这些问题。
答案 0 :(得分:16)
hot
函数的hot属性用于通知编译器函数是已编译程序的热点。该功能进行了更积极的优化,并且在许多目标上,它被放置在文本部分的特殊子部分中,因此所有热门功能都紧密地联系在一起,从而改善了局部性。 当配置文件反馈可用时,通过-fprofile-use,将自动检测热门功能,并忽略此属性。函数的hot属性未在4.3之前的GCC版本中实现。
标签上的hot属性用于通知编译器标签后面的路径比未注释的路径更可能。此属性用于无法使用__builtin_expect的情况,例如使用计算的goto或asm goto。
标签上的hot属性未在4.8之前的GCC版本中实现。
2007:
__attribute__((hot))
提示标记的功能是“热门”,应该更加积极地优化和/或放置在其他“热门”功能附近(用于缓存局部性)。
顾名思义,这些函数属性用于暗示编译器在代码中经常调用相应的函数(热)或很少调用(冷)。
然后,编译器可以在分支中对代码进行排序,例如if语句,以支持调用这些热函数的分支并拒绝函数冷函数,假设更可能是将要调用的分支将调用热门功能,不太可能叫冷。
此外,编译器可以选择将生成的二进制文件中特殊部分标记为hot的函数组合在一起,前提是数据和指令缓存基于局部性或相关代码和数据的相对距离工作,将所有经常调用的函数放在一起将导致更好地缓存整个应用程序的代码。
热门属性的优秀候选者是核心函数,这些函数在代码库中经常被调用。 cold属性的良好候选者是内部错误处理函数,只有在出现错误时才会调用它们。
因此,根据这些来源,__attribute__ ((hot))
表示:
.hot
部分(将所有热门代码分组到一个位置)在源代码分析之后,我们可以说用(lookup_attribute ("hot", DECL_ATTRIBUTES (current_function_decl))
检查“热”属性;当它成立时,函数node->frequency
设置为NODE_FREQUENCY_HOT
(predict.c, compute_function_frequency())。
如果函数的频率为NODE_FREQUENCY_HOT
,
如果分支上没有配置文件信息且likely/unlikely
,则maybe_hot_frequency_p
将为该函数返回true(==“...频率FREQ被认为是热门。”) 。对于函数中的所有基本块(BB),这会将maybe_hot_bb_p
的值转换为true(“BB可以是CPU密集型,应该针对最大性能进行优化。”)并且maybe_hot_edge_p
对于函数中的所有边都为真。反过来在非-Os
- 模式中,这些BB和边缘以及循环将针对速度进行优化,而不是针对大小进行优化。
对于此函数的所有出站调用边,cgraph_maybe_hot_edge_p
将返回true(“如果调用可能很热,则返回true。”)。该标志用于IPA(ipa-inline.c,ipa-cp.c,ipa-inline-analysis.c)并影响内联和克隆决策