【发布时间】:2012-09-04 03:16:36
【问题描述】:
在常规的面向对象实践中,很少有对象具有多个不相关的成员属性。并且在处理对象时,经常会在不同的通道中完成,这些通道针对其属性的不同部分。
在这方面,创建对象集合的典型方法似乎不是一种非常有效的方法。考虑到计算机访问内存的方式和高速缓存行的平均大小,高速缓存很有可能会被不需要的内存填满,而只是碰巧相邻,因此最终会浪费缓存的容量并增加停顿和执行延迟。
更糟糕的是使用多态性和动态分配对象的做法,没有内存池和自定义分配器。在这种情况下,不仅缓存中充满了不需要的数据,而且由于动态内存分配使用的任意地址,预取器也无法充分工作。
拯救是回到 OOP 之前的时代并选择面向数据,这似乎是开发性能关键应用程序、操作系统等的偏好选择。但是为什么不使用两者的混合版本呢? 面向数据的对象编程?
在漫长的序曲之后,让我们开始讨论手头的问题。我没有足够庞大的项目来测试这个概念的效率,因此非常欢迎社区的理论专业知识。
如果对象不存储自己的数据成员,它们只存储对集合的引用,它们的数据成员按顺序存储在自己的容器中,并且它们的成员方法从这些容器中返回数据,这样的可能性应该减少最终到达 CPU 的不需要的数据,并增加在不久的“未来”需要的数据的几率。合乎逻辑的假设是,这种方法将提高预取器效率、缓存命中率和使用效率,还将减少延迟,涉及自动和手动并行化。
你怎么看?
后期编辑:如果我们以 OOP 方式考虑结构和类填充,如果“模型”具有 char 和 int 数据成员,则应用“数据导向模式”可能会更有益它将被填充,只会进一步污染缓存,但是面向数据的存储模式可以顺序存储所有chars和所有ints,完全没有空间和缓存浪费。
【问题讨论】:
-
@ArjunShankar - 感谢您的链接,看来性能改进比我预期的还要重要。令人惊讶的是,在我浏览过的几种编程材料中,我从未听到有人谈论过这个主题......
-
我知道这是“结构数组”与“数组结构”的区别。如果你用谷歌搜索这两个术语,你会得到相当多的材料。
-
很好的问题,我也注意到这个主题缺乏材料。
-
其实我越想越喜欢这个概念。我即将开始在一个高性能项目中重构一些基于 OOP 的 C++ 代码,我想我会尝试这个想法。希望我能在几个月后发布一些结果。
标签: performance oop caching memory-efficient data-oriented-design