Mobius 一個運行在 .NET Core 上的 .NET 運行時

来源:https://www.cnblogs.com/lindexi/archive/2020/04/23/12758500.html
-Advertisement-
Play Games

一個 .NET 應用僅僅只是一塊在 .NET 運行時上面運行的二進位代碼。而 .NET 運行時只是一個能執行這項任務的程式。當前的 .NET Framework 和 .NET Core 運行時採用 C++ 編寫,而 Mobius 是一個使用 C# 重寫的 .NET 運行時,重寫包括 JIT 編譯和 ... ...


一個 .NET 應用僅僅只是一塊在 .NET 運行時上面運行的二進位代碼。而 .NET 運行時只是一個能執行這項任務的程式。當前的 .NET Framework 和 .NET Core 運行時採用 C++ 編寫,而 Mobius 是一個使用 C# 重寫的 .NET 運行時,重寫包括 JIT 編譯和 GC 等,這些邏輯都將和 C++ 無關

原文:Mobius – .NET runtime running on .NET Core – TooSlowException

我看到這個有趣的項目的時候就想試試安利一下大家,這個項目特別適合用來瞭解 GC (Garbage Collector 垃圾收集)和 JIT (Just-In-Time Compiler 即時編譯器)的演算法

讓 C# 編寫一個 .NET 運行時和編寫一個運行在這個運行時上的 .NET 應用是否有可能呢?換句話是不要 Native 的本機代碼或 C++ 代碼,所有的代碼都是通過 C# 編寫是否有可能?這看起來是一個無窮的遞歸,用 .NET 寫 .NET 的運行時運行在 .NET 的運行時上。這是不是就是將一個 .NET 運行時運行在另一個 .NET 運行時上?

作者kkokosa決定開始試試水,這就是做 Mobius 運行時想法的原因。這個想法聽起來很奇怪,連作者都不抱期望在一個世紀內將這個想法投入使用。不過作者的想法是想要瞭解如果寫出整個 .NET 運行時需要多少的代碼量。同時作者也發現了其實這個想法的作用其實很小,即使想象現在有一個 NuGet 包在安裝完成之後就可以添加到咱的應用上,此時的這個包就包含了完整的運行時代碼,其實好像也不能做什麼

原理

其實這個想法在其他的領域也有人嘗試過,最著名的不過是 RVM —— 用 Java 編寫的 JVM 虛擬機。雖然他需要使用 C 的引導啟動,但是能做到自己托管自己,完全由 Java 運行的虛擬機同時不需要其他的虛擬機。這看起來非常和作者想象的 Mobius 非常接近

這個想法不止作者一個人在想,其實也有小伙伴在 Github 上發佈了一個 issus 說能否使用 C# 寫 JIT 和 GC 的邏輯

基於這些考慮,可以看到開發 Mobius 的原因如下:

  • 用於實驗和研究的框架。使用 C# 和 .NET 編寫的運行時,咱可以更簡易和快速的瞭解整個原型,比如對 JIT 或 GC 模塊的更改。咱可以使用熟悉的語言如 F# 等去編寫整個 .NET 的底層
  • 用於學習。在寫這個框架或參與開發的時候,可以從裡面學到很多運行時的做法。這也是可以用到很多現代化的 C# 特性的項目,使用更底層的 API 如 Span staclallock Unsafe 等
  • 提升性能。這顯然是很有爭議的一點。在另一個托管的運行時上面運行另一個運行時看起來就和高性能沒有關聯。但是如果應用是熱啟動,那麼意味著此時運行的代碼生成質量可以依托對CPU的優化,可以達到比本機代碼更好的性能。使用 C# 開發理論上可以使用更加穩健的優化。同樣用 C# 寫 GC 也能有相同的提升
  • 用於玩鬧。對於很多人來說,例如德熙看著這個項目一步步搭建起來是十分有趣的

如上面說的,其實都不是很強的理由,為什麼要用 .NET 去寫 .NET 運行時。大多數情況下,人們會認為使用 C++ 開發和使用 C# 開發不是對立的,兩者的差別不是很大。作者非常同意這個觀點,這就是為什麼作者其實是將這個項目當成一個玩具和實驗的項目

先拋開是否有必要做這樣的事情,請讓咱想想這個項目可以如何做

基本設計原理

首先,要理解的最重要的事情是 Mobius 仍然會將咱的應用程式編譯為本地 Native 代碼。以這種方式,最終應用程式將以(幾乎)本機代碼速度運行。不同之處在於托管的基礎設施,如 GC 和類型系統、JIT編譯器是作為托管代碼運行的。這意味著這些代碼也被 JIT 編譯

如上圖,我們有兩層JIT構建的代碼和底層實際運行時的本地 Native 代碼。從圖片看起來中間的這一層 .NET Core 基礎設施的 Mobius 層是多餘的。如果這一層是使用無分配對象的方式寫的,那麼不需要任何的 GC 方法。在預熱之後,對 JIT 的調用也將會很少。這就允許咱假設在一個正常運行的應用程式中,大部分在 Mobius 層的內容都是經過了 JIT 編譯優化完成之後運行的,這包括了常用的對 .NET Core 代碼的 JIT 構建的代碼,這將十分接近 .NET Core 的原生調用

從上面的圖看,其實 Mobius 的多餘還是很明顯。一個可以想的方法是在兩個運行時之間共用基礎設施

重寫整個類型系統並不是一件很有趣的事情。我們甚至可以考慮在 Mobius 中重用相同的 GC 垃圾回收,所以使用 Mobius 給 .NET 應用提供對象將看起來不錯。雖然上面的方法請看起來不錯,但依然存在兩個問題:

  • 這大大減少了 Mobius 框架需要研究的功能。因為沒有重新研究一遍 GC 和 JIT 演算法,我們將被迫考慮如何合併現有的技術
  • 在 .NET 運行時裡面 JIT 和 GC 和類型系統都有比較大的耦合。除了在 Mobius 實現相同的機制之外沒有其他方法,將會受限於當前的方法

基於這個原因,作者認為 .NET Core 運行時應該只提供很少量的運行時服務給到 Mobius 框架,提供的服務主要只是調用 Jit 編譯代碼

當前狀態

當前作者還是試驗可行性,正在做的是讓最簡單的 C# 應用能玩起來

private static int Main(string[] args)
{
   int num = 1;
   int num2 = 2;
   return num + num2;
}

通過一些可行性的測試,作者看到了曙光,應該是能做出來的。目前所有需要的機制都已就緒,包括:即使編譯的基礎支持,通過托管調用 JIT 代碼,通過 JIT 代碼調用 Mobius 框架。但是因為測試可行性的項目代碼寫的糟,還需要一點時間對代碼進行重構,完善並實現大量的元數據處理,去掉一些硬編碼值

現在這個可行性項目只是能做到運行當前這個簡單的應用而已,運行的時候通過完全的 CIL 指令和沒有任何的異常處理,同時只有 GC 的存根

在下一篇系列文章中,作者將介紹Mobius實現最底層部分的更多細節和代碼片段

逗比註:

如果本文看的不錯,想要參與開發,我覺得在這之前需要先讀一下農夫的書,請看 《.NET 底層入門》這本書

另外上面說的玩具什麼的只是原作者謙虛的說法,其實這個玩法是可行的,在 Github 有小伙伴在討論,請看 Port JIT and GC to C# 這個鏈接


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 解決方式: 1.檢查iis托管模塊中是否有Session 2.在web.Config中的加上 <pages enableSessionState="true" /> ...
  • 1、創建Api項目 我用的是VS2019 Core3.1 。打開Vs2019 創建Asp.Net Core Web應用程式命名CoreWebApi 創建選擇API 在Controller文件夾下麵添加一個Api控制器 FileUp,修改Api的路由 [Route("api/[controller]/ ...
  • 普通調用方法 調用方法如下 須通過'DBTool.BeginTransaction()'開啟事務調用'tran.Complete()'提交事務,不調用'tran.Complete()'當using結束會自動回滾 註意'DBTool.BeginTransaction()'必須使用using 事務嵌套調 ...
  • c 類 當你定義一個類時,你定義了一個數據類型的藍圖。這實際上並沒有定義任何的數據,但它定義了類的名稱意味著什麼,也就是說,類的對象由什麼組成及在這個對象上可執行什麼操作。對象是類的實例。構成類的方法和變數成為類的成員。 聲明類 創建對象 通過使用 new 關鍵字(後跟對象將基於的類的名稱)可以創建 ...
  • 這是要爬的地址 https://www.iqiyi.com/manhua/detail_18yzlq8jc5.html,F12 查看網路發現他是通過 https://www.iqiyi.com/manhua/catalog/18yzlq8jc5/ 這個介面獲取目錄信息的。 這是第一話的地址 http ...
  • c 方法 一個方法是把一些相關的語句組織在一起,用來執行一個任務的語句塊。 方法簽名 通過指定在 或 中聲明方法: 可選的訪問級別,如 或 。 預設值為 。 可選的修飾符,如 或 。 返回值,或 (如果該方法不具有)。 方法名。 任何方法參數。 方法參數在括弧內,並且用逗號分隔。 空括弧指示方法不需 ...
  • wpf開源控制項MahApps.Metro 安裝 您可以通過NuGet GUI(右鍵單擊您的項目,單擊 Manage NuGet Packages ,選擇 Online 並搜索 MahApps.Metro )或使用Package Manager控制台安裝MahApps.Metro。 或使用軟體包管理器 ...
  • 1、安裝Nuget包MailKit,引用命名空間。 using MailKit.Net.Smtp; using MimeKit; 註意:引用MailKit對應最新版本 2、定義收發地址和標題 MimeMessage message = new MimeMessage(); MailboxAddres ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...