【问题标题】:which is faster, a single array of object, or multiple array of data attributes? [closed]单个对象数组或多个数据属性数组哪个更快? [关闭]
【发布时间】:2014-03-04 10:28:18
【问题描述】:

这是一个简化的例子。请注意,我选择了简单类型,但在应用程序中我可能有更多属性

struct object
{
    float a, b;
    int c;
};
vector<object> objects;

vector<float> a, b;
vector<int> c;

在您至少访问每个属性一次的游戏应用程序中,性能可能会有所不同。无论如何,游戏循环都会贯穿整个索引。

我知道第一个示例更方便(使用单个结构组织代码要容易得多)并且它可能取决于应用程序的实际操作,但第二个示例不是对缓存更友好吗?

我知道一开始使用 Knuth 过早优化的东西不是制作应用程序的正确方法,但我想知道...我在 gamedev 幻灯片中读过一次,我想知道是否是真是假,为什么。

【问题讨论】:

  • 我认为确定您的具体情况的唯一方法是针对您的具体情况进行测试。
  • 第二个在只访问每个对象的一个​​(或多个)成员的循环中对缓存更友好。如果“您至少访问每个属性一次”,那么第一个可能更有效,也更方便。

标签: c++ arrays performance


【解决方案1】:

“视情况而定!”

真的,对于所有问题,不仅一个最佳数据分布,否则编译器和编程语言将围绕它构建。

这取决于大部分时间花在计算上的算法。

因此,结构数组对缓存更友好/对页面未命中更友好; struct-of-arrays 更适合 SSE/AVX SIMD 优化,具有更好的内存通道利用率(例如 CUDA)。

我的首选方法是开始使用对象数组,并且只使用接口(getter/setter)。比尝试优化使对象成为底层数组的接口,以防我有证据表明我错过了一些重要的分析优化。

记住...“早期优化对所有编程都是有害的”;)

【讨论】:

  • +1 表示“早期优化是邪恶的......”
【解决方案2】:

在我看来,最好只有一个类对象向量而不是其数据成员的三个向量。在最后一种情况下,所有操作都重复了三遍,包括内存分配/释放。

Mpreover 在最后一种情况下存在逻辑不一致,因为这三个向量没有与对象连接。您将无法找到包含这些属性的对象。

【讨论】:

  • 问题是我的访问模式可能非常复杂,它包括物理,库中的其他对象,所以我可能不会只访问这些东西一次,我可能会访问它们来计算平均值,或者访问附近物理对象。例如,在 box2d 中,fixture 和 body 似乎是以不同的方式分配的,而 fixture 实际上属于一个 body
【解决方案3】:

由于数据局部性和缓存更友好,一个对象向量可能会表现得更好,但最好通过实际分析您的使用场景来确定,这尤其取决于您的访问模式。

【讨论】:

    【解决方案4】:

    如果 a、b、c 是相关的并且可能会一起读取,则结构对缓存更友好。

    但是将所有相同的数据类型按顺序放在内存中的打包具有可能是(自动)矢量化的优点。

    无论如何,一些需要深入研究的相关问题是:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-12
      • 2021-02-19
      • 2019-09-09
      相关资源
      最近更新 更多