此处仅简单分析每个命令的含义,背景,以及可能的状态变化,对于每个trans具体包含的流程,将在下文描述;
read类型的操作分为两类,allocating read和non-allocating read;
Allocating read
==============================================================
ReadClean
- 此类命令只能接收cacheline状态为UC/SC的数据,即不能接收dirty的数据;
- 示意流程图如下:
- 一般用于,当某个RNF不具备将dirty的数据flush入内存的能力时,会使用这种命令;
- 也就是说,当前这个RNF的cache的写回策略是write through, 所以只能支持clean态;
- readclean触发的snpclean, 会将其他RNF中的dirty的数据写入主存,然后将clean的数据返回给发起ReadClean的RNF;
- 允许的初始状态:(根据tagop做区分) 所有状态都可以发送该命令;
- 响应返回后的状态:UC/SC;
- 被SNP的RNF,SNP后的状态:I / SC / SD;
==============================================================
ReadNotSharedDirty
- 当RNF本身只支持MESI协议,不支持MOESI时,此RNF不能存在O态,即shared dirty, 该RNF不能够接收该状态;
- 期望的snoop 请求;
- 允许的初始状态:I / UCE;
- 响应返回后的状态:UC/UD/SC;
- 被SNP的RNF,SNP后的状态:I / SC / SD;
==============================================================
ReadShared
- 此命令和上一命令相对应,支持MOESI状态模型;
- ReadShared is used instead of ReadNotSharedDirty when the Requester is willing to accept data in the SD state;也就是说,最好是shared, 如果不是,也行;
- 流程示意图:
- 允许的初始状态:I / UCE;
- 响应返回后的状态:UC/UD/SC/SD;
- 被SNP的RNF,SNP后的状态:I / SC / SD;
==============================================================
ReadUnique
- RN想要写非完整的cacheline, 所以先要获得最新的数据和写(unique)的权限,接着进行partial的写并与最新的数据merge;
- 基础数据流如下:
- 访问的是snoopable的地址空间;
- 对应的snp请求如下:
- 初始状态建议最好是I/SC/SD, 但是也允许在UC/UD/UDP/UCE时发送;
- 命令完成后状态,只能是UC/UD;
- 其他core收到后可以转变的状态:
- 状态转化如下:
==============================================================
ReadpreferUnique
- 可以理解成一个exclusive read;
- 访问的是snoopable的空间,想要获得一个unique的cacheline;
- 使用场景上,发送此命令,是希望获得unique状态,但是如果不是unique的,也允许;
1. 发送该命令时,其他RN正在对这个地址进行exclusive的访问,此时返回的状态时shared;
2. 允许返回的状态一直是shared;
- 此命令主要是用来提高exclusive访问的效率,具体提升点在exclusive访问处描述;
- 对应的snp请求如下:
- 发起的rn的状态可以是如下状态:
- 最终的状态可以是如下状态:
- 其他core完成之后的状态:
- 当前RN的状态转换图示如下:
==============================================================
MakeReadUnique
- 访问snoopable的空间,想要获取该cacheline的unique状态;
- 典型使用场景是当前RN有该cacheline的shared copy, 想要获得写该cacheline的权限;
- 此命令分为exclusive/非exclusive两种,具体后文再介绍;
- 发起者可能的状态:
- 最终可能的状态;
- 接收方可能的状态;
- 对应的snp请求: