缓存一致性协议MESI和MOESI

下面的看法只是本人阅读了一些简单的文献,自己用自己能理解的方式写出来的文章,如果有不对的希望大家指出。我了解这些比较底层的东西只是为了更好的理解JAVA多线程的一些知识,对底层的一些具体实现原理并没有深究(深究也学不会,呃呃)。

1.寄存器、缓存、内存

下图以多CPU的情况举例。

缓存一致性协议MESI和MOESI_第1张图片

cpu:中央处理器,一台计算机的控制核心和运算核心。

register:通用寄存器,主要存储cpu当次运算所需要使用到的指令集和数据的位置。

引申概念:

地址总线:

数据总线表示cpu的寻址能力,这与寄存器的位数有关,如果寄存器是n位的,那么寻址能力就是2的n次方,他也可以理解为寄存器存储的最大数字。

数据总线:

由地址寄存器指出要存取数据或指令的位置后,接下来就是到该地址把数据或指令找到,并用数据总线传输给CPU。假设数据总线有m位,则传输的数据或指令也有m位。

字长:字长指CPU同一时间内可以处理的二进制数的位数,所以数据总线传输的数据或指令的位数要与字长一致。否则,如果数据总线宽度大于字长则一条数据或指令要分多次传输,则分开传输的几组数据也就没有意义了;如果数据总线宽度小于字长,则CPU的利用率要降低,对资源是种浪费。

我们安装系统的时候就需要先看到自己cpu的位数,然后选择跟cpu位数相同的系统来安装。

cache:缓存,分为三级缓存,不同级别的缓存空间不同,距离CPU的距离也不相同。缓存存在的目的是为了缩短CPU直接访问内存的时间消耗。从缓存里面获取数据要比内存中里面获取数据要很多。

 

slot:逻辑处理单元,因为当今cpu的运行速度越来越快,已经远远超过CPU访问cache的速度。这样就会产生大量的等待cache返回数据的情况发生。造成性能瓶颈。因此现在很多计算机采用了cache分片的技术,就是把一个cache分成多个处理单元。这样cpu获取数据只需要在固定的一小块区域获取数据就可以了,提高了性能。

memory:就是主内存了,CPU访问最慢的区域。

2.缓存一致性协议MESI

现在大多数电脑都是多核的,那么如何保证每个CPU的缓存里面数据一致性呢?现在很著名的一个协议就是MESI协议,就是缓存区域的四个状态,不同状态下进行不同的操作会产生不同的结果。下面引用了一张https://blog.csdn.net/muxiqingyang/article/details/6615199这篇文章里面的图

注意MESI是作用在各级的CPU缓存上面的,加入计算机有L1、L2、L3三级缓存的时候,这个时候可能L3级缓存包含所有L1和L2级别的缓存,这个时候MESI只会对L3缓存进行查找,不会深度去另外两层缓存查找。当计算机没有L3缓存的时候可能就是L2缓存来执行这个作用。这个跟不同的处理器的方式不相同。

缓存一致性协议MESI和MOESI_第2张图片

Local Read表示本内核读本Cache中的值,Local Write表示本内核写本Cache中的值,Remote Read表示其它内核读其它Cache中的值,Remote Write表示其它内核写其它Cache中的值。

缓存一致性协议MESI和MOESI_第3张图片

 

 

缓存一致性协议MESI和MOESI_第4张图片

3.MESIO协议

这个协议是在MESI协议上面的优化.大家在上面的图里面可以看出来,如果当前缓存是shared状态的时候,要想修改当前缓存里面的值得时候需要先要发起广播,其他缓存会把当前状态标记为Valid状态。然后当前缓存修改完之后,会把自己的状态改为Modified状态。这样其他缓存发起读的操作的时候当前缓存就会把修改后的值写入到主内存里面。然后这些缓存的状态都改为shared状态。这里面有一个点就是其他缓存发起读操作的时候必须再去内存里面读取一次数据。

MESIO协议就是在MESI协议上面加了一个Owned状态解决上述问题。这样当用户修改完当前缓存的时候,会把当前状态改为owned状态,这个状态下代表当前缓存的值和内存里面的值不同并且被多人共享,并且这个状态下其它缓存会直接从当前缓存里面把修改后的数据拷贝过去,然后状态再次变为shared状态。注意,Own状态的缓存应该保证下次其它没有这个变量的缓存从内存读取之前把修改后的值写入到主内存里面。

你可能感兴趣的:(多线程)