dte*_*ech 8 oop performance caching memory-efficient data-oriented-design
在常规的面向对象实践中,并不是罕见的对象具有多个不相关的成员属性.当物体被处理时,在不同的通道中进行处理并不罕见,这些通道针对其属性的不同部分.
在这方面,创建对象集合的典型方法似乎不是非常有效的方法.考虑到计算机访问内存的方式和缓存行的平均大小,很有可能缓存内存正在填充不需要的内容,但恰好是相邻的,因此最终浪费缓存容量并增加停顿和执行的延迟.
更糟糕的是使用多态和动态分配对象的做法,没有内存池和自定义分配器.在这种情况下,不仅缓存会被不需要的数据填充,而且由于动态内存分配使用的任意地址,预取程序也无法正常工作.
拯救是回到OOP之前的时间并选择数据导向,这似乎是开发性能关键应用程序,操作系统等的首选.但为什么不使用两者的混合版本呢?排序的数据面向对象的编程?
在那么久的提议之后,让我们来看看手头的问题.我没有足够大的项目来测试这个概念的效率,所以社区的理论专业知识非常受欢迎.
如果不是存储自己的数据成员的对象,它们只存储对集合的引用,其数据成员按顺序存储在它们自己的容器中,并且它们的成员方法从这些容器返回数据,这样就不需要数据结束的几率应该减少在前往CPU的路上,并且增加近期"未来"所需的数据几率.逻辑假设是这种方法将提高预取器效率,缓存命中率和使用效率,并且还将减少自动和手动并行化中涉及的延迟.
你怎么看?
后期编辑:如果我们考虑结构和类填充,应用"数据方向模式"可能会更有利,如果"模型"有一个char和一个int数据成员,以OOP方式它将被填充,这只会污染进一步缓存,但是面向数据的存储模式可以顺序存储所有chars和所有ints,没有空间和缓存浪费.
首先,漂亮的幻灯片演示。嗯,据我所知,你的问题与演示方法有很大不同。变量甚至对象属性都随机存储在主存中。如果您尝试将内存分配给连续的数据结构,则数据结构的大小将受到主内存中最大的“气泡”的限制,否则它不会是纯粹连续的。也许你有这样的想法:
class MyClass
{
public:
MyClass()
{
m_dataMembers = new GenericObject[DATA_MEMBERS_AMOUNT];
//initialize array values...
}
int getMyVar()
{
return (int)m_dataMembers[MY_VAR_INDEX];
}
//others functions...
private:
GenericObject* m_dataMembers;
}
Run Code Online (Sandbox Code Playgroud)
这样,你就会遇到一些问题。首先,您需要一个通用对象类来存储任何类型的变量。然后,您需要知道每个变量在数据结构中的位置,然后您需要知道数据结构中每个变量的类型,以便在 getter 中正确转换。他在演示中实际做的是使用引用减少类大小,使其更好地适合缓存页面,并减少缓存而不是主内存的使用。我希望我没有误解你。