2013-02-22 76 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