为什么要将 l1, l2, l3 级缓存设计为树形结构

缓存设计为树形结构主要还是为了分层,其根本原因是物理距离决定的。缓存越大,占用面积也就越大,物理距离也就越长。距离越远,速度上也就会越慢。

排队管理调度

DOTS 面向数据的设计部分就是在设计队列的结构,ECS 就是在组织队列中的规则,JobSystem 就是在做队列的调度。

队列类型

单队列

单队列:这样的队列很简单,需要的队伍管理人员也可以很少。但是只要当队列中的任何一个人或者业务人员出现了处理时间较长的问题,造成的阻塞会是整个系统级别的。

多队列

多队列:既然单队列的方式会阻塞,那么我们可能会想使用多队列并行处理不就可以了吗,但是这样的话,需要的服务人员和队列数量也成正比,类比到 CPU 上面也就是对工艺需求会更高一点,而且因为“木桶效应”,当一个队列中某个人处理时间很慢的时候,造成的是我们的系统运行依旧很慢,因此多队列的效率也不高。

处理并行,调度串行的队列

处理并行,调度串行的队列:这种队列与前两者相比,引入了一个调度人员来管理调度(图中的黄色方块)。当某个处理窗口被阻塞时,调度人员会将长队列等待人员安排到其余空闲的窗口。长的单行队列就如 Cache 缓存一样。与多队列并行处理相比,这种队列很适合处理长队列中人员处理时间不均,即将到来的人员处理时间随机的情况。

复合队列

复合队列(单行调度队列加上多行并行队列):这种队列比较适合多阶段批次处理事物的队列,每个批次内每个人处理时间近似的情况。但是如上图,同个批次类每个人处理时间差距比较大的时候,此时调度员的工作复杂度和工作量也大幅上升,造成此队列的效率变低。此时就需要新的处理阶段。

此时我们又增加了一个并行队列和两个调度人员:

  • 调度人员 C:应付即将到来进入队列的调度人员,负责调度人员进入相应类似属性的队列。
  • 调度人员 B:按照并行等待队列中单个队列是否达到人数上限,将此队列中所有人统一调度下一层的单行队列中进行等待。

接下来我们将其类比为机场的处理,到最后处理完队列的后续工作,就是安排人员上摆渡车。虽然我们当前是按相同属性处理完了,但是上摆渡车这个操作有啥离散的,对于整点发车的摆渡车,会造成有时候又超载,有时候又载不满的情况。

我们考虑在进入第一层并行队列的时候,不仅按照属性划分,还按照家庭或旅行团划分队列,这样在进入办理登机手续的时候,第一位成员就可以拿着队列中所有人的证件去一起办理了,座位号也可以选择临近的(只是类比并不一定符合登机常识),也就能一起进入摆渡车了。

回到 CPU 这边,我们上面类比的这个操作,其实就是在把数据组织成矢量,做对齐优化,处理时可以兼容 SIMD 指令。这样一条指令可以处理多条数据,离开时还能保证数据的连续性。

此处可以做一个更大胆的类比:将图中紫色区域类比成 CPU,那么蓝色,绿色和红色分别就是 l1, l2, l3 级缓存,其中的队列就可以类比为 Cache Line 或者是 Archetype Chunk。整个系统组织数据 layout 的过程就可以理解为 ECS。黄色调度员就可以当作不同调度类型下的 job system。而进入到蓝色处理员处理的队列就是相当于 Burst 编译过后支持 SIMD 的代码。

记录此排队管理的调度,可以对 ECS 架构有个更好的了解吧。


参考资料: