ECS和SoA:我们可以简单地摆脱后者吗?

时间:2017-08-11 15:20:58

标签: c++ game-engine software-design

考虑以下组件:

struct Comp {
    Whatever data;
    bool activated;
};

在处理ECS时,我们有一个隐式AoS模型,其中实例以缓存友好的方式打包在一起(希望至少)。

让我们想象一个系统想要遍历Comp的所有实例,并且只有在data为真时才需要阅读activated
在这种情况下,当activated为false时,即使数据从未使用过,数据也会从主内存流式传输到缓存中。 可以通过切换到SoA方法来减轻它。这是一个重新定义Comp的问题:

struct Comp {
    Whatever *data;
    bool *activated;
};

当然,它还需要重构代码的一部分,但是让它继续下去。无论如何,这不是问题的目标 这次所有activated值紧密打包,迭代应该导致Whatever缓存未命中,如果不使用则不会流式传输到缓存。

到目前为止,这么好。简短的简历,但它应该让我知道我在说什么。

我的猜测是,在 ECS方法中,可以将Comp拆分为两个组件:

struct Data {
    Whatever data;
};

struct Activated {
    bool value;
};

然后系统可以迭代所有Activated组件并检查他们的value数据成员,因此仅在需要时才会获得Data。结果是(?)相同 换句话说,据我所知,在处理ECS时,我们可以通过使用多个组件来摆脱SoA。

我可以看到的唯一缺点是,您无法保证Data实际存在并且在具有Activated组件的情况下分配给实体。
好吧,抛开一个可以通过一些断言在调试/开发模式中强制执行约束的事实,SoA也不能保证这一点。
在这两种情况下,工厂方法都可以解决问题,所以谁在乎?

话虽如此,问题是:在基于ECS的方法中,我还有什么其他缺点吗?
我的意思是,实际上可以摆脱SoA并使用更多的组件来实现相同的结果,或者是否存在不适合它的情况?

0 个答案:

没有答案