在计算机系统设计实践中,我们常常会遇到下图所示架构:
![](https://i-blog.csdnimg.cn/blog_migrate/7ad22f469c7839e9fde9c52cab6825c9.jpeg)
为了解决单个存储器读吞吐无法满足要求的问题,常常需要在存储器上面增加一个或多个缓存。但由于相同的数据被复制到一个或多个地方,就容易引发数据一致性问题。不一致的数据可能出现在同级 Cache 之间 (Cache Coherence) 和上下级 Cache 之间。解决这些数据一致性问题的方案可以统称为 Cache Policies。从本质上看,所有 Cache Policies 的设计目的都可以概括为:在增加一级缓存之后,系统看起来和没加缓存的行为一致,但得益于局部性原理,系统的读吞吐量提高、时延减少。
本文将探讨三个场景:
- Cache Policy In Single-core Processor
- Cache Coherence in Multi-core Processor
- Cache Policy in Cache/DB Architecture
Cache Policy in Single-core Processor
在单核 CPU 中,只有一套 Cache,因此只要确保写入 Cache 中的数据也写入到 Memory 即可。
![](https://i-blog.csdnimg.cn/blog_migrate/349a3faa5a4bba8ecd78ac1872bfaccf.jpeg)
补充一些概念定义:数据在 Cache 与 Memory 之间移动的最小单位通常在 32 - 128 字节之间,Memory 中对应的最小单位数据称为 Cache Block,Cache 中与单个 Cache Block 对应的存储空间称为 Cache Line,在 Cache 中除了存储 Block 数据,还需要存储 Block 对应的唯一标识 T T T (Tag),以及一个用于标记 Cache Line 是否有数据的有效位 V V V。完整对应关系如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/c33f694c5d7268d8ea710efe476b9c51.jpeg)
单核处理器下的 Cache Policy 要解决的问题可以被概括为:
CPU 从 Cache 中读到的数据必须是最近写入的数据
要满足定义,最简单的方式就是 Write-Through,即每次写入 Cache 时,也将数据写到 Memory 中。当之前写入的某数据 D D D 在某时刻被置换后,可以保证再次读入的数据是最近写入的数据。这里有个很明显的改进空间:只需要在数据 D D D 被置换前将其写入 Memory 即可。为此我们可以为每个 Cache Line 增加一个脏位 (Dirty Bit),即:
![](https://i-blog.csdnimg.cn/blog_migrate/34fbef9b9cf911c7277029fc861c1ed8.jpeg)
当其被写入时置为 1;当其被置换时,如果脏位为 1,则写出到 Memory,否则直接丢弃即可。以上所述的 Cache Policy 就是 Write-Back Policy,也是目前在单核处理器中被广泛采用的 Cache Policy。
Cache Coherence in Multi-core Processor
在多核 CPU 中,如果这些核共用一套缓存,由于单套 Cache 的吞吐跟不上,无法达到最佳性能。
![](https://i-blog.csdnimg.cn/blog_migrate/9d186e55c4de0c94b277c9a5e6cedd0f.jpeg)
这时候就需要在每个核上再加一级私有缓存:
![](https://i-blog.csdnimg.cn/blog_migrate/55e3a5ccaff50ab029dc4a8194582a71.jpeg)
假设在一个 4 核处理器中,内存地址 M A MA MA 处最开始存储着整数 0,这时每个核都需要完成一个 read-modify-write 的操作,如下所示:
Core 0 | Core 1 | Core 2 | Core 3 |
---|---|---|---|
LW Reg <= A Reg ++ SW Reg => A |
LW Reg <= A Reg ++ SW Reg => A |
LW Reg <= A Reg ++ SW Reg => A |
LW Reg <= A Reg ++ SW Reg => A |
如果不加任何协议,当 4 个核都完成相应的操作后,内存地址 M A MA MA 处可能存储着 1、2、3、4 中的任意值,这将影响并行计算的正确性。要保证并行计算的正确性,就必须保证每个核私有缓存之间的数据一致且永远是最新版本,可以想象,多核处理器上的各核之间必须遵守某种数据读写协议,才可能在获得多核计算力的同时维持计算的正确性,我们称这种数据读写协议为 Cache Coherence Protocols。
Cache Coherence 的要求:
- 从内存地址 M X MX MX 将数据 D D D 读入到核 C 1 C1 C1 的 Cache 中,在其它核没有写入数据到 MX 的情况下,读入的数据 D D D 必须是 C 1 C1 C1 最近写入的数据值。(单核 CPU 的 Cache Coherence 定义)
- 如果 C 1