CPU多级缓存
Posted 一起写程序
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CPU多级缓存相关的知识,希望对你有一定的参考价值。
一、什么是CPU缓存
1. CPU缓存的来历
2. CPU缓存的概念
64
字节。
3. CPU缓存的意义
-
时间局部性(Temporal Locality): 如果一个信息项正在被访问,那么在近期它很可能还会被再次访问。 -
空间局部性(Spatial Locality): 如果一个存储器的位置被引用,那么将来他附近的位置也会被引用。
二、CPU的三级缓存
1. CPU的三级缓存
L1
,
L2
,
L3
。
级别越小越接近CPU,所以速度也更快,同时也代表着容量越小。
L1 是最接近CPU的, 它容量最小(例如:
32K
),速度最快,每个核上都有一个 L1 缓存,L1 缓存每个核上其实有两个 L1 缓存, 一个用于存数据的 L1d Cache(Data Cache),一个用于存指令的 L1i Cache(Instruction Cache)。
L2 缓存 更大一些(例如:
256K
),速度要慢一些, 一般情况下每个核上都有一个独立的L2 缓存; L3 缓存是三级缓存中最大的一级(例如3MB),同时也是最慢的一级, 在同一个CPU插槽之间的核共享一个 L3 缓存。
下面是三级缓存的处理速度参考表:
从CPU到 | 大约需要的CPU周期 | 大约需要的时间(单位ns) |
---|---|---|
寄存器 | 1 cycle | |
L1 Cache | ~3-4 cycles | ~0.5-1 ns |
L2 Cache | ~10-20 cycles | ~3-7 ns |
L3 Cache | ~40-45 cycles | ~15 ns |
跨槽传输 | ~20 ns | |
内存 | ~120-240 cycles | ~60-120ns |
下图是Intel Core i5-4285U的CPU三级缓存示意图:
2. 带有高速缓存CPU执行计算的流程
-
程序以及数据被加载到主内存 -
指令和数据被加载到CPU的高速缓存 -
CPU执行指令,把结果写到高速缓存 -
高速缓存中的数据写回主内存
三、CPU缓存一致性协议(MESI)
Modified Exclusive Shared Or Invalid
)(也称为伊利诺斯协议,是因为该协议由伊利诺斯州立大学提出的)是一种广泛使用的支持写回策略的缓存一致性协议。
为了保证多个CPU缓存中共享数据的一致性,定义了缓存行(Cache Line)的四种状态,而CPU对缓存行的四种操作可能会产生不一致的状态,因此缓存控制器监听到本地操作和远程操作的时候,需要对地址一致的缓存行的状态进行一致性修改,从而保证数据在多个缓存之间保持一致性。
1. MESI协议中的状态
CPU中每个缓存行(Caceh line)使用4
种状态进行标记,使用2bit
来表示:
状态 | 描述 | 监听任务 | 状态转换 |
---|---|---|---|
M 修改 (Modified) | 该Cache line有效,数据被修改了,和内存中的数据不一致,数据只存在于本Cache中。 | 缓存行必须时刻监听所有试图读该缓存行相对就主存的操作,这种操作必须在缓存将该缓存行写回主存并将状态变成S(共享)状态之前被延迟执行。 | 当被写回主存之后,该缓存行的状态会变成独享(exclusive)状态。 |
E 独享、互斥 (Exclusive) | 该Cache line有效,数据和内存中的数据一致,数据只存在于本Cache中。 | 缓存行也必须监听其它缓存读主存中该缓存行的操作,一旦有这种操作,该缓存行需要变成S(共享)状态。 | 当CPU修改该缓存行中内容时,该状态可以变成Modified状态 |
S 共享 (Shared) | 该Cache line有效,数据和内存中的数据一致,数据存在于很多Cache中。 | 缓存行也必须监听其它缓存使该缓存行无效或者独享该缓存行的请求,并将该缓存行变成无效(Invalid)。 | 当有一个CPU修改该缓存行时,其它CPU中该缓存行可以被作废(变成无效状态 Invalid)。 |
I 无效 (Invalid) | 该Cache line无效。 | 无 | 无 |
注意 :对于M和E状态而言总是精确的,他们在和该缓存行的真正状态是一致的,而S状态可能是非一致的。 如果一个缓存将处于S状态的缓存行作废了,而另一个缓存实际上可能已经独享了该缓存行,但是该缓存却不会将该缓存行升迁为E状态,这是因为其它缓存不会广播他们作废掉该缓存行的通知,同样由于缓存并没有保存该缓存行的copy的数量,因此(即使有这种通知)也没有办法确定自己是否已经独享了该缓存行。
M |
E |
S |
I |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
假设cache 1 中有一个变量 x = 0
的 Cache line 处于S状态(共享)。
那么其他拥有x变量的 cache 2、cache 3 等x
的 Cache line调整为S
状态(共享)或者调整为I
状态(无效)。
2. 多核缓存协同操作
(1) 内存变量
x
的引用值为0。
(2) 单核读取
-
CPU A发出了一条指令,从主内存中读取 x
。 -
从主内存通过 bus 读取到 CPU A 的缓存中(远端读取 Remote read),这时该 Cache line 修改为 E 状态(独享)。
(3) 双核读取
-
CPU A发出了一条指令,从主内存中读取 x
。 -
CPU A从主内存通过bus读取到 cache a 中并将该 Cache line 设置为E状态。 -
CPU B发出了一条指令,从主内存中读取 x
。 -
CPU B试图从主内存中读取 x
时,CPU A检测到了地址冲突。 这时CPU A对相关数据做出响应。 此时x
存储于 cache a 和 cache b 中,x
在 chche a 和 cache b 中都被设置为S状态(共享)。
(4) 修改数据
-
CPU A 计算完成后发指令需要修改 x
. -
CPU A 将 x
设置为M状态(修改)并通知缓存了x
的 CPU B, CPU B 将本地 cache b 中的x
设置为I
状态(无效) -
CPU A 对 x
进行赋值。
(5) 同步数据
-
CPU B 发出了要读取x的指令。 -
CPU B 通知CPU A,CPU A将修改后的数据同步到主内存时cache a 修改为E(独享) -
CPU A同步CPU B的x,将cache a和同步后cache b中的x设置为S状态(共享)。
3. CPU 存储模型简介
4
种操作可能会产生不一致状态,因此 cache 控制器监听到本地操作和远程操作的时候,需要对地址一致的 Cache line 状态做出一定的修改,从而保证数据在多个cache之间流转的一致性。
I
(无效)状态通知到其他拥有该缓存数据的CPU缓存中,并且等待确认。
等待确认的过程会阻塞处理器,这会降低处理器的性能。
因为这个等待远远比一个指令的执行时间长的多。
所以,为了为了避免这种阻塞导致时间的浪费,引入了存储缓存(
Store Buffer
)和无效队列(
Invalidate Queue
)。
(1) 存储缓存
-
量不在该 CPU 缓存中,则需要发送 Read Invalidate 信号,再等待此信号返回,之后再写入量到缓存中。 -
量在该 CPU 缓存中,如果该量的状态是 Exclusive 则直接更改。 而如果是 Shared 则需要发送 Invalidate 消息让其它 CPU 感知到这一更改后再更改。
(2) 无效队列
四、乱序执行
out-of-orderexecution
):
是指CPU允许将多条指令不按程序规定的顺序分开发送给各相应电路单元处理的技术。
这样将根据各电路单元的状态和各指令能否提前执行的具体情况分析后,将能提前执行的指令立即发送给相应电路。
-
写写乱序(store store): a=1;b=2; -> b=2;a=1;
-
写读乱序(store load): a=1;load(b); -> load(b);a=1;
-
读读乱序(load load): load(a);load(b); -> load(b);load(a);
-
读写乱序(load store): load(a);b=2; -> b=2;load(a);
以上是关于CPU多级缓存的主要内容,如果未能解决你的问题,请参考以下文章