结构数组总是比数组的结构更快?

时间:2012-10-30 15:55:59

标签: java c performance caching data-structures

我想知道数据布局Structs of Arrays SoA )是否总是比Array of Structs AoS )或{{1}更快}( AoP )表示输入问题只适合Array of Pointers中编程的RAM

前几天我正在改进分子动力学算法(在C中)的性能,总结在这个算法中,它计算了粒子之间基于力和位置的力相互作用。

原始粒子由包含9个不同双精度的结构表示,3表示粒子力(Fx,Fy,Fz),3表示位置,3表示速度。该算法有一个数组,其中包含指向所有粒子的指针( AoP )。我决定将布局从 AoP 更改为 SoA 以改善缓存使用。

所以,现在我有一个带有9个数组的结构,其中每个数组存储每个粒子的力,速度和位置(x,y,z)。每个粒子都由它自己的数组索引访问。

我的性能提升(仅适用于RAM的输入)大约 1.9x ,因此我想知道是否通常会从 AoP AoS SoA 它总是会表现得更好,如果不是哪种类型的算法就不会出现这种情况。

2 个答案:

答案 0 :(得分:6)

很大程度上取决于所有领域的有用性。如果你有一个数据结构,其中使用一个字段意味着你可能会使用所有这些字段,那么一个struct数组会更有效,因为它可以将你可能需要的所有内容保存在一起。

假设您有时间序列数据,您只需要选择一小部分可能的字段。您可能拥有关于某个事件或时间点的各种数据,但您只需要说3-5个。在这种情况下,数组的结构更有效,因为a)你不需要缓存你不使用的字段b)你经常按顺序访问值,即缓存一个字段,它的下一个值和下一个值是有用的。 / p>

出于这个原因,时间序列信息通常存储为列的集合。

答案 1 :(得分:2)

这取决于您访问数据的准确程度。 试着想象一下,当你访问数据时,在SoA或AoS中,硬件究竟会发生什么。

要推断您的问题,您必须考虑以下事项 -

  1. 如果没有缓存,性能应该相同,假设数据的所有元素的内存访问延迟相等。
  2. 现在使用缓存,如果您访问连续的地址位置,肯定会获得性能提升。这在您的情况下完全有效。当你有AoS时,内存中的位置不连续,所以你必须在那里失去一些性能。
  3. 您必须访问for for循环您的数据,例如for(int i=0;i<1000000;i++) Fx[i] = 0。因此,如果数据量很大,您将很容易看到小的性能优势。如果你的数据很小,那就不重要了。
  4. 最后,您还不了解您正在使用的DRAM。访问连续数据时,它会带来一些好处。例如,要理解为什么你可以参考wiki