数据对齐与缓存局部性

时间:2012-12-27 14:41:39

标签: java android caching memory-access

从内存中,数据只能以体系结构的自然字大小读取。例如,在32位系统上,以4字节块的形式从内存中读取数据。如果将2字节或1字节的值添加到存储器,则它们的读取仍然需要访问4字节字。 (如果是2字节值,则可能需要两次4字节访问,如果该值存储在字边界上。)

因此,当需要访问单个单词时,访问单个值是最快的,并且需要最少的额外工作(例如屏蔽)。如果我是正确的,这就是虚拟机(例如 JVM Android的Dalvik )在Object个实例中的4字节边界中布置成员变量的原因

另一个概念是缓存友好性,即位置(例如L1,L2)。如果必须在彼此之后直接遍历/处理许多值,则将它们彼此靠近地存储(理想地,在连续的块中)是有益的。这是空间局部性。如果这是不可能的,那么至少对相同值的操作应该在相同的时间段内完成(时间局部性 - 即,当对其执行操作时,该值很可能保留在高速缓存中)。

据我所知,上述两个概念在某些情况下可能是“矛盾的”,它们之间的选择取决于它们的使用场景。例如,较少量的连续数据比较大量(平凡)更容易缓存,但如果某些数据通常需要随机访问,则字对齐(但更大)的结构可能是有益的 - 除非整个结构适合缓存。因此,我认为局部性(〜数组)或对齐优势是否应该首选取决于如何操纵值

有一个场景对我很有意思:让我们假设一个路径寻找算法,它接收输入图形(其他辅助结构)作为数组。 (它的大多数输入数组都存储值<= 32767。)

路径寻找算法在阵列上执行非常多的随机访问(在几个循环中)。从这个意义上讲,输入数据(在Android / ARM上)可能需要int[],因为访问时这些值将位于字边界上。 (另一方面,如果需要顺序遍历,那么建议使用较小的数据类型 - 特别是对于大型数组 - 因为缓存友好性的概率较高。)

但是,如果(随机访问的)输入数据如果指定为short[]则适合L1 / L2,但如果指定为int[]则不适合该怎么办?在这种情况下,int[]的{​​{1}}的{​​{1}}的4字节对齐优势是否超过short[]的缓存友好性?

当然,在一个具体的应用中,我会进行测量以进行比较。然而,这并不一定能回答上述问题。

1 个答案:

答案 0 :(得分:0)

如果你可以确保转向短线导致更好的地方(也就是所有东西都在缓存中),这会超过对齐惩罚。

访问缓存是低纳米<10ns,访问ram是60-80ns