链接列表,数组和硬件内存缓存

时间:2016-04-02 09:48:45

标签: arrays performance linked-list language-agnostic cpu-cache

虽然之前已经提出了关于链接列表与数组之间的问题,但答案大多归结为我们大多数人可能已经在某些方面学到的东西:

  • 列表善于插入和删除
  • 阵列擅长随机访问

现在像Bjarne Stroustrup这样受人尊敬的人argued,阵列实际上总是优于链表,因为它们更好地利用了现代硬件中实现的缓存架构。他还指出,阵列的性能优势随着它们的大小而增加。

虽然我基本上理解他的论点并同意他,但我想知道当数组的大小明显大于缓存大小时是否仍然如此。我会说,性能真的很重要。

总结一下:在大多数情况下,阵列的性能是否仍然优于列表,即使它们的大小比缓存大小大得多,并且大部分操作都是插入或删除?如果是,如何解释?

1 个答案:

答案 0 :(得分:4)

阵列的表现更好,不仅因为缓存,还因为预取。

缓存有两个主要好处 - 顺序元素可能位于同一行,因此您可以获取一次并多次使用整行(而在链接列表中,您的下一个元素是其他位置,因此您不享受此优势) 。元素变得越大,这个好处就越少,一旦元素超过线条大小,它就会消失。

第二个好处是更微妙 - 您可以更好地利用缓存,因为它的组织方式有利于顺序分配。这意味着高达缓存大小的数组可能仍然适合,而随机分配的列表可能会有一些冲突,即使列表大小小于缓存也会导致颠簸。

然而,除了缓存之外,空间分配结构的更大好处来自预取。大多数CPU会自动预取访问流(例如阵列访问)中的下一行,因此可以消除顺序访问场景中的所有未命中。

另一方面,所有这些好处只是优化,因此它们只能线性地加速性能,但永远不能减少渐近的复杂性差异,例如列表提供的O(1)插入。最后,您需要对代码进行基准测试,以确定是否需要此类案例并创建瓶颈 - 如果是这样,可能需要采用混合方法。