.NET 7 預覽版2 的亮點之 NativeAOT 正式合併入 .NET 主線

張善友發表於2022-03-19

.NET 中備受追捧和期待已久的功能NativeAOT終於出現在本週的.NET 7 預覽版2中,該專案的工作仍在繼續,該版本將 NativeAOT 從實驗性的 dotnet/runtimelab repo 中移出合併進入穩定的執行時庫 dotnet/runtime repo,但尚未在 dotnet SDK 中新增足夠的支援,以使用 NativeAOT 釋出專案。完成此操作後,可以對實際測試進行完善了。

.NET NativeAOT 編譯器脫離實驗性質正式跟隨 .NET 7 Preview 2 釋出到了官方 nuget 源:https://www.nuget.org/packages/Microsoft.DotNet.ILCompiler

從現在開始,7.0.0-* 版本基本可以放心用在生產環境。我們可用開始嘗試修剪我們的應用程式,並確保沒有剪裁警告。剪裁是 NativeAOT 的要求。GitHub 問題 .NET 7 中的 NativeAOT #61231 顯示了正在檢查的初始工作以及第一階段的剩餘工作:

aot_goals


NativeAOT 這個功能的完整支援真是不容易,具體怎麼用可用參考 hez2010的文章:通過 .NET NativeAOT 實現使用者體驗升級

這裡來回顧一下這個歷程:具體內容來自知乎的hez2010 的整理的內容 https://www.zhihu.com/question/472875939

Native AOT (2021.1~2021.7)的進展:

  • 託管型別系統的完善,支援了泛型介面的預設方法實現,但是還是不支援介面的泛型預設方法實現,因為這部分要對型別系統做很多的改動。
  • COM 支援基本做完了,因此現在的 Native AOT 已經可以成功編譯和執行 winforms 程式了(需要 COM Wrapper),WPF、WinUI 和 UWP 也在實驗中,但是 WPF 涉及到 C++/CLI,這部分無法靜態連結進去,不太可能獲得 Native AOT。
  • 泛型虛方法懶例項化(GVM Instantiation),不需要在編譯的時候就例項化所有的泛型虛方法,而是留在執行時第一次呼叫時來做,這麼做不僅不會損失效能,而且還能節省大量的編譯後體積,並避免泛型虛方法遞迴例項化導致的編譯時無限遞迴展開問題。但是並沒有完全解決無限泛型遞迴的問題,由於並行編譯沒法使用強聯通分量演算法進行檢測。
  • 支援了動態呼叫標註,然後對 .NET 6 的 BCL 進行了標註,因此大多數情況即使基礎庫某些方法裡用到了反射建立型別,也不會出現執行時找不到程式碼的問題,因為框架自己做了標註,編譯的時候編譯器就能知道並生成程式碼,而無需人工編寫大量的 rd.xml 標註資訊。
  • 目前正在新增託管型別系統對靜態虛方法的支援(已有 PR)。
  • 目前正在新增對 PS4/PS5 等平臺的支援(緩慢進展,可以執行起來簡單程式了)。
  • 目前正在新增對 WASM 平臺的支援(緩慢進展,可以執行起來簡單程式了)。
  • 支援了 ARM64 平臺。
  • 支援了靜態連結依賴項。
  • 支援使用 .NET 6 的靜態 PGO 資料做優化編譯。
  • 編譯速度的改善也是能明顯看得到的,以前的舊版本 CoreRT 編譯個程式動輒十分鐘半小時,現在基本半分鐘一分鐘都能搞定。
  • 2021/8/12 更新:

    1. 正在新增對 ARMv7 平臺的支援(已有 PR)
    2. 正在新增對介面泛型方法預設實現的支援(已有 PR)

    2021/8/14 更新:

    1. 介面泛型方法預設實現已支援,因此 efcore 可以用 NativeAOT 了
    2. 泛型虛擬方法解析速度有所提升(大概 8%),編譯時間更短了

    2021/8/17 更新:

    1. NativeAOT 在 .NET 6 上計劃的內容已經完成,已經可以穩定使用,另外可能會在 .NET 7 脫離實驗正式釋出
    2. ARMv7 平臺支援已接近完成
    .NET 7 預覽版2 的亮點之 NativeAOT 正式合併入 .NET 主線

    2021/8/24 更新:

    1. NativeAOT 編譯器版本已提升至 7.0.0-*

    2021/9/6 更新:

    1. 正在適配安卓
    2. LLVM 從 6 升級到 12
    3. 完善 IDynamicInterfaceCastable 支援,對 COM 的支援度進一步改善

    2021/9/17 更新:

    1. 支援了模組初始化器
    2. 正在新增對 x86 的支援

    2021/12/6 更新:

    1. Native AOT 轉正正式提上 .NET 7 計劃

    2021/12/15 更新:

    1. Native AOT 程式碼正式合併入 .NET 主線並啟用了構建
    2. 無限泛型展開導致無法編譯的問題已經解決

    2022/3/17 更新:

       1. 正式在.NET 7 Preview 2部落格文章中宣佈可用。 

       2. WPF 開始了 AOT 改造: https://github.com/dotnet/wpf/pull/6171

    相關文章