1.前言
前面一篇(分层编译)讲了它的一个原理,分层编译的两个指标,函数编译的时间以及函数调用的次数,该如何设置呢?本篇来看下。
2.详述
之前有了解过.NET7里面的全局程序集设置给普通方法设置分层编译
[assembly: Debuggable( DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
这个特性在.NET8里面依然适用。原文:.NET普通方法开启分层编译
本篇主要看下,函数编译时间
tieredCompilation_CallCountingDelayMs环境变量,它是以毫秒ms为单位。
以及函数调用次数:
TieredCompilation_CallCountThreshold环境变量,它的值是十六进制(0xXX)。
在.NET8里面只要程序集有
DebuggingModes.IgnoreSymbolStoreSequencePoints
这个标志,并且有一个函数编译的时间超过了的
tieredCompilation_CallCountingDelayMs环境变量的值,那么这个函数以及之前的所有被调用的函数都会进入到分层编译队列(之前的.NET版本是只有这个超时的函数才会进入分层编译队列),然后判断它的调用次数是否超过了
TieredCompilation_CallCountThreshold环境变量的值,如果超过了则进行分层编译。
函数以及之前的所有被调用的函数都会进入到分层编译队列,这句话怎么理解呢?下面简单例子:
[assembly: Debuggable( DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
static void ABC(){
}
static void DEF()
{
}
static void Main(string[] args){
ABC();
DEF();
Console.ReadLine();
ABC();
}
}
如果不设置tieredCompilation_CallCountingDelayMs环境变量值,它默认是1ms,Console.ReadLine()这个系统级调用超过了1ms。这个函数(Console.ReadLine())以及之前调用的方法如示例里面的ABC函数,DEF函数都会进入到分层编译队列。
3.设置
如何设置这两个环境变量呢?
一般来说,通过dotnet命令来运行托管DLL之前,可以设置它,比如如下:
Windows CMD:
set DOTNET_TieredCompilation_CallCountingDelayMs=10ms
set DOTNET_TieredCompilation_CallCountThreshold=0xA
dotnet xxx.dll
编译当前托管dll(xxx.dll)程序集里面带有
IgnoreSymbolStoreSequencePoints标志的的托管函数,如果有一个函数编译时间超过10ms,那么这个函数之前的所有函数都会进入到分层队列,如果分层队列里面的有函数调用次数超过0xA次,就会进行分层编译。