GDC2018 Job System and Entity Component System的笔记

# brief
- 粗看感觉没啥,就是个普通的多线程job system
- 但是没想到的是还讲了一堆unity提供的collection、temp storage
- 还提到了ECS,原来ECS就是为了data oriented

# feature
- job之间有dependency,submitt的顺序不一定是执行顺序,有依赖项。可是这个到底有啥用呢?
- c#部分有对应的接口
- 提供了一堆collection(C#用)

# 基本概念
- 不spawn很多thread,基本上每个核一个thread,而且PC上可能还要空个核出来

# race conditions
- 为了处理这个问题:only allow job to reference copied data or 读写被控制的buffer(NativeContainer)(不能同时写、写时不能都)。可是这个是怎么做到的呢?

# NativeContainer
- unmanaged allocation of memory,需要自己Dispose
- 很难搞对,所以加了一堆检查措施(DisposeSentinal检查leak、AtomicSafetyHandle用来transfer ownership)
- 似乎连[]都被特殊处理了,因为提到了reference,有坑,[]返回的时值,不是reference
- allocation type。。。allocator?
- 一堆unity.collections,啥都有hashmap、queue、concurrent version
- 想不到这些container都是纯C#的,所以你也可以自己写container

# 传递的数据
- struct,继承IJob或IJobParallelFor
- native conatiner都是值类型,所以也是直接包含在struct里
# particle的例子
- 要干的事情
- loop1:reinitialize if too old
- loop2:update position、color
- loop3:render list
- schedule as early as we can,wait for as late as we can
- Emitter拿的时NativeSlice,只是去访问需要emit的particle
- 可以对struct里的数据加[ReadOnly] tag,不知道对于实际machine code啥影响
- schedule job的时候可以控制parallelfor的batchsize,就是实际一个job做多少子任务。可以用handle来等待job执行完,等待的线程也可以去帮忙

# Integration with other systems
- 不知道为啥要想访问Transofrm的话需要特殊类型的IJob核TransformAccessArray,大概是因为Transform是引用?

# performance observation #2:
- C#编译器有时候不会生成最有代码,所以他们自己有个编译器burst,在另外一个talk(Unity From C# to Machine Code),看数据有巨大优化,说是就是给struct加了attribute,感觉不可能啊?妈的2.29ms vs 0.43ms(看了下后面的ECS部分的代码,感觉可能是因为用了struct后都是value type了,所以有些写法就变得十分诡异了(比如给struct的一部分做修改,需要新建一个、改完了然后重新赋值回去)

# entity component system
- enittiy is a handle for a collection of componnets, has no data of its own
- IComponentData contains only data
- System operato on sets of components
- 这个的意义是:假设一个entity最多有X种component,那就是有2**X种组合,此时就会最多有2**X个system来分着遍历所有的entity,entity会被加到不同的组种

# ECS的particle例子
- [Injection]感觉是不是就是特殊用来标记System种使用到的数据的,因为System按说不应该有数据,所以要特殊处理
- 拆了很多component,就是为了保证每个system只去只访问需要的数据,不会对不需要访问的数据产生dependency

# JobComponentSystem
- allow to schedule job with component access
- 更重要的是自动track dependencies based on data access.要是还依赖其他东西就要自己track了
- advice
- place all data in components
- 可以用empty component做tracking(for what?)

# ParticleEmitterSystem的JobComponentSystem例子
- 自己有dependency
- 自己schedule job后也会有个handle
- barrier,commandbuffer用来在delay一些执行到某些事件后,比如在这一阵结束后再更新entity的position。这个commandbuffer就是queue一些操作感觉
- 用attribute来空只system在谁之前、在谁之后update

# Memory layout
- archtype,就是component的组合

# Moving from GameObject to ECS
- 用个什么GameObjectEntityComponent后就对system可见了,后面慢慢改(用IComponentData)

# 打脸(QA)环节
- Q:对于system要过的component,有没有更复杂的可配置
- A:可以button off一些
- Q:一个system是否可以处理不同的2组component
- A:可以,可以获得2个list(这个API是啥样的?)
- Q:Job ECS这套所有平台都行么
- A:winRT、webgl外应该都行。那个burst只work in editor。ECS那套都行
- Q: Component不能access manage objects?
- 这个就是说Component这一套就是想DOD,所以只能是value type
- 目前不行,working on it。
- 这么看来那个burst是要编译所有Component相关的代码
- 结束的时候台下有笑声!
- Q:不是说threads的数量和core的数量要一样嘛?有没有设置affinity,有没有专门对平台处理,比如x86
- A:俺不记得专门处理过,我回头double check下
- Q:你有没有好好profile context switch
- 我没。之前的proejct大家都说这个,所以我就没测了
- Q:我咋把jobsystem里算的数据用到rendering上(output of jobssystem used by rendering operations),要卜要加barrier啥的或者commandqueue来保证rendering operation被hold到我的job结束。或者把jobssystem里的数据作为material的property啥的(没太听懂)
- A:说了一大堆,什么meshinsntance,什么实在main thread上rendering啥的。乃就是说要在mainthread上等相关的job结束后然后从mainthread去进行rendering
- Q: 可以从jobsystem调rendering嘛?
- A:现在你没法从job里掉任何unity API
- Q:不同的system可以modify同一个component,怎么同步
- A:(以为是从不同的job,或许其实是一回事)用command buffer。最近没看那块代码,所以我也不记得了。我不晓得,到底是最后modified win还是error
- Q:设计的时候考虑过fiber没
- A:我觉得fiber是想workaround a foundimentally broken design
- Q:debugging support, graph visualization啥的
- A: working on it.还没release计划
- Q:logging在main或job里有区别吗?
- A:我得check,我觉得在job里log就是在job里log,但是要check

# 没想通的问题
- system怎么创建怎么注册?
- 对于一个entity可能有很多component的情况,会不会导致有无数多system,反而降低速度?
- 如何把entity注册到若干system上?手工?自动?

# related
- Unity: from C# to Machine Code

猜你喜欢

转载自blog.csdn.net/killer4747/article/details/80738518
今日推荐