Cache 一致性
Cache 一致性是 Cache 中遇到的比较坑的一个问题。
什么原因需要 Cache 处理一致性呢?
主要是多核系统中,假如core 0读了主存储的数据,写了数据。core 1也读了主从的数据。这个时候core 1并不知道数据已经被改动了,也就是说,core 1 Cache中的数据过时了,会产生错误。
Cache一致性的保证就是让多核访问不出错。
Cache一致性主要有两种策略。
策略一:基于监听的一致性策略
这种策略是所有Cache均监听各Cache的写操作,如果一个Cache中的数据被写了,有两种处理办法。
写更新协议:某个Cache发生写了,就索性把所有Cache都给更新了。
写失效协议:某个Cache发生写了,就把其他Cache中的该数据块置为无效。
策略 1 由于监听起来成本比较大,所以只应用于极简单的系统中。
策略二:基于目录的一致性策略
这种策略是在主存处维护一张表。记录各数据块都被写到了哪些Cache, 从而更新相应的状态。一般来讲这种策略采用的比较多。又分为下面几个常用的策略。
- SI: 对于一个数据块来讲,有share和invalid两种状态。如果是share状态,直接通知其他Cache, 将对应的块置为无效。
- MSI:对于一个数据块来讲,有share和invalid,modified三种状态。其中modified状态表表示该数据只属于这个Cache, 被修改过了。当这个数据被逐出Cache时更新主存。这么做的好处是避免了大量的主从写入。同时,如果是invalid时写该数据,就要保证其他所有Cache里该数据的标志位不为M,负责要先写回主存储。
- MESI:对于一个数据来讲,有4个状态。modified, invalid, shared, exclusive。其中exclusive状态用于标识该数据与其他Cache不依赖。要写的时候直接将该Cache状态改成M即可。
我们着重讲讲 MESI。图中黑线:CPU的访问。红线:总线的访问,其他Cache的访问。
当前状态时I状态时,如果发生处理器读操作 prrd。
- 如果其他Cache里有这份数据,如果其他Cache里是M态,先 把M态写回主存再读。否则直接读。最终状态变为S。
- 其他Cache里没这个数据,直接变到E状态。
当前状态为S态
- 如果发生了处理器读操作,仍然在S态。
- 如果发生了处理器写操作,则跳转到M状态。
- 如果其他Cache发生了写操作,跳到I态。
当前状态E态
- 发生了处理器读操作还是E。
- 发生了处理器写操作变成M。
- 如果其他Cache发生了读操作,变到S状态。
当前状态M态
- 发生了读操作依旧是M态。
- 发生了写操作依旧是M态。
- 如果其他Cache发生了读操作,则将数据写回主存储,变换到S态。
总结
Cache 在计算机体系架构中有非常重要的地位,本文讲了 Cache中最主要的内容,具体细节可以再根据某个点深入研究。