簡體   English   中英

什么調用編譯器內聯?

[英]what calls does the compiler inline?

你怎么知道編譯器內聯的內容和內容是什么?

有時我被告知一些小的優化是沒有意義的,因為編譯器將內聯某些調用或計算,其他時候似乎建議使用類似的優化。

有什么規則可以讓我們知道什么時候或者不需要優化這些東西?

查看內聯是否內聯的唯一可靠方法是查看程序集。

是否內聯的內容完全取決於編譯器 - 因為編譯器最終決定是否內聯某些內容。

拋棄過早的優化:如果真的很重要(或者你只是好奇的話),你可以使用特定於編譯器的編譯指示來強制內聯/不內聯函數,然后適當地進行配置以查看是否可以做出比編譯器更好的決策。

然而,在某些情況下,您可以確定無法內聯函數:

  • 實際上稱為函數,在編譯時無法確定類型。
  • 除非可以靜態確定最大深度,否則遞歸函數永遠不能完全內聯。

這可能看起來有點切,但我認為這很重要。

有什么規則可以讓我們知道什么時候或者不需要優化這些東西?

我會說在有任何其他問題之前有兩個規則可以解決這個具體問題:

  1. 這可能沒關系。 除非您在Release版本中分析了代碼並證明與函數調用相關的開銷是代碼中的主要瓶頸,否則最好忘記inline代碼的性能影響。

  2. 您很少或根本無法控制編譯器將不會內聯的內容。 如果編譯器認為合適,則可以忽略inline 有些事情是不可能內聯的。 有些平台沿force_inline提供語言擴展,但即使這些也可以忽略。

沒有可靠的規則。 甚至還有一些 測試可以測試您對優化的假設。

How can you tell what will or what won't be made inline by the compiler?

你不能:)例如,如果你使用inline關鍵字,它只是一個提示,沒有編譯器有義務尊重它。 但是,如果您需要瘋狂的優化,似乎您可能需要在比c / c ++更低的級別編碼並使用匯編調用

你看過SO了嗎?

例如:

GCC內聯C ++是否在沒有'inline'關鍵字的情況下運行?

為什么不將內容標記為內聯?

你問的問題非常籠統 - 因為它取決於哪些編譯器,更不用說哪個版本了。 聽起來你正在做的是過早優化 - 你應該分析你的代碼並找到減慢它的區域。 這種情況會讓人覺得“這會被內聯嗎?” 問題沒有實際意義,因為你會看到編譯器的后效,包括內聯和其他優化。

沒有辦法確定,有關詳細信息,為什么以及何時內聯是一個好習慣,我建議您閱讀此C ++常見問題解答

您無法知道編譯器在優化階段內聯的內容:您應該清楚地了解精確編譯器的啟發式方法。 但是,您可以指定要內聯的內容。

微軟的編譯器很長一段時間都有/ Ob優化標志,它強制它內聯所有顯式inline函數。 這是非標准的,默認情況下,它的行為符合標准,即將關鍵字視為提示。 英特爾Parallel Studio編譯器的行為類似。

你怎么知道編譯器內聯的內容和內容是什么?

一般來說,你不能。

您可能想閱讀Herb Sutter撰寫的Inline Redux文章。 它揭示了許多技術來解釋何時可能發生內聯,知道后者發生......你擁有的信息越多。

例如,在JIT環境中,你可以看一個循環,意識到它的整個主體是在一個看起來經常是Foo類型的對象上執行的,它專門用於Foo的整個主體,它允許完全內聯虛擬方法,現在檢查循環的頂部,如果對象是Foo ,如果是,則切換到完全內聯的正文版本而不是具有虛擬調用的通用版本。

那么什么可以內聯? 這取決於......

一般來說,C ++編譯器的特點是:

  • 編譯時間內聯(歷史)
  • 鏈接時間內聯(所謂的LTO優化包的一部分)

這意味着它們只能將其優化基於靜態(在編譯時已知)信息。

在編譯時,這意味着如果靜態類型虛擬調用可能被虛擬化(內聯的第一步:猜測實際函數調用;))。 這意味着任何定義都可見的函數也可以內聯。

在庫的鏈接時,您基本上公開了新的函數定義,允許內聯幾個調用。

在可執行文件的鏈接時,WPA(整個程序分析)可以通過意識到某些類永遠不會從中派生來開始添加一些虛擬化,因此就這個可執行文件而言可以被認為是final GCC和LLVM(我懷疑VC ++可以)都不會執行此優化,因為它們沒有保持類層次結構的字節代碼。

如果他們希望,編譯器可以轉儲他們擁有的中間表示(某種方式為字節碼)並等待安裝以內聯OS特定的調用。 雖然我知道沒有(對於C ++)這樣做。

運行時更改在C ++中非常棘手,因為程序員可以訪問內存(例如函數地址),因此很難只進行安全轉換......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM