cpu缓存是位于CPU与内存之间的临时存储器,它的容量比内存小的多,但是交换速度却比内存要快得多
cpu的频率太快了,快到主存跟不上,这样在处理器时钟周期内,cpu常常需要等待主存,浪费资源。cache的出现,是为了缓解cpu和主存之间速度的不匹配问题(结构:cpu->cache>memory)
1、时间局部性:如果某个数据被访问,那么在不久的将来它很可能被再次访问;
2、空间局部性:如果某个数据被访问,那么与它相邻的数据很快也可能被访问;
用于保证多个CPU cache之间缓存共享数据的一致,也可以通过给总线加LOCK锁的方式来保证缓存一致性
每个缓存行有如下M、E、S、I 四种状态
M(Modified):被修改,该缓存行只被缓存在该CPU的缓存中,并且是被修改过的,目前与主存的数据不一致,即该缓存需要在未来的某个时间点(并且允许其他CPU读取该主存中相应内存之间)写回主内存,当被写回主存之后,该缓存行的状态会变成独享(Exclusive)状态
E(Exclusive):独享的,该缓存行只被缓存在该CPU的缓存中,它是未被修改过的,与主存中的数据一致。该状态可以在任何时刻当有其它CPU读取该内存时变成共享状态。同样地,当CPU修改该缓存行中内容时,该状态可以变成Modified状态
S(Shared):共享的,该状态意味着该缓存行可能被多个CPU缓存,并且各个缓存中的数据与主存数据一致,当有一个CPU修改该缓存行时,其他CPU中对该缓存行的缓存可以被作废,变为无效状态(Invalid)
I(Invalid):该缓存时无效的
从CPU读写角度来说:
CPU读请求:缓存处于M、E、S状态都可以被读取,I状态CPU只能从主存中读取数据
CPU写请求:缓存处于M、E状态才可以被写。对于S状态的写,需要将其他CPU中缓存行置为无效才可写
典型的例子如下:
在一个典型系统中,可能会有几个缓存(在多核系统中,每个核心都会有自己的缓存)共享主存总线,每个相应的CPU会发出读写请求,而缓存的目的是为了减少CPU读写共享主存的次数。
一个缓存除在Invalid状态外都可以满足cpu的读请求,一个invalid的缓存行必须从主存中读取(变成S或者 E状态)来满足该CPU的读请求。
一个写请求只有在该缓存行是M或者E状态时才能被执行,如果缓存行处于S状态,必须先将其它缓存中该缓存行变成Invalid状态(也既是不允许不同CPU同时修改同一缓存行,即使修改该缓存行中不同位置的数据也不允许)。该操作经常作用广播的方式来完成,例如:Request For Ownership (RFO)
缓存可以随时将一个非M状态的缓存行作废,或者变成Invalid状态,而一个M状态的缓存行必须先被写回主存。
一个处于M状态的缓存行必须时刻监听所有试图读该缓存行相对就主存的操作,这种操作必须在缓存将该缓存行写回主存并将状态变成S状态之前被延迟执行。
一个处于S状态的缓存行也必须监听其它缓存使该缓存行无效或者独享该缓存行的请求,并将该缓存行变成无效(Invalid)。
一个处于E状态的缓存行也必须监听其它缓存读主存中该缓存行的操作,一旦有这种操作,该缓存行需要变成S状态。
对于M和E状态而言总是精确的,他们在和该缓存行的真正状态是一致的。而S状态可能是非一致的,如果一个缓存将处于S状态的缓存行作废了,而另一个缓存实际上可能已经独享了该缓存行,但是该缓存却不会将该缓存行升迁为E状态,这是因为其它缓存不会广播他们作废掉该缓存行的通知,同样由于缓存并没有保存该缓存行的copy的数量,因此(即使有这种通知)也没有办法确定自己是否已经独享了该缓存行。
当CPU写数据时,如果发现操作的变量是共享变量,即在其他CPU中也存在该变量的副本,会发出信号通知其他CPU将该变量的缓存行置为无效状态,因此当其他CPU需要读取这个变量时,发现自己缓存中的缓存该变量的缓存行是无效的,那么它就会重新从内存中读取。
JVM的工作内存,还包括了一内存中的一部分,仅仅依靠缓存一致性,不能保证工作内存的变量在线程之间可见。
参考链接:
https://blog.csdn.net/u014078904/article/details/79974156
https://blog.csdn.net/andy2019/article/details/79787888