Unity 2018 之 Jos System and ECS的研究
关于Jos System and ECS:我们重新构建了unity的核心代码,可以很轻松利用当前多核处理器的性能。这一切要归功于:the new C# Job System,The Entity Component System and The Burst compiler。
job system
job system 只能处理一些基本类型的操作在多线程上面,主要实现原理是直接暴露使用Native C++ Job System。在每个job中不能去访问静态变量。
在使用Job system的时候,我们可以使用的接口有:IJob,IJobParallelFor,IJobParalleForTransform.
那么IJob:是只能处理一个任务,也只会在一个worker thread上去执行。
IJobParallelFor:会把你的一个复杂的任务拆分到多个worker thread上去执行。
IJobParalleForTransform:这个主要是对transform组件进行优化,经过测试,我把100000个cube进行移动,如果使用普通的移动方式,需要消耗40多毫秒,但是改为使用IJobParalleForTransform的方式,一般在13毫秒左右。性能的提示还是很多的。
描述:
1.job system 可以想象为一个Task,多线程执行的方法,在干掉多线程资源竞争的方式是复制一份主线程的数据到job中处理。由于是复制数据,那么这些数据只能是.Net 下的基本数据类型。也就是非引用类型,要求使用值类型的数据。
2.上面这种复制数据到job中处理的缺点就是:在一个job中多个copy的值都是相对独立的。所有需要使用一种类型可以共享数据的内存块,他叫NativeContainer.这也是唯一可以从job中把数据传入到主线程中
3.NativeContainer是一种托管类型,他其实是包含一个指针到非托管区的内存。当使用job处理任务时,这种类型的数据块是可以被主线程和工作线程共享的。
当然也要注意:当多个job共享一块NativeArray时,他们都是可读写的,这时需要job按照规定的顺序执行。如果这些job只是读取NativeArray,那么一定要在job中的NativeArray 数据加上特性[ReadOnly],这样可以优化性能。
[ReadOnly]
public NativeArray<Vector3> m_inPos;
在分配NativeContainer时可以指定分配内存方式
Allocator.Temp:最快的分配方案,在一帧或者两帧就分配好空间。但是在使用完成后要立即调用Dispose;
Allocator.TempJob:比较快的分配,一般在4帧左右,是线程安全的,在使用完成后调用Dispose;大多小job都使用这种分配方式。
NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);
Allocator.Persistent:最慢的分配方式,但是这种分配可以持续很久,长任务job可以使用他,在要快速操作的情况下不建议使用。
new NativeArray<Vector3>(t_count, Allocator.Persistent);
在引入了using Unity.Collections;,还可以使用多种类型
using Unity.Jobs;
using Unity.Collections;
// using Unity.Entities;
namespace Assets.Scripts.UseJob
{
public struct testStruct : IJob
{
NativeList<int> m_theList;
NativeHashMap<int, float> m_hashmap;
NativeMultiHashMap<int, NativeList<int>> m_mult;
NativeQueue<int> m_queue;
public void Execute()
{
}
}
}
//
4.创建jobs
在编写结构时,