java - 数据对齐与缓存局部性

标签 java android caching memory-access

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

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

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

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

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

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

但是,如果(随机访问的)输入数据指定为 short[] 适合 L1/L2 会怎样? ,但如果指定为 int[] 则不适合?在这种情况下, int[] 的 4 字节对齐是否有优势?对于随机访问来说,short[] 的缓存友好性胜过它。 ?

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

最佳答案

如果您可以确保转向短会导致显着更好的局部性(即所有内容都在缓存中),那么这将超过对齐损失。

访问缓存的时间为低纳秒 <10ns,访问 RAM 的时间为 60-80ns

关于java - 数据对齐与缓存局部性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14056437/

相关文章:

java - 在Hibernate4中配置查询缓存

php - WordPress - PHP 警告无法打开流 : No such file or directory (advanced-cache. php)

java - toast 未显示

java - vertx-web 路由处理程序是单例还是每次都会实例化一个新的?

android - IllegalStateException:RecyclerView 正在计算布局或滚动时无法调用此方法

android - 给 cardview 充气时出错

android - 有什么方法可以提高 BitmapFactory.decodeStream() 的速度?

java - 找不到元素 "context:property-placeholder"的声明

java - 我想在我的 Android 应用程序中使用大整数,但是当我应用运算符时我会收到错误?

java - 重用缓存的实例