Joh*_*ica 47
如果您的计算机充满超快速内存,这无关紧要.
但不幸的是情况并非如此,计算机内存看起来像这样:
+----------+
| CPU | <<-- Our beloved CPU, superfast and always hungry for more data.
+----------+
|L1 - Cache| <<-- works at 100% of CPU speed (fast)
+----------+
|L2 - Cache| <<-- works at 25% of CPU speed (medium)
+----+-----+
|
| <<-- This thin wire is the memory bus, it has limited bandwidth.
+----+-----+ <<-- works at 10% of CPU speed.
| main-mem | <<-- The main memory is big but slow (because we are cheap-skates)
+----------+
|
| <<-- Even slower wire to the harddisk
+----+-----+
| harddisk | <<-- Works at 0,001% of CPU speed
+----------+
Run Code Online (Sandbox Code Playgroud)
空间位置
在此图中,CPU越接近CPU,CPU就越快.
这与Spacial Locality
.有关.如果数据位于内存中,则数据具有空间局部性.
由于便宜的冰鞋,我们RAM不是真正的随机访问,它真的是Slow if random, less slow if accessed sequentially Access Memory
SIRLSIAS-AM.
这就是为什么将相关数据保持在一起很聪明,因此您可以对一堆数据进行顺序读取并节省时间.
时间局部性
数据保留在主内存中,但它不能保留在缓存中,否则缓存将不再有用.可以在缓存中找到最近使用的数据之一; 旧数据被推出.
这与temporal locality
.有关.如果同时访问数据,则数据具有强时间局部性.
这很重要,因为如果项目A在缓存中(好)而不是项目B(具有强时间局部性到A)很可能也在缓存中.
首先,请注意这些概念并不是普遍规律,它们是对常见代码行为形式的观察,这些代码行为允许 CPU 设计人员优化他们的系统以在大多数程序上表现得更好。同时,这些是程序员试图在他们的程序中采用的属性,因为他们知道这是构建内存系统的方式,也是 CPU 设计人员优化的目的。
空间局部性是指某些(实际上是大多数)应用程序以顺序或跨步方式访问内存的属性。这通常源于这样一个事实,即最基本的数据结构构建块是数组和结构,它们都在内存中相邻地存储多个元素。事实上,语义上链接的数据结构(图、树、跳过列表)的许多实现都在内部使用数组来提高性能。
由于以下原因,空间局部性允许 CPU 提高内存访问性能:
内存缓存机制(如缓存、页表、内存控制器页面)在设计上已经比单次访问所需的更大。这意味着一旦您为从远内存或较低级别的缓存中获取数据而付出了内存代价,您可以从中消耗的额外数据越多,您的利用率就越高。
当今几乎所有 CPU 上都存在的硬件预取通常涵盖空间访问。每次获取 addr X 时,预取器可能会获取下一个缓存行,也可能会获取更远的其他缓存行。如果程序表现出恒定的步幅,大多数 CPU 也能够检测到这一点,并推断以预取相同步幅的更多步骤。现代空间预取器甚至可以预测可变的重复步幅(例如VLDP、SPP)
时间局部性是指内存访问或访问模式重复的属性。在最基本的形式中,这可能意味着如果地址 X 曾经被访问过,它也可能在未来被访问,但是由于缓存已经将最近的数据存储了一段时间,因此这种形式不太有趣(尽管某些 CPU 上有一些机制旨在预测哪些线路可能很快会再次访问,哪些不会)。
一种更有趣的时间局部性形式是两个(或多个)时间相邻的访问被观察到一次,可能再次一起重复。也就是说 - 如果您曾经访问过地址 A 并且在该地址 B 之后不久,并且在稍后某个时间点 CPU 检测到对地址 A 的另一次访问 - 它可能会预测您可能很快会再次访问 B,并提前进行预取。旨在提取和预测此类关系的预取器(时间预取器)通常使用相对较大的存储空间来记录许多此类关系。(参见 Markov 预取,以及最近的ISB、STMS、Domino等。)
顺便说一下,这些概念绝不是排他性的,一个程序可以展示两种类型的位置(以及其他更不规则的形式)。有时两者甚至在术语时空局部性下组合在一起以表示局部性的“常见”形式,或时间相关性连接空间构造的组合形式(例如地址增量总是跟随另一个地址增量)。