标签:核心 方案 code 发送 操作 无效 并发 har 包括
对于cpu来说,直接访问内存是比较耗时的,为了提高访问性能,现代计算机在cpu模块都加上了缓存(一般有3级缓存),cpu访问缓存的速度比直接访问内存的速度提高了很多。cpu在计算时会先从缓存中查找数据,如果在缓存中没有找到(缓存未命中),则从内存中查找并加载到缓存中,然后再把数据从缓存加载到寄存器中进行计算。
在多核cpu的计算机中,缓存在提高了cpu访问速度的同时,也带来了相应的问题:
在上左图中,由于cpu1和cpu2都保存着同一缓存行x的拷贝,如果cpu1将x修改为1,则cpu1缓存中的x与cpu2缓存中的x,以及内存中的x的值是不一致的,这就是缓存一致性问题。接下来cpu2如果读取x,则读取的依然是x的旧值0(正确的情况下cpu读取的x应为新值1)。
在上右图中,由于可能发生cpu1和cpu2同时对x进行修改,这又会产生写顺序问题。如果cpu1和cpu2同时对x加1,最后都将值回写到了内存,则内存的值为1(正确的情况下x应为2),也就是说其中一个cpu对x加1这个计算是无效的。
针对以上2个问题,可以提出2个要求来解决:1.cpu的读操作必须能读到修改后的新值;2.cpu对同一缓存行的写操作不能同时发生。第1点保证了数据的一致性,第2点保证了写数据的顺序性。
有2种缓存的写策略可以满足以上2点要求,从而解决一致性问题。
由于写无效策略在性能上优于写更新策略,如对同一数据多个写而中间无读的情况,写更新需要多次写广播操作,而在写无效协议下只需一次写无效操作,因此,在基于总线的多核计算机中,写无效策略成为大多数系统设计的选择。
上述的2种缓存写策略解决了导致缓存一致性的核心问题,但是还不够,若要完整的解决一致性问题,势必需要更加完整的方案,它们是:目录协议和监听协议。本文主要讲解监听协议。
监听协议使用共享总线连接多个cpu的私有缓存和主存,共享总线保证所有处理器内核的数据请求串行执行。任何处理器发出的数据请求将被广播到所有的cpu缓存控制器,所有cpu的缓存控制器都时刻监视着总线。如果收到读请求,数据所有者将把有效数据返回给发出此请求的cpu;如果收到写请求,拥有有效副本的cpu便无效或更新本cpu上的数据,数据所有者将把有效数据返回到发出此请求的cpu。数据所有者可能是cpu,也可能是主存。
MESI协议是MSI的拓展协议,它是采用写回和写无效策略的监听协议,被广泛用于维护缓存一致性。MESI指的是缓存行4个状态的首字母。
MESI协议包含的4个状态
状态 | 描述 |
已修改Modified (M) | 缓存行是脏的(dirty),与主存的值不同。如果别的CPU内核要读主存这块数据,该缓存行必须回写到主存,状态变为共享(S). |
独占Exclusive (E) | 缓存行只在当前缓存中,但是干净的(clean)--缓存数据同于主存数据。当别的缓存读取它时,状态变为共享;当前写数据时,变为已修改状态。 |
共享Shared (S) | 缓存行也存在于其它缓存中且是干净的。缓存行可以在任意时刻抛弃。 |
无效Invalid (I) | 缓存行是无效的 |
这些一致性状态通过高速缓存和后备存储之间的通信进行维护。 当缓存中的某个块被读或写时,或者当缓存通过总线接收到其他缓存发出的读写信号时,它需要据此来做出动作并调整自己的状态。
当缓存收到cpu的读请求时,如果一个缓存行处于“M”或“S”状态,则它会直接提供数据。但如果缓存行尚未被加载到缓存(处于“I”状态),则在加载该缓存行之前,cpu中的缓存控制器会向总线广播这个读请求,在收到这个广播后,其他缓存中处于"E"状态的拷贝直接修改为“S"状态就可以了;而处于“M”状态的拷贝,则会将数据地址广播到总线,以供读请求的cpu拿到新数据,并且写回内存,在提供数据后,该拷贝修改为“S”状态。
当缓存收到cpu的写请求时,如果这个块处于"M"状态,则缓存只需要修改本地的数据。 如果块处于"S"状态,则必须先将其他缓存中的拷贝置为“I”状态后,在修改本地的数据。 如果块处于"I"状态,则其他处于”S"状态的拷贝只需将拷贝置为“I”状态;如果有一个拷贝处于"M"状态,那么它必须先将数据通过总线提供给请求数据的缓存,并写回内存,然后将拷贝置为“I”状态。如果此时缓存尚未装载该缓存行的数据,则修改前要先将其从内存中读取。在数据被修改之后,缓存块处于"M"的状态。
对于任何给定的两个缓存,如果他们具有对应相同地址的缓存行,则允许的状态如下表所示:
MESI协议可以看作是一个有限状态机,它的4种状态转换来自两种场景:缓存所在处理器的读写;其他处理器的读写。
处理器向高速缓存发出的请求包括:
此外,还有总线方面的请求。 包括:
初始状态 | 操作 | 响应 | 最终状态 |
I | PrRd |
|
S |
PrWr |
|
M | |
BusRd |
|
I | |
BusRdX/BusUpgr |
|
I | |
E | PrRd |
|
E |
PrWr |
|
M | |
BusRd |
|
S | |
BusRdX |
|
I | |
S | PrRd |
|
S |
PrWr |
|
M | |
BusRd |
|
S | |
BusRdX |
|
I | |
M | PrRd |
|
M |
PrWr |
|
M | |
BusRd |
|
S | |
BusRdX |
|
I |
下面举个例子,来说明在MESI协议下,各个cpu是如何协同工作以保证缓存一致性的。
1.cpu1,x的初始值为0
2.cpu2读取x(0)
2.cpu1修改x,将x修改为1。
3.cpu2读取x,读取x(1)。
标签:核心 方案 code 发送 操作 无效 并发 har 包括
原文地址:https://www.cnblogs.com/wql025/p/14665177.html