从 Cache 说起
如今的多核计算机往往包含多个 CPU 核心,其中每个 CPU 有自己独立的 Cache L1、Cache L2,同时多个 CPU 共享主存。
- 由于 CPU 获取指令数据的速度远快于主存,所以通过一级缓存、二级缓存等等来降低 CPU 从主存获取数据的频率,提升性能。
- CPU 不会每需要一次数据就从主存读取一次数据,而是一次读满一个 CacheLine(大小为 2的幂次方,16B ~ 256B)。
- 如果 CPU 访问 Cache发现数据不存在,就会触发
Cache Miss
,需要从主存加载数据。此时 CPU 必须等待; - 如果
Cache Miss
触发需要替换现有 Cache 中的数据,而此时 Cache 正好满载,就会触发Capicity Miss
;在这之后又访问了 Cache Line,就会触发Associativity Miss
。
MSI协议
现在有两个CPU,假设 CPU-1 更改了自己 cacheline 中变量值时,其它也拥有这个共享变量的 cacheline 的 CPU-2 会执行 write invalidate
操作,就是将自己的 cacheline 状态置为 invalid
,这样如果再次访问这个 cacheline,就需要刷新 CPU-1 的 cacheline 值到内存,同时 CPU-2 重新访问内存获取最新值并保存到 cacheline。
MSI 协议的名称是指 cacheline 可能处于的状态(Modified、Shared、Invalid)。
当一些 CPU 从内存读取数据到自己的 cacheline,这些 CPU 中这些 cacheline 数据都是一致的,cacheline 处于 shared状态。
如果 P2 将 cacheline 中变量修改为13,P2-cacheline 的状态就会变为 Modified 状态,其它 CPU-cahceline 状态变为 invlidate。
此时 P1 试图读取 cacheline 中数据,由于是 invalidate 状态,就会触发 read-miss。P2 会将自己 cacheline 中的数据写回到内存,供 P1 从内存读取最新值,读取完毕后 P1-cacheline、P2-cacheline 都会变为 Shared 状态。
上面讨论的是读写操作,如果是写写操作,P1-cacheline 会由 Shared——>Modified 状态;其它 CPU-cacheline 会由 Shared——>Invalidate 状态。
总的来说无论什么时候,某个内存位置和它对应的 cacheline 中,最多只有一个 CPU-cacheline 可以处于 Modified 状态,它代表着最新的数据。
MESI协议
在 MSI 协议的基础上,又出现了 MESI 协议,新增了 Exclusive 状态,各状态含义解释如下:
- Modified:这行数据有效,数据被修改了,和内存中数据不一致,数据只存在于本 Cache中;
- Exclusive:这行数据有效,数据和内存中一直,数据只存在于本 Cache中;
- Shared:这行数据有效,数据和内存中一致,数据存在于多个 Cache中;
- Ivalid:数据无效;
- E 状态:
- S 状态:
- M 和 I 状态:
MESI状态变迁
local-read
:本内核读取本 Cache 中值;local-write
:本内核写本 Cache 中值;remote-read
:其它内核读其它 Cache 中值;remote-write
:其它内核写其它 Cache 中值;