哪个更快,单个对象数组或多个数据属性数组

which is faster, a single array of object, or multiple array of data attributes?

本文关键字:数组 数据属性 对象 单个      更新时间:2023-10-16

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

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

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

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

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

我知道这不是一开始使用 Knuth 过早优化来制作应用程序的正确方法,但我只是想知道......我曾经在游戏开发幻灯片中读过这篇文章,我想知道它是否属实,以及为什么。

"视情况而定!"

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

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

因此,结构数组对缓存更友好/页面错误友好;数组结构更适合 SSE/AVX SIMD 优化,具有更好的内存通道利用率(例如,CUDA 很明显)。

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

并记住..."早期优化是所有编程的邪恶" ;)

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

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

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

  • 哪个缓存最友好?
  • 数组的结构和结构数组 - 性能差异
  • 结构内存中的布局。 C/C++ 中的数组结构和结构数组
  • cuda 中的数组结构与结构数组

在我看来,只有一个类对象的向量比它的三个数据成员向量更好。在最后一种情况下,所有操作都会重复三次,包括内存分配/释放。

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

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