.Net8编译设置的原理剖析(一)

前言

.Net已经来到了.Net8了,此后就着手于.Net8方面的技术研究。本篇看下.Net8三大编译设置的原理。他们的设置究竟是如何让CLR运行达到性能优化的目的呢?比如OSR替换,动态PGO,快速JIT。.

概括

1.编译设置
目前的.Net8里面的编译设置,可分分为三类。其一可以通过Debug或Release目录下的runtimeconfig.json文件进行修改,其二可以通过修改csproj项目文件来配置,其三可以通过当前的环境变量设置来配置。

2.编译细节
csproj项目文件里面设置的,通过MSbuild的微软官方编译器编译之后,其实它的配置项会被放到Debug或Release目录下的runtimeconfig.json文件里面去(关于这点可以自己去尝试下)。所以此处可以三大配置,可以浓缩成两个方面。一个是配置文件,一个环境变量。

3.原理
一:先看配置文件的原理
配置文件这一项,实际是通过宿主文件(hostfxr)加载Debug或Release目录下的配置文件runtimeconfig.json。对这些json进行解析之后,在CLR初始化的时候,传入到CLR里面去,存放在一个指针变量(knobNames/knobValues)里面。

此后在CLR里面加载的时候,会加载所有的需要预加载编译变量,跟这个指针变量进行比对。如果指针变量里面设置的值为true,那么就会启用,如果是false,则关闭。实质上就是一个开关形式的。

二:环境变量
关于环境变量这点,非常简单。在Windows上面它直接通过windows API GetEnvironmentVariableW获取到当前的环境变量以及其值。然后根据传进来的值进行一个设置,本身也是开关形式的。一开一合。

4.OSR
OSR堆栈替换,实际上就是快速JIT(DOTNET_TC_QuickJit)是个比较酷的功能。当一个方法循环超过0x3E8次的时候,就会开启OSR。主要是这个方法进行一个高度优化,让其循环以及之后的运行更为迅速。注意这个功能在Relase里面才开启,在Debug下面则是直接给屏蔽了。

5.其余比如R2R,动静态PGO,分层,边界检查等等以及它这些编译变量传递进去之后,是如何运作操控CLR运行的下篇看看。