您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關.NET Core 2.1中的分層編譯是什么意思,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
如果您是.NET性能的粉絲,最近有很多好消息,例如.NET Core 2.1中的性能改進和宣布.NET Core 2.1,但我們還有更多的好消息。分層編譯是一項重要的新特性功能,我們可以作為預覽供任何人試用,從.NET Core 2.1開始。在我們測試的許多場景中,應用程序啟動更快,并且在穩定狀態下運行得更快。一個在.NET Core 2.1上運行的項目,以及對環境變量或項目文件進行微不足道的更改以啟用它。在文章的其余部分,我們將介紹它是什么,如何使用它,以及為什么它是2.1版本的隱藏技能!
從.NET Framework開始,代碼中的每個方法通常都編譯一次。但是,在決定如何進行會影響應用程序性能的編譯時,需要進行權衡。例如,JIT可以進行非常積極的優化并獲得很好的穩定性能,但是優化代碼并不是一件容易的事情,因此您的應用程序啟動速度非常慢。或者JIT可以使用非常簡單的編譯算法,這些算法可以快速運行,因此您的應用程序可以快速啟動,但代碼質量會更差,并且應用程序吞吐量會受到影響。.NET一直試圖采用一種平衡的方法,在啟動和穩定性能方面做得很合理,但使用單一編譯意味著需要妥協。
分層編譯功能通過允許運行時熱交換技術對.NET進行多次編譯同一個方法改變了以上前提。兩套機制的分離以便我們可以選擇最適合啟動的技術,選擇最穩定狀態并且在兩者上都表現出更好性能的第二種技術(分層編譯)。在.NET Core 2.1中,這就是Tiered Compilation旨在為您的應用程序做的事情:
更快的應用程序啟動時間 - 當應用程序啟動時,它會等待一些MSIL代碼到JIT。分層編譯要求JIT快速生成初始編譯,如果需要,犧牲代碼質量優化。之后,如果頻繁調用該方法,則在后臺線程上生成更優化的代碼,并替換初始代碼以保持應用程序的穩定性能。
更快的穩定狀態下的性能 - 對于典型的.NET Core應用程序,大多數框架代碼將從預編譯(ReadyToRun)映像加載。這對于啟動非常有用,但預編譯的映像具有版本控制約束和禁止某些類型優化的CPU指令約束。對于經常調用的這些鏡像中的任何方法,分層編譯請求JIT在后臺線程上創建優化代碼,以替換預編譯版本。
我們將此作為預覽版發布的部分原因是要了解它對您的應用程序的執行情況,但以下是我們對其進行測試的一些示例。雖然非常依賴于場景,但我們希望這些結果是您在類似工作場景上的典型代表,并且隨著功能的成熟,結果將繼續改進。基準測試是在默認配置下運行的.NET Core 2.1 RTM,并且所有數字都經過縮放,因此基準始終為1.0。在第一組中,我們有幾個Tech Empower測試和MusicStore(用來專門測試的項目),這是我們常用的ASP.NET應用示例。
雖然我們的一些ASP.NET基準測試得益于特別好(MvcPlaintext RPS超過60% - 哇!),但分層編譯并不特定于ASP.NET。以下是您在日常開發中可能遇到的一些示例.NET Core命令行應用程序:
你的應用程序將如何運作?測量比預測要容易得多,但我們可以提供一些廣泛的經驗法則。
啟動改進主要適用于減少管理托管代碼的時間。您可以使用PerfView等工具來確定您的應用花費多少時間。在我們的測試中,jitting花費的時間通常會減少約35%。
穩定狀態的改進主要適用于CPU綁定的應用程序,其中一些熱代碼來自.NET或ASP.NET預編譯庫。例如PerfView可以幫助您確定您的應用程序是這一類。
一個小免責聲明,該功能仍然是一個預覽。我們已對其進行了大量測試,但默認情況下未啟用此功能,因為我們希望收集反饋并繼續進行調整。打開它可能不會使你的應用程序更快,或者你可能遇到我們沒有覆蓋到的地方。如果遇到問題,微軟隨時為您提供幫助,您可以隨時輕松將其禁用。如果您愿意,可以在生產中啟用此功能,但我們強烈建議您事先進行測試。
有幾種方式可以選擇加入此功能,所有這些方法都具有相同的效果:
如果使用.NET 2.1 SDK 自行構建應用程序 - 將MSBuild屬性<TieredCompilation> true </ TieredCompilation>添加到項目文件中的默認屬性組。例如:
此GitHub 鏈接可找到以下代碼
<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp2.1</TargetFramework> <TieredCompilation>true</TieredCompilation></PropertyGroup></Project>
如果運行已構建的應用程序,請編輯runtimeconfig.json以將System.Runtime.TieredCompilation = true添加到configProperties。例如:
{ "runtimeOptions": { "configProperties": { "System.Runtime.TieredCompilation": true } }, "framework": { ... } }
如果您想運行應用程序但不想修改任何文件,請設置環境變量
COMPlus_TieredCompilation=1
有關嘗試和測量性能的更多詳細信息,請查看分層編譯演示
好奇它是如何工作的?不要害怕,理解這些內部細節不是使用分層編譯所必需的,如果您愿意,可以跳過本節。一目了然,該功能可分為四個不同的部分:
JIT編譯器可以配置為生成不同質量的匯編代碼 - 令許多人驚訝的是,到目前為止,這還不是該功能的重點。回到.NET的起始,JIT支持默認編譯模式和用于調試的無優化編譯模式。正常模式產生更好的代碼質量并且編譯需要更長時間,而“無優化”模式則相反。對于分層編譯,我們創建了新的配置名稱“Tier0”和“Tier1”,但這些配置生成的代碼與我們一直使用的“無優化”和“正常”模式大致相同。到目前為止,大多數JIT更改都涉及在請求“Tier0”代碼時使JIT生成代碼更快。我們希望將來繼續提高Tier0編譯速度,
CodeVersionManager(代碼版本管理)跟蹤同一方法的不同代碼編譯(版本) - 最基本的是一個大內存字典,它存儲應用程序中.NET方法之間的映射和不同程序集實現的列表運行時可以使用它來執行該方法。我們使用一些技巧來優化這種數據結構,但如果你想深入研究項目的這個方面,可以參考我們提供的非常好的規范。
相同方法的不同匯編代碼匯編之間,在運行時狀態下熱更新的機制, - 當方法A調用方法B時,調用將依賴于jmp指令。通過調整運行時的jmp指令可以控制執行B的哪個實現。
決定要創建哪些代碼版本以及何時在它們之間切換的策略 - 運行時始終首先創建Tier0,這是從ReadyToRun映像加載的代碼,或者是使用最小化優化的代碼。呼叫計數器用于確定頻繁運行哪些方法,并使用計時器來避免在啟動期間過早創建Tier1的工作。一旦計數器和計時器都滿足,該方法就會排隊,后臺線程會編譯Tier1版本。有關詳細信息,請查看規范。
分層編譯創造了各種可能性,我們可以繼續充分利用未來的時間。既然運行時可以利用更極端的情況,那我們就有了擴展邊界的動力和動力,既可以加快編譯速度,又可以生成更高質量的代碼。通過代碼的運行時熱更新,.NET可以進行更詳細的分析,然后使用運行時反饋來進行更好的優化(配置文件引導優化)。這些技術可以允許代碼生成器甚至超出無法訪問配置文件數據的最佳靜態優化器。或者還有其他選項,例如用于更好診斷的動態去優化,用于減少內存使用的可收集代碼,以及用于性能檢測或服務的熱補丁。目前,我們最直接的目標仍然接近實際 - 確保預覽中的功能運行良好,響應您的反饋,并完成工作的第一次迭代。
關于.NET Core 2.1中的分層編譯是什么意思就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。