追蹤設定檔品質

使用 PGO 進行原生映像檔的最具挑戰性的步驟是為相關工作負載收集設定檔。因為您的原始碼不斷演進,您的應用程式很少在時間上是靜態的。為每個原始碼變更執行「建置儀器化映像檔」、「收集設定檔」和「建置最佳化映像檔」的步驟有時非常耗時。本文檔針對「隨著應用程式原始碼隨時間變更,我可以在多久時間內繼續使用現有的設定檔?」這個問題提供了一些解答。

方法 1:無限期重複使用設定檔 #

當您建置最佳化應用程式時,原生映像檔會盡力使用指定的設定檔。這表示為您的應用程式提供過時的設定檔(甚至是完全不同應用程式的設定檔)不應該阻止原生映像檔產生原生可執行檔。

注意:不正確的設定檔可能會導致比沒有設定檔更差的效能。這是因為不正確的設定檔可能會導致編譯器將最佳化資源花在應用程式的錯誤元素上,並降低重要元素的優先順序。

儘管如此,無限期地重複使用單一設定檔來開發應用程式遲早會適得其反。

方法 2:定期收集設定檔 #

由於您的應用程式可能會定期變更,因此定期收集新的設定檔是合理的。達成此目的的一種方法是使用 master 分支的頂端建置應用程式的儀器化版本,執行工作負載以收集設定檔,並將產生的 iprof 檔案上傳到 FTP 伺服器,其他最佳化建置可以從該伺服器下載它。這確保了正在建置的應用程式版本與所用設定檔之間的差異永遠不會大於固定的時間間隔(在此範例中為 24 小時)。

然而,定期收集設定檔會延長計算時間,因此應該根據應用程式變更的頻率來平衡。如果您的應用程式相對穩定且原始碼變更不頻繁,則重新設定設定檔的頻率較低是沒有問題的。以下是一些需要記住的事項

  • 將您的設定檔排程與應用程式發佈排程對齊,以避免使用過時的設定檔建置應用程式。
  • 理想情況下,將生產工作負載轉換為可重現的工作負載,將收集設定檔作為建置的一部分,然後使用始終為最新的設定檔建立最佳化的原生可執行檔。

這樣一來,只要您的工作負載執行稍後將在生產中執行的應用程式的相同部分,您就不會有過時或錯位的設定檔的風險。

方法 3:隨時間追蹤設定檔品質指標 #

為了更好地了解設定檔的品質,原生映像檔提供了兩個指標,您可以在建置最佳化可執行檔時要求這些指標:設定檔相關性設定檔適用性。這些指標反映了設定檔與最佳化可執行檔中出現的方法和類別之間的關係。

使用相同設定檔的建置之間這兩個指標的值發生變化,表示這些建置中的類別和/或方法集合也發生了變化(在收集設定檔時和目前建置之間)。

如何取得設定檔品質指標 #

若要計算和列印設定檔品質指標,請在建置最佳化的原生可執行檔時傳遞 -H:+PGOPrintProfileQuality 選項。(此選項為實驗性質。)

讓我們考慮在 設定檔導向最佳化的基本用法 中介紹的生命遊戲範例應用程式

native-image -cp . GameOfLife -o gameoflife-pgo --pgo=gameoflife.iprof -H:+PGOPrintProfileQuality

在建置輸出中的第 5 階段,您應該會看到關於設定檔適用性和設定檔相關性的額外行

GraalVM Native Image: Generating 'gameoflife-pgo' (executable)
...
[5/8] Inlining methods...     [***]                                                                      (0.4s @ 0.28GB)
Info: PGO: Profile applicability is 21.74%. Profile relevance is 72.71%.
...

這些指標的絕對值並未告訴您太多,不應單獨考慮。如先前所述,這些指標描述了設定檔與應用程式程式碼之間的關係。如果您變更應用程式並重複使用設定檔,您應該會看到指標的值發生變化。

例如,將簡單的「方法重新命名」重構套用到 applyRules () 應用程式方法。從設定檔的角度來看,applyRules () 方法已從應用程式的方法集中移除,並引入了一個稱為 applyGameRules 的新方法。使用相同的設定檔和修改後的應用程式重新執行最佳化建置會傳回以下輸出

native-image -cp . GameOfLife -o gameoflife-pgo --pgo=gameoflife.iprof -H:+PGOPrintProfileQuality
========================================================================================================================
GraalVM Native Image: Generating 'gameoflife-pgo' (executable)...
...
[5/8] Inlining methods...     [***]                                                                      (0.4s @ 0.28GB)
Info: PGO: Profile applicability is 21.67%. Profile relevance is 72.66%.                                                                  (6.8s @ 0.29GB)
...

回想一下,第一個建置中的設定檔適用性為 21.74%,現在為 21.67%。同樣地,第一個建置中的設定檔相關性為 72.71%,現在為 72.66%。程式碼的小幅變更導致指標值發生小幅變化,通知您設定檔可能稍微過時。

注意:在此範例中,您重新命名了一個非常熱門的方法。由於設定檔無法套用到熱門方法,此變更可能會導致效能衰退。在應用程式的冷程式碼中所做的類似變更將導致這些指標出現類似的減少,但這不應影響效能。請注意,這些指標是用於衡量提供的設定檔與應用程式中的方法集合之間的關係,而不是以任何方式衡量或預測設定檔、應用程式原始碼或相依性變更可能產生的任何效能影響。當在單一建置中觀察到這些數字時,也沒有什麼意義或用處。它們的用處來自於觀察跨建置重複使用設定檔或為應用程式的相同建置提供不同設定檔時指標的變化。

設定檔品質指標:適用性 #

適用性指標回答了以下問題:「此設定檔對應用程式的方法的適用性如何?」。在編譯應用程式中的個別方法期間,它會追蹤程式碼中有多少個位置 N 需要設定檔,以及有多少次 S 可使用設定檔。設定檔適用性指標是比率 S / N,以百分比表示。

這表示在應用程式中新增程式碼(而不是設定檔中)應該會導致設定檔適用性降低。這是因為更多程式碼表示對設定檔的請求更多,而設定檔可以套用 (S) 的相同次數,除以對設定檔的總請求數 (N) 較大。

注意:期待設定檔適用性為 100% 是錯誤的。在幾乎所有情況下,良好的工作負載都會區分應用程式的熱門部分和冷門部分,並且不會執行某些冷程式碼部分。因此,設定檔不會包含應用程式冷部分(例如例外狀況處理常式)的任何項目,而這些部分在實際工作負載中很少執行。100% 的適用性表示映像檔中的所有程式碼部分都已完全設定設定檔,這在實務上幾乎從未發生過。

設定檔品質指標:相關性 #

相關性指標旨在回答以下問題:「設定檔內容在多大程度上與應用程式方法相符?」。載入設定檔時,會根據應用程式方法集合檢查其所有資料,並且會捨棄所有不符合這些方法的項目。例如,如果您從類別中移除方法,但使用仍然具有該方法項目的設定檔,則所有這些項目都會在載入設定檔期間捨棄。設定檔相關性是在載入期間捨棄的資料百分比。

這表示從應用程式中移除程式碼(而不是從設定檔中)應該會導致設定檔相關性降低,因為設定檔中與新應用程式版本相關的資料百分比會降低。另一方面,在應用程式中新增程式碼(例如新的類別或相依性)不會影響此指標,因為您需要從設定檔捨棄的資料量不會變更。

注意:期待建置與用於收集設定檔的應用程式完全相同的最佳化二進位檔會導致設定檔相關性為 100% 是錯誤的。事實並非如此,因為儀器化二進位檔和最佳化二進位檔的方法在細微之處有所不同。例如,儀器化二進位檔包含用於收集設定檔資料的程式碼以及將該資料序列化為檔案的程式碼。此程式碼是不必要的,因此不會出現在最佳化二進位檔中。檢視生命遊戲範例,約 70% 的相關性主要是因為應用程式非常小(單一 Java 類別的程式碼少於 120 行)。因此,儀器化二進位檔和最佳化二進位檔的方法集合差異相當誇大。對於較大的真實應用程式,此百分比通常較大,但不會達到 100%。

延伸閱讀 #

與我們聯繫