考虑以下组件:
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并使用更多的组件来实现相同的结果,或者是否存在不适合它的情况?