当前位置:首页 > 数码 > MESI-深入理解-CPU-协议-缓存一致性

MESI-深入理解-CPU-协议-缓存一致性

admin5个月前 (05-15)数码2903

在本文中,我们将深入探讨有关 CPU 缓存一致性协议 MESI 的知识。随着计算机技术的发展,了解这些概念对于优化系统性能至关重要。

CPU 高速缓存

为了弥合理论上无限的 CPU 速度和实际有限的内存和硬盘速度之间的差距,CPU 制造商在 CPU 中集成了少量的高速缓存。

局部性原理指出,CPU 访问存储设备时倾向于集中在连续区域内。这导致了以下两种局部性:

  • 时间局部性:如果一个信息项正在被访问,那么在近期它很可能还会被再次访问。
  • 空间局部性:如果一个存储器位置被引用,那么将来他附近的位置也会被引用。

高速缓存利用局部性原理,将最近使用的数据和指令存储在 CPU 附近,从而减少了从较慢的内存和硬盘中检索信息的需要。

多级缓存结构

随着 CPU 运算速度超越了 1 级缓存的数据 I/O 能力,CPU 制造商引入了多级的缓存结构。这允许在多个级别上存储数据,从最快的 L1 缓存到最慢的 L3 缓存。

多核 CPU 多级缓存一致性协议 MESI

在多核 CPU 中,有多个一级缓存。为了确保这些缓存中的数据保持一致,需要一种一致性协议。MESI 协议就是这样的协议。

MESI 协议缓存状态

MESI 指 4 种状态的首字母,每个 Cacheline(缓存存储数据的单元)都有这 4 种状态,可用 2 个比特表示:

  • M(修改):该 Cacheline 有效,数据被修改,与内存中的数据不一致,数据只存在于本 Cache 中。
  • E(独占、互斥):该 Cacheline 有效,数据与内存中的数据一致,数据只存在于本 Cache 中。
  • S(共享):该 Cacheline 有效,数据与内存中的数据一致,数据存在于多个 Cache 中。
  • I(无效):该 Cacheline 无效。

注意:对于 M 和 E 状态而言总是精确的,但 S 状态可能是非一致的。这是因为其他缓存不会广播他们作废该缓存行的通知,并且缓存没有保存该缓存行副本的数量。

MESI 状态转换

MESI 协议的状态转换如下表所示:

| 触发事件 | 本地读取 | 本地写入 | 远端读取 | 远端写入 | |---|---|---|---|---| | 本地 Cache 为 M 状态 | 读数据 | 触发写回 | 不响应 | 触发写回 | | 本地 Cache 为 E 状态 | 读数据 | 更新数据 | 触发总线事务 | 无效 | | 本地 Cache 为 S 状态 | 读数据 | 触发写回 | 触发总线事务 | 无效 | | 本地 Cache 为 I 状态 | 从主内存加载数据 | 触发总线事务 | 无响应 | 访问无效 | | 其他 Cache 读取 | 无操作 | 无操作 | 从本地 Cache 读数据 | 无响应(如果本地 Cache 为 I 状态,则无效) | | 其他 Cache 写入 | 无操作 | 从本地 Cache 读数据 | 无响应 | 无效 |

前置说明:

  • 触发事件:触发读写事件的事件。
  • 本地 Cache:当前 CPU 的 Cache。
  • 触发 Cache:触发读写事件的 Cache。
  • 其他 Cache:除了以上两种之外的其他 Cache。

结论

MESI 协议是用于在多核 CPU 中维护缓存一致性的重要一致性协议。它通过跟踪每个 Cacheline 的状态并在触发事件发生时更新状态来确保所有缓存中的数据保持一致。

理解 MESI 协议对于优化多核 CPU 的性能至关重要,因为它可以防止数据损坏和系统不稳定。


计算机组成原理之缓存行 cacheLine

缓存行:64字节;缓存行越大,局部空间效率高,读取时间慢;反之局部空间效率低读取速度快,所以折中选择了64个字节;

如何保证CPU中不同L1缓存、L2缓存的 缓存一致性? MESI缓存一致性协议, 因特尔CPU的协议 其他的缓存一致性协议有: MSI/MOSI/Synapse/Firefly/Dragon

L1:CPU一级缓存; L2:CPU二级缓存; L3:CPU三级缓存; 其中 L3 是计算 CPU共享的,L1、L2是CPU中 核 独享的;

缓存一致性

缓存一致性的实现:如上图 如果左侧核的X值在L1中被修改了----modified,此时会有通知到右侧的核 的X为---invalid; 之后,右侧再读取X值时发现无效会往上层查询有效数据;

为了减少 CPU中缓存数据被不同的 核 读取,程序设计中有一个 RingBuffer 环形缓存,在实际存储变量 INITAL_CURSOR_VALUE 前后都增加了7个变量,long类型的长度时8字节;CPU在读取数据时会修改的变量只有 INITAL_CURSOR_VALUE ,数据只会被其中一个核读取,就不会出现使用 MESI缓存一致性协议 去解决缓存一致性导致的耗时问题;

除了上述方式,JDK1.8中 使用了注解的方式强制让一个变量占据一个缓存行;

缓存一致性协议

锁缓存行有一套协议叫做 缓存一致性协议 。缓存一致性协议有MSI、MESI、MOSI、Synapse、Firefly以及DragonProtocol等等。

MESI分别代表缓存行数据的4中状态,通过对这四种状态的切换,来达到对缓存数据进行管理的目的

假设有三个CPU-A、B、C,对应三个缓存分别是cache-a、b、c。在主内存中定义了x的引用值0

单核读取

MESI优化和引入的问题:各CPU缓存行的状态是通过消息传递来进行的。如果CPU0要对一个在缓存中共享的变量进行写入,首先需要发送一个失效的消息给到其他缓存了该数据的CPU,并且要等到他们的确认回执。CPU0在这段时间内都会一直处于阻塞状态,会导致各种各样的性能问题和稳定性问题。

为了避免阻塞带来的资源浪费,在CPU中引入了Store Buffer。

CPU在写入共享数据时,直接把数据写入到Store Buffer中,同时发送Invalidate消息,然后继续去处理其他指令。当收到其他所有CPU发送了Invalidate Acknowledge消息时,再将Store Buffer中的数据存储到Cache Line中,最后再从Cache Line同步到主内存。

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: CPU缓存