UH4L16——寄存器模式

本章代码关键字

1
2
3
4
5
6
7
ILRuntimeJITFlags                    //ILRuntime的即时编译(JIT)模式
ILRuntimeJITFlags.None //不启用寄存器模式
ILRuntimeJITFlags.JITOnDemand //按需即时编译(JIT)模式,全局开启时,一般只会使用该模式
ILRuntimeJITFlags.JITImmediately //立即JIT模式
ILRuntimeJITFlags.NoJIT //禁用JIT模式
ILRuntimeJITFlags.ForceInline //强制内联模式,该模式只对方法的Attribute生效
[ILRuntimeJIT()] //对类和方法使用,指定为某个类或者方法开启寄存器模式

寄存器模式

寄存器模式是 ILRuntime2.0 版引入的专用于优化大规模数值计算的执行模式
该模式通过 ILRuntime 自己的 编译器以及指令集(JIT Compiler) 将原始DLL的 微软中间语言(MSIL) 指令集
转换成一个自定义的基于寄存器的指令集,再进行解释执行

在ILRuntime中使用寄存器模式可以有效的提高性能,主要有以下特点:

  1. 数值计算性能会大幅提升,包括 for​ 循环等需要数值计算的控制流
  2. 属性的调用开销,for​ 循环里调用其他热更内方法的性能会有所提升

注意:如果一个方法即没有数值计算,也没有频繁调用热更内的的方法或者访问属性,
只是调用系统或UnityAPI,那么不会产生任何优化,甚至一些情况下性能还会低于传统模式

开启寄存器模式

全局开启

在初始化 appDomain​ 时 调用其有参构造new AppDomain(ILRuntimeJITFlags.JITOnDemand)
ILRuntimeJITFlags​代表ILRuntime的 即时编译(JIT)模式

  • None​:不启用寄存器模式
  • JITOnDemand​:按需即时编译(JIT)模式,
    使用该模式在默认的情况下会按照原始的方式运行,当该方法被反复执行时,会被标记为需要被JIT,
    并在后台线程完成JIT编译后切换到寄存器模式运行
  • JITImmediately​(全局开启时不推荐):立即JIT模式,
    使用该模式时,当方法被调用的瞬间即会被执行JIT编译,在第一次执行时即使用寄存器模式运行。
    JIT会在当前线程发生,因此如果方法过于复杂在第一次执行时可能会有较大的初始化时间
  • NoJIT​: 禁用JIT模式,该方法在执行时会始终以传统方式执行
  • ForceInline​(全局开启时不使用):强制内联模式,该模式只对方法的Attribute​生效,
    标注该模式的方法在被调用时将会无视方法体内容大小,强制被内联
1
2
3
4
5
6
7
8
9
10
public void StartILRuntime(UnityAction callBack = null)
{
if (!isStart)
{
//如果开启全局寄存器模式,则一般只使用JITOnDemand,而不会使用其他模式
appDomain = new AppDomain(ILRuntimeJITFlags.JITOnDemand);
StartCoroutine(LoadHotUpdateInfo(callBack));
isStart = true;
}
}

指定开启寄存器

在指定的类和方法前加上 [ILRuntimeJIT(寄存器模式)]​ 特性,自己指定那些类或方法将使用 哪种 寄存器模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[ILRuntimeJIT(ILRuntimeJITFlags.JITImmediately)]
internal class Lesson20_Test
{
public void Test1()
{
//假设该方法全是数值计算相关
}

[ILRuntimeJIT(ILRuntimeJITFlags.NoJIT)]
public void Test2()
{
//假设该方法只有API调用而无数值计算,因此需要特别关闭寄存器模式
}

[ILRuntimeJIT(ILRuntimeJITFlags.JITImmediately)]
public void Test3()
{
//假设这个类会在别的类里面调用
}
}

注意:在热更工程中使用该特性,我们需要引用ILRuntime库
可以在项目工程文件中找到 Library\ScriptAssemblies\ILRuntime.dll 进行引用(将复制本地设置为false​,避免生成时导出)

imageimage

寄存器模式使用建议

推荐使用2种模式:

  1. 在初始化AppDomain​时,将寄存器模式指定为 JITOnDemand​(按需即时编译(JIT)模式)
    ILRuntime会自己判断运行模式,在大多数情况下能达到不错的性能平衡
  2. 初始化AppDomain​时,不指定寄存器模式,而是通过自己利用[ILRuntimeJIT(寄存器模式)]​特性来指定精准控制想要优化的方法