释义
缓存一致性协议指的是在计算机中,为保证多CPU从内存读取到缓存中的数据一致,而定义的一种解决方案。
由来
1.为什么要使用多CPU
假如一台计算机只有一个CPU,想要同时执行多个进程,就需要经常进行上下文切换,这个代价是比较大的,所以为了提高性能,一台计算机往往有多个CPU。
2.CPU是如何进行工作的
要理解CPU的工作方式,首先要知道计算机是怎么工作的。
CPU在读取数据的时候,首先是在自己的寄存器和缓存中查看有没有,如果有就直接使用,如果没有则需要去内存中取。而寄存器和缓存存在的价值,就在于比读取内存快得多,每次都要取内存中读取,是一件非常影响效率的事情。
3.CPU的工作方式是否存在问题
在单CPU的情况下,CPU的工作方式,固然没有什么问题,但是多CPU呢?
就“a=a+1”的操作而言,假如CPU1和CPU2同时要进行此操作,CPU1进行操作之后还没来得及将a的计算结果写回内存,CPU2就在内存中读取了a的原始值,最终导致,a的值本该增加了2,却最终增加了1。这就是所谓的缓存不一致问题。
4.怎么解决缓存不一致问题呢
很简单,直接在总线上加锁不就可以了,如果CPU1的整个操作还没有完成,就不允许CPU2再执行操作,也就是说,只有CPU1将计算后的a值写回内存后,才允许CPU2再读取a。这就是总线锁,将共享内存变为独享内存,以保证数据的正确性。
5.总线锁的方式会不会降低了效率
是的,加锁虽然简单粗暴,但是效率上将会大打折扣。所以为了提高效率,缓存一致性协议诞生了,缓存一致性协议有MSI、MESI、MOSI、Synapse、Firefly及DragonProtocol等。其中最出名的就是MESI。
MESI
1.四种状态
M(Modified):修改,数据被修改了,和内存中的数据不一致,数据只存在于本Cache中。
E(Exclusive):独占,数据和内存中的数据一致,数据只存在于本Cache中。
S(Shared):共享,数据和内存中的数据一致,数据存在于很多Cache中。
I(Invalid):失效,缓存中的数据已经失效。
2.规则
(1) 如果缓存状态是I,那么就从内存中读取,否则就从缓存中直接读取。
(2) 如果缓存处于M或E的CPU读取到其他CPU有读操作,就把自己的缓存写入到内存中,并将自己的状态设置为S。
(3) 只有缓存状态是M或E的时候,CPU才可以修改缓存中的数据,修改后,缓存状态变为M。
3.触发机制
如何才能触发MESI呢?
在汇编指令中添加#Lock信号,即可触发MESI。下面还是以“a=a+1”为例:
当CPU1读取到变量a之后,会将a的状态变为E;
若与此同时CPU2也读取了变量a,那么CPU1将会监听(总线嗅探机制)到其它CPU也使用了这个变量,接着就将a的状态变为S;
当CPU1中对a执行了+1操作,则同时将a的状态改为M;
此时CPU监听到a的状态已经改变为M,则会将自身缓存中的状态改为I;
CPU1将a的值重新写回内存后,会将a的状态再次改为E。
注意点
1.缓存的基本单位是缓存行,缓存一致性协议基于缓存行,若一个缓存行存不下一个变量的值,那么缓存一致性协议将失效,此时需要借助总线锁解决缓存一致性问题。
2.CPU有可能本身并不支持缓存一致性协议。
3.缓存一致性协议只能保证数据的可见性,却不能保证数据的有序性和原子性。
【个人笔记】转载请注明出处!