缓存数组的局部性和摊销的复杂性

时间:2015-08-08 06:20:29

标签: arrays caching memory linked-list

数组的访问速度通常比链表更快。 这主要是由于数组的缓存局部性。 我有两个疑问:

  1. 带入缓存的数据量取决于什么因素?它完全等于系统的缓存吗?我们怎么知道这是多少内存?
  2. 第一次访问数组通常比较昂贵,因为必须在内存中搜索数组并将其引入内存。后续操作比较快。我们如何计算访问操作的摊销复杂性?
  3. 什么是缓存未命中?是否(参考链表)所需的项目(当前指针 - >下一个)尚未加载到高速缓冲存储器中,因此必须再次搜索存储器的地址?

1 个答案:

答案 0 :(得分:0)

实际上,它比你在问题中提出的简单模型更复杂。

首先,您可能有多个缓存层(L1,L2,L3),每个缓存层都具有不同的特征。特别是,每个缓存的替换策略可以使用不同的算法作为效率和复杂性(即成本)之间的权衡。

然后,所有现代操作系统都实现了虚拟内存机制。仅缓存数据和指令(这是L1..L3的用途)是不够的,还需要缓存虚拟和物理地址之间的关联(在TLB,事务旁视缓冲区中)。

要了解地方的影响,您需要考虑所有这些机制。

问题1

内存和缓存之间交换的最小单位是缓存行。通常,它是64字节(但它取决于CPU型号)。我们假设缓存是空的。

如果迭代一个数组,则每64字节将支付一次缓存未命中。智能CPU(和智能程序)可以分析内存访问模式,并决定在缓存中预取连续的内存块以提高吞吐量。

如果您在列表上进行迭代,则访问模式将是随机的,您可能会为每个项目支付缓存未命中。

问题2

在第一次访问时,不搜索整个数组并将其引入缓存。只有第一个缓存行是。

然而,还有另一个需要考虑的因素:TLB。页面大小取决于系统。典型值为4 KB。第一次访问数组时,将发生地址转换(其结果将存储在TLB中)。如果阵列小于4 KB(页面大小),则不必进行其他地址转换。如果它更大,则每页翻译一次。

将此与列表进行比较。多个项目适合同一页面(4 KB)的概率远低于数组。它们可以适合同一缓存行(64字节)的概率非常低。

我认为计算复杂性很困难,因为可能需要考虑其他因素。但是在这种复杂性中,您必须考虑缓存行大小(缓存未命中)和页面大小(对于TLB未命中)。

问题3

缓存未命中是指给定缓存行不在缓存中。它可能发生在L1,L2或L3级别。越高,越贵。

当虚拟地址不在TLB中时,发生TLB未命中。在这种情况下,使用页表(昂贵)转换为物理地址,结果存储在TLB中。

所以是的,使用链表,你可能会支付比数组更多的缓存和TLB未命中数。

有用的链接: