Mobius 一个运行在 .NET Core 上的 .NET 运行时

导语

一个 .NET 应用仅仅只是一块在 .NET 运行时上面运行的二进制代码。而 .NET 运行时只是一个能执行这项任务的程序。当前的 .NET Framework 和 .NET Core 运行时采用 C++ 编写,而 Mobius 是一个使用 C# 重写的 .NET 运行时,重写包括 JIT 编译和 GC 等,这些逻辑都将和 C++ 无关

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

https://tooslowexception.com/mobius-net-runtime-running-on-net-core/

我看到这个有趣的项目的时候就想试试安利一下大家,这个项目特别适合用来了解 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# 这个链接

https://github.com/dotnet/runtime/issues/10158

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/310197.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Autofac的切面编程实现

面向切面编程:Autofac.Annotation扩展组件是我开源的一款利用打标签完成autofac容器的注入组件。https://github.com/yuzd/Autofac.Annotation我们之前介绍了利用Aspect标签来完成拦截器功能Aspect是一对一的方式,我想要某个class开启拦截器功能我需要针…

[Java基础]体验Lambda表达式

普通写法: 代码如下: package LambdaPack01;public class MyRunnable implements Runnable{Overridepublic void run() {System.out.println("多线程启动了");} }package LambdaPack01;public class LambdaDemo01 {public static void main(String[] args) {MyRunna…

linux启动mqtt_linux下安装MQTT服务器 - EMQTT

1. 下载从官网下载https://www.emqx.io/downloads#broker, 本文所用版本为broker/v3.2.1/emqx-centos7-v3.2.1.ziplinux下 下载:wget https://www.emqx.io/downloads/broker/v3.2.1/emqx-centos7-v3.2.1.zip解压;unzip emqx-centos7-v3.2.1.zip所在目录&…

.net core 基于Dapper 的分库分表开源框架(core-data)

一、前言感觉很久没写文章了,最近也比较忙,写的相对比较少,抽空分享基于Dapper 的分库分表开源框架core-data的强大功能,更好的提高开发过程中的效率;在数据库的数据日积月累的积累下,业务数据库中的单表数…

[Java基础]Lambda表达式练习

代码如下: package LambdaPracticePack;public interface Eatable {void eat(); }package LambdaPracticePack;public class EatableImpl implements Eatable{Overridepublic void eat() {System.out.println("一天一苹果,医生远离我");} }package Lambd…

​你可能不知道的7个HTML小技巧

五一期间&#xff0c;知道大家都比较懒&#xff0c;我也是。所以写篇简单且基础的技术小文&#xff0c;不需要动脑子&#xff0c;扫一眼就能掌握的那种。DETAILS 标签<details> 标签将额外的详情信息隐藏起来&#xff0c;用户在需要的时候点击即可展开查看详情。<deta…

青年节寄语和新课程免费上架

大家好&#xff0c;确实好久没有写东西了&#xff0c;希望这篇推送不是用来提醒你取消关注哈。2020年这突如其来的疫情&#xff0c;打乱了我们的生活&#xff0c;也让很多人更加明白了生活的无常以及可贵吧&#xff0c;在此也真诚希望大家都要好好哒&#xff0c;不负韶华&#…

从堆里找回“丢失”的代码相关命令简介

前言 在上一篇文章中&#xff0c;我们主要使用了三个命令 !address&#xff0c;s&#xff0c;.writemem 把丢失的代码成功的保存到了文件中。本文简单介绍一下上文用到的这三个命令。windbg 中的地址范围语法 很多命令都会用到 地址范围。比如 s 命令&#xff0c;.writemem 命令…

慎用ToLower和ToUpper,小心把你的系统给拖垮了

不知道何时开始&#xff0c;很多程序员喜欢用ToLower&#xff0c;ToUpper去实现忽略大小写模式的字符串相等性比较&#xff0c;有可能这个习惯是从别的语言引进的&#xff0c;大胆猜测下是JS&#xff0c;为了不引起争论&#xff0c;我指的JS是技师的意思~一&#xff1a;背景1. …

mysql 2008 日_SQL2008 的 日期数据类型

摘要你是否曾经想在数据库中存储一个日期而没有时间部分&#xff0c;或者想存储一个时间值希望有更高的精度&#xff1f;在SQL Server 2008的介绍中&#xff0c;微软介绍了一些新的日期数据类允许你只存储一个日期、更高精度的时间值等。这些新的数据类型为你存储日期和时间相关…

别了,JavaScript;你好,Blazor

Web开发与JavaScript开发向来是同义词。直到WebAssembly的横空出世&#xff0c;WebAssembly (Wasm)是一种在浏览器中可以执行的二进制指令。WebAssembly 的 官方工具链 能够编译 C/C 代码&#xff0c;但许多社区也提供了不同语言的编译器&#xff0c;如 Rust&#xff0c;Python…

[Java基础]接口组成(默认方法,静态方法,私有方法)

默认方法: 代码如下: package MyInterfacePack;public interface MyInterface {void show1();void show2();// void show3();public default void show3(){System.out.println("show3");};}package MyInterfacePack;public class MyInterfaceImplOne implements …

linux jdk1.7 tomcat mysql_Linux环境搭建 jdk+tomcat+mysql

好久之前搭建的&#xff0c;现在记录下 防止下次配置去找安装jdk(jre也行),tomcat MySQL一、jdk安装及环境变量配置:我是用 jdk-8u191-linux-x64.tar.gz 安装的安装之前提前下载好 jdk版本 看你用什么版本吧 都一样的步骤 按照下面的步骤操作 要确保完全是一个新环境…

开源 一套 Blazor Server 端精致套件

Blazor 作为一种 Web 开发的新技术已经发展有一段时间了&#xff0c;有些人标称 无 JS 无 TS&#xff0c;我觉得有点误导新人的意味&#xff0c;也有人文章大肆宣传 Blazor 是 JavaScript 的终结者&#xff0c;是为了替代 JavaScript 而生的&#xff0c;我认为这些言论都太激进…

[Java基础]函数式接口

代码如下: package MyInterfacePack01;FunctionalInterface public interface MyInterface {void show(); }package MyInterfacePack01;public class MyInterfaceDemo {public static void main(String[] args){MyInterface my ()->System.out.println("hello world&q…

从零搭建分布式文件系统MinIO比FastDFS要更合适

前两天跟大家分享了一篇关于如何利用FastDFS组件来自建分布式文件系统的文章&#xff0c;有兴趣的朋友可以阅读下《用asp.net core结合fastdfs打造分布式文件存储系统》。通过留言发现大家虽然感兴趣&#xff0c;但是都觉得部署比较麻烦。的确&#xff0c;fastdfs的部署很繁琐&…