在局部性方面的数组与链接列表

时间:2013-09-28 07:09:28

标签: arrays caching data-structures linked-list localityofreference

假设我们有一个未排序的数组和链表。 搜索两个数据结构的元素时最糟糕的情况是O(n),但我的问题是:

由于在缓存中使用空间局部性,数组是否仍会更快,或者缓存是否会使用分支局部性,从而允许链表与任何数组一样快?

我对数组的理解是,如果访问一个元素,那么该存储器块和许多周围的块将被带入高速缓存,从而允许更快的存储器访问。

我对链表的理解是,由于遍历列表的路径是可预测的,因此缓存将利用它并仍然存储适当的内存块,即使列表的节点可能相距很远在堆内。

1 个答案:

答案 0 :(得分:12)

您对阵列案例的理解大多是正确的。如果按顺序访问数组,许多处理器不仅会获取包含该元素的块,还会预取后续块以最小化等待缓存未命中所花费的周期。如果您使用的是英特尔x86处理器,则可以在英特尔x86优化manual中找到有关此内容的详细信息。此外,如果数组元素足够小,则加载包含元素的块意味着下一个元素可能位于同一个块中。

不幸的是,对于链表,从处理器的角度来看,加载模式是不可预测的。它不知道在地址X加载一个元素时,下一个地址是(X + 8)的内容。

作为一个具体示例,顺序数组访问的加载地址序列很好且可预测。 例如,1000,1016,1032,1064等

对于链表,它将如下所示: 1000,3048,5040,7888等很难预测下一个地址。