计算机组成原理:CPU Cache(高速缓存) 您所在的位置:网站首页 高速缓存作用及其原理 计算机组成原理:CPU Cache(高速缓存)

计算机组成原理:CPU Cache(高速缓存)

2024-07-14 14:05| 来源: 网络整理| 查看: 265

为什么需要CPU Cache

在这里插入图片描述

为了弥补CPU和内存之间的性能差异,以便于能够真实变得把CPU的性能提升利用起来,而不是让它在那里空转,我们在现代CPU中引入了高速缓存。

从CPU Cache被加入到现有的CPU里开始,内存中的指令、数据,会被加载到L1-L3 Cache中,而不是直接从CPU访问内存中取拿。

CPU从内存读取数据到CPU Cache的过程中,是一小块一小块来读取数据的,而不是按照单个数组元素来读取数据的。这样一小块一小块的数据,在CPU Cache里面,叫做Cache Line(缓存块)

在我们日常使用的 Intel 服务器或者 PC 里,Cache Line 的大小通常是 64 字节。

知道了为什么需要CPU Cache,接下来,我们就来看一看,CPU究竟是如何访问CPU Cache的,以及CPU Cache是如何组织数据的

Cache的数据结构和读取过程是怎么样的

现代CPU进行数据读取的时候,无论数据是否已经存储在Cacha中,CPU时钟会首先访问Cache。只有当CPU在Cache中找不到数据的时候,才会去访问内容,并且将读取到的数据写入Cache中。当时间局部性原理其作用后,这个最近刚刚被访问的数据,会很快再次被访问。而Cache的访问速度远远快于内存,这样,CPU花在等待内存访问上的时间就大大变短了。 在这里插入图片描述 这样的访问机制,和我们自己在开发应用系统的时候,“使用内存作为硬盘的缓存”的逻辑是一样的。在各类基准测试(Benchmark)和实际应用场景中,CPU Cache 的命中率通常能达到 95% 以上。

问题来了,CPU如何知道要访问的内存数据,存储在Cache的哪个位置呢?接下来,从最基本的直接映射 Cache(Direct Mapped Cache)起,了解整个 Cache 的数据结构和访问逻辑:

CPU访问内存数据,是一小块一小块数据来读取的。对于读取内存中的数据,我们首先拿到的是数据所在内存块(block)的地址。而直接映射Cache采用的策略,就是确保任何一个内存块的地址,时钟映射到一个固定的CPU Cache地址(Cache Line)。而这个映射关系,通常用mod运算来实现。比如说,我们的主内存被分成0-31号这样的32个块。我们一共有8个缓存块。用户想要访问第21号内存块。如果21号内存块内容在缓存块中的话,它一定在5号缓存块(21 mode 8 = 5)中。 在这里插入图片描述实际计算中,有一个小小的技巧,通常我们会把缓存块的数量设置成 2 的 N 次方。这样在计算取模的时候,可以直接取地址的低 N 位,也就是二进制里面的后几位。比如这里的 8个缓存块,就是 2 的 3 次方。那么,在对 21 取模的时候,可以对 21 的 2 进制表示10101 取地址的低三位,也就是 101,对应的 5,就是对应的缓存块地址

在这里插入图片描述

取Block地址的低位,就能得到对应的Cache Line地址,除了21号内存块之外,13号、5号等很多内存块的数据,都对应着5号缓存块。既然如此,假如现在 CPU 想要读取 21号内存块,在读取到 5 号缓存块的时候,我们怎么知道里面的数据,究竟是不是 21 号对应的数据呢? 这个时候,在对应的缓存块中,我们会存储一个组标记(Tag)。这个组标记会记录,当前缓存块内存储的数据对应的内存块,而缓存块本身的地址表示访问地址的低N位。就像上面的例子,21 的低 3 位 101,缓存块本身的地址已经涵盖了对应的信息、对应的组标记,我们只需要记录 21 剩余的高 2 位的信息,也就是 10 就可以了。除了组标记之外,缓存块中还有两个数据。一个自然是从主内存中加载来的实际存放的数据,另一个是有效位(valid bit)。啥是有效位呢?它其实就是用来标记,对应的缓存块中的数据是否有效的,确保不是机器刚刚启动的时候的空数据。如果有效位是0,无论其中的组标记和 Cache Line 里的数据内容是什么,CPU 都不会管这些数据,而要直接访问内存,重新加载数据CPU在读取数据的时候,并不是读取一整个Block,而是读取一个它需要的整数。这样的数据,我们叫做CPU里的一个字(word)。具体是哪个字,就用这个子在整个Block里面的位置来决定。这个位置,我们叫作偏移量(Offset)。

总结一下,一个内存的访问地址,最终包括高位代表的组标记、低位代表的索引,以及在对应的 Data Block 中定位对应字的位置偏移量。 在这里插入图片描述

而内存地址对应到Cache里的数据结构,则多了一个有效位和对应的数据,由“索引+有效位+组标记+数据”组成。如果内存中的数据已经在CPU Cache里了,那一个内存地址的访问,就会经历下面4个步骤

根据内存地址的低位,计算在 Cache 中的索引;判断有效位,确认 Cache 中的数据是有效的;对比内存访问地址的高位,和 Cache 中的组标记,确认 Cache 中的数据就是我们要访 问的内存数据,从 Cache Line 中读取到对应的数据块(Data Block);根据内存地址的 Offset 位,从 Data Block 中,读取希望读取到的字。

如果在 2、3 这两个步骤中,CPU发现,Cache中的数据并不是要访问的内存地址的数据,那CPU就会访问内存,并把对应的Block Data更新到Cache Line中,同时更新对应的有效位和组标记的数据。

可以看到:通过巧妙的将内存地址,拆分成“索引+组标记+偏移量”的方式,使得我们可以将很大的内存地址,映射到很小的CPU Cache地址里。

另外:除了直接映射 Cache 之外,我们常见的缓存放置策略还有全相连 Cache(Fully Associative Cache)、组相连 Cache(Set AssociativeCache)。

你确定你的数据更新了吗?

CPU不仅要读数据,还需要写数据,问题是,CPU在写入数据的时候,怎么既不牺牲性能,又能保证数据的一致性呢?

我们现在用的 Intel CPU,通常都是多核的的。每一个 CPU 核里面,都有独立属于自己的L1、L2 的 Cache,然后再有多个 CPU 核共用的 L3 的 Cache、主内存。

在这里插入图片描述 第一个问题是:我们写入的数据,到达应该写到Cache里还是主内存呢?如果我们直接写入到主内存里,Cache里的数据是否会失效呢?为了解决这些问题,我们需要先了解两种写入策略

写直达(Write-Through)

最简单的一种写入策略,叫做写直到。在这个策略里,每一次数据都要写入到主内存里。

写入前,我们会先去判断数据是否已经在Cache里面了如果数据已经在Cache里面,我们就先把数据写入更新到Cache里面,再写入到主内存中如果数据不在Cache里面,我们就只更新主内存

写直到这个策略很直观,但是问题也很明显,那就是这个策略很慢。无论数据是不是在Cache里面,我们都需要把数据写到主内存里面。

在这里插入图片描述

写回(Write-Back)

这个时候,我们就想了,既然我们去读数据也是默认从 Cache 里面加载,能否不用把所有的写入都同步到主内存里呢?只写入 CPU Cache 里面是不是可以?

当然是可以的。在 CPU Cache 的写入策略里,还有一种策略就叫作写回。这个策略里,我们不再是每次都把数据写入到主内存,而是只写到CPU Cache里。只有当CPU Cache里面的数据都要被“替换”的时候,我们才把数据写入到主内存里面去。

写回策略的过程是这样的:

如果发现我们要写入的数据,就在CPU Cache里面,那么我们就只是更新CPU Cache里面的数据同时,我们会标记CPU Cache里的这个Block是脏(Drity)的。所谓“脏”,就是指这个时候,我们的CPU Cache里面的这个Block的数据,和主内存是不一致的。如果我们发现,我们要写入的数据所对应的 Cache Block 里,放的是别的内存地址的数据,那么我们就要看一看,那个 Cache Block 里面的数据有没有被标记成脏的。 如果是脏的话,我们要先把这个 Cache Block 里面的数据,写入到主内存里面。然后,再把当前要写入的数据,写入到 Cache 里,同时把 Cache Block 标记成脏的。如果 Block 里面的数据没有被标记成脏的,那么我们直接把数据写入到 Cache 里面,然后再把 Cache Block 标记成脏的就好了。 在用了写回这个策略之后,我们在加载内存数据到 Cache 里面的时候,也要多出一步同步脏 Cache 的动作。如果加载内存里面的数据到 Cache 的时候,发现 Cache Block 里面有脏标记,我们也要先把 Cache Block 里的数据写回到主内存,才能加载数据覆盖掉Cache

在这里插入图片描述 可以看到,在写回这个策略里,如果我们大量的操作,都能够命中缓存。那么大部分时间里,我们都不需要读写主内存,自然性能会比写直达的效果好很多。

小结 然而,无论是写回还是写直达,其实都还没有解决多个线程,或者是多个 CPU 核的缓存一致性的问题。这也就是我们在写入修改缓存后,需要解决的第二个问题。要解决这个问题,我们需要引入一个新的方法,叫作 MESI 协议。这是一个维护缓存一致性协议。这个协议不仅可以用于CPU Cache之间,也可以广泛用于各种需要使用缓存,同时缓存之间需要同步的场景下。


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有