performance - 面向对象,数据方向,缓存污染和缓存明显性

标签 performance oop caching memory-efficient data-oriented-design

在常规的面向对象的实践中,稀有对象并不是具有多个不相关的成员属性。而且,在处理对象时,通常会针对对象属性的不同部分进行不同的遍历。

在这方面,创建对象集合的典型方法似乎不是一种非常有效的方法。考虑到计算机访问内存的方式以及缓存行的平均大小,很有可能缓存中的缓存已被不需要的东西填满,而只是碰巧是相邻的,因此最终浪费了缓存的容量并增加了停顿和执行延迟。

更糟糕的是使用多态并动态分配对象而没有内存池和自定义分配器的做法。在这种情况下,不仅高速缓存中会填充不需要的数据,而且由于动态内存分配使用了任意地址,因此预取器也无法正常工作。

挽救工作要回到OOP之前的时间,并选择数据定向,这似乎是对性能至关重要的应用程序,操作系统等的开发的优先选择。但是,为什么不使用两者的混合版本呢?排序面向数据的对象编程吗?

经过漫长的序曲,让我们谈谈眼前的问题。我没有足够大的项目来测试此概念的效率,因此非常欢迎社区的理论知识。

而不是对象而不是存储自己的数据成员的对象,它们仅存储对集合的引用,在该集合中,其数据成员按顺序存储在其自己的容器中,并且它们的成员方法从这些容器返回数据,这样不需要数据结束的几率减少其进入CPU的速度,并增加近乎“ future ”所需的数据几率。合理的假设是,这种方法将提高预取器效率,缓存命中率和使用效率,还将减少自动和手动并行化所涉及的延迟。

你怎么看?

后期编辑:如果考虑结构和类填充,则应用“数据定向模式”会更加有益,如果“模型”具有charint数据成员,则将以OOP方式对其进行填充,这将只会进一步污染高速缓存,但是面向数据的存储模式可以按顺序存储所有char和所有int,而不会浪费空间和缓存。

最佳答案

首先,漂亮的幻灯片演示。嗯,据我所知,您的问题与陈述方式大不相同。变量被随机存储在主存储器中,甚至是对象属性。如果您尝试将内存分配给连续的数据结构,则您的数据结构的大小将受到主内存中最大的“气泡”的限制,否则它将不会纯粹是连续的。也许您认为是这样的:

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;
}

这样,您将遇到一些问题。首先,您将需要一个通用对象类来存储任何类型的变量。然后,您将需要知道每个变量在数据结构中的位置,然后您将需要知道数据结构中每个变量的类型,以便在getter中正确转换。他在演示文稿中实际要做的是使用引用减少类的大小,以使其更适合于缓存页面,并减少缓存(而不是主内存)的使用。我希望我没有误会你。

关于performance - 面向对象,数据方向,缓存污染和缓存明显性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12365527/

相关文章:

windows - 有没有办法强制Windows缓存文件?

ruby - 在 Sinatra 中缓存响应的最佳方式?

windows - 从 Windows CLI 刷新磁盘写入缓存

c - 哪个能够容纳 1 亿条记录的嵌入式数据库具有高效的 C 或 C++ API

javascript - ES6 object.method 不是函数

java - 在for循环条件下重复调用getter

java - 如何在Java中为不同的对象创建单独的列表?

Javascript:访问高阶函数中的对象范围成员

c - 使用通用案例进行开关改进

c - 使用另一个编译器更快的代码