关于.NET 6.0 Crossgen2的一些研究

NET 6.0引入了Crossgen工具的后续版本Crossgen2,这个工具提供了程序提前(AOT)编译的能力。

什么是CrossGen?

我们日常开发时使用C#编译器CSC编译一个.NET程序集,程序集包含MSIL代码(中间语言代码)。当应用程序运行时,目标环境的本地JIT编译器将MSIL代码转换为本机代码,然后CPU才能执行它们。

但是这种JIT编译到导致应用程序启动很慢,因为JIT编译器必须花时间翻译代码。

为了实现更快地启动应用程序,CoreCLR包含了一个名为CrossGen的工具,它可以将MSIL代码预编译成本机代码。

其实最早可以追溯到.NET ngen技术,Ngen.exe (Native Image Generator)

然后,.NET 6设计引入Crossgen2有两大目标:

  •   提高crossgen开发的效率
  •   并实现crossgen目前无法实现的一系列功能。

这种转换有点类似于本机代码csc.exe升级演进为基于Roslyn的托管代码编译器。这种过程。

Crossgen2是用C#编写的,但是它没有像Roslyn那样公开一个功能全面的API,可以编程灵活使用。

接下来简单了解一下关于Crossgen2的几个主要问题:

一、Crossgen2的用途是什么,什么时候应该使用它

Crossgen 是一个为代码提供提前 (AOT) 编译的工具,从而减少了运行时对 JIT的性能消耗。

发布应用程序时,Crossgen 对所有程序集运行 JIT,并将 JIT 代码存储在一个额外的部分中,该部分可以在运行时快速获取。

Crossgen 应该用在快速启动的应用场景中。

二、Crossgen2跨平台编译原理是什么?

Crossgen2支持跨操作系统和体系结构的交叉编译能力。未来使用一台构建服务器就可以为所有目标环境生成本机代码Native Code,直接运行,提升第一次访问的性能和速度。

内部实现上,在Arm64上,Crossgen2可以使用编译为Arm64的x64 RyuJIT生成x64代码。类似的方式还有x64架构下生产x64代码。Crossgen2加载为该配置构建的RyuJIT。

三、用 C# 编写 Crossgen 的主要优点和缺点是什么

用 C# 编写,可以访问一组丰富的 .NET API 以及使用托管语言提供的内存安全保证。

使用 C# 的一个缺点是同时在许多小型程序集上使用 Crossgen2 时会增加处理时间,因为多次启动运行时会产生开销。幸运的是可以通过在自身上运行 Crossgen2 来缓解大部分问题!

四、Crossgen2的设计过程

Crossgen2 也不是简单的托管重写。该架构使用图表来驱动分析和编译。这允许扫描器、优化器、分析器处理、分析、表示正在编译的程序集。这个项目已经进行了 2 年——Crossgen2 编译器的起源始于 2016 年左右的一个研究项目。

展望未来,crossgen2 将给我们提供更多选择,为平台和代码做出更高性能的选择。让我们持续关注。

 

周国庆

2022/3/28