Unity DOTS Burst 运行分析
Unity版本:Unity 2020.1.0f1
Burst版本:1.39
资料来源:
使用工具:Unity工程文件,IDA pro,X32dbg(这里都使用32位工程)
研究目的:研究Unity在mono和il2cpp环境下如何使用Burst和Burst是否有更多可能的利用.
前言
一直想了解Burst的运行原理,故花了一点时间研究其内部运行过程。
初步了解的情况是,Burst是由LLVM修改的到,LLVM是一个高度自定义的编译器,Unity就是使用LLVM来完成IR到硬编码的转换。
想深入理解可以参考视频:ECS-深入解析Burst Compiler
Burst技术有可能在未来替换il2cpp技术成为Unity跨平台的工具。
问题
研究前问自己几个问题:
- Burst的代码是如何嵌入到Unity工程里的?
- Burst是如何同时适应mono和il2cpp的?
- Burst在Editor展示的代码是否是最终运行时的代码?
开始分析
简单的BurstCompile代码,具体意义见代码:
public class MyBurst2Behavior : MonoBehaviour
{
void Start()
{
var input = new NativeArray<float>(10, Allocator.Persistent);
var output = new NativeArray<float>(1, Allocator.Persistent);
for (int i = 0; i < input.Length; i++)
input[i] = 1.0f * i;
var job = new MyJob
{
Input = input,
Output = output
};
job.Schedule().Complete();
Debug.Log("The result of the sum is: " + output[0]);
input.Dispose();
output.Dispose();
}
// Using BurstCompile to compile a Job with Burst
// Set CompileSynchronously to true to make sure that the method will not be compiled asynchronously
// but on the first schedule
[BurstCompile(CompileSynchronously = true)]
private struct MyJob : IJob
{
[ReadOnly]
public NativeArray<float> Input;
[WriteOnly]
public NativeArray<float> Output;
public void Execute()
{
float result = 0.0f;
for (int i = 0; i < Input.Length; i++)
{
result += Input[i];
}
Output[0] = result;
}
}
}
MyJob.Execute()通过Burst生成的代码如下:
这里是X86_SSE2下面会解释.
将项目发布生成32位il2cpp可执行文件(.exe),这里需要copy pdb文件.
然后用X32dbg调试,不停F9执行,这里会发现一个lib_burst_generated.dll的动态链接库.
这其实就是BurstCompiler真正生成的动态链接库.同时在lib_burst_generated.dll的文件目录下也存在一个lib_burst_generated.txt的解释文件.
内容如下:
Library: lib_burst_generated
–platform=Windows
–backend=burst-llvm-9
–target=X86_SSE2
–dump=Function
–float-precision=Standard
–format=Coff
–compilation-defines=UNITY_2020_1_0
–compilation-defines=UNITY_2020_1
–compilation-defines=UNITY_2020
…
这就解释了上面inspector为什么要显示X86_SSE2用来对比.
##下面就要找到MyJob.Execute()在lib_burst_generated.dll中的具体位置.
- 找到lib_burst_generated.txt中的
--method=Unity.Jobs.IJobExtensions+JobStruct`1[[MyBurst2Behavior+MyJob, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null::Ex