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