计算机系统结构-第五章-目录式协议
目录式协议*******:
基本思想:
物理存储器中数据块的共享状态被保存在一个称为目录的地方。通过目录来完成一系列的操作.
广播和监听的机制使得监听一致性协议的可扩展性很差。 所以寻找替代监听协议的一致性协议。
概念:
目录:一种集中的数据结构。对于存储器中的每一个可以调入Cache的数据块,在目录中设置一条目录项,用于记录该块的状态以及哪些Cache中有副本等相关信息。
特点:对于任何一个数据块,都可以快速地在唯一的一个位置中找到相关的信息。这使一致性协议避免了广播操作。
位向量:记录哪些Cache中有副本。(由位向量指定的处理机的集合称为共享集S)
物理存储器中数据块的共享状态被保存在一个称为目录的地方。
分布式目录:目录与存储器一起分布到各结点中,从而对于不同目录内容的访问可以在不同的结点进行。
目录法的实现方案:
1:最简单版本
对于存储器中每一块都在目录中设置一项。目录中的信息量与M×N成正比。
其中:
M:存储器的块数量
N:处理器的个数
由于M=K×N, K是每个处理机中存储块的数量,所以如果K保持不变,则目录中的信息量就与N^2成正比。
引入一些概念:
本地结点:发出访问请求的结点
宿主结点:包含所访问的存储单元及其目录项的结点
远程结点可以和宿主结点是同一个结点,也可以不是同一个结点。
节点之间的消息发送:
(p是处理机,K是地址)
本地节点发送给宿主节点(p是处理机,K是地址)
1:读不命中:rdmiss(p,k)
处理机P读取地址为K的数据时不命中,请求宿主结点提供数据(块),并要求把P加入共享集(要求本地也要存储K的数据)。
2:写不命中wtmiss(p,k)
处理机P对地址K进行写入时不命中,请求宿主结点提供数据,并使P成为所访问数据块的独占者。
3:写命中Invalidate(K)
请求向所有拥有相应数据块副本(包含地址K)的远程Cache发Invalidate消息,作废这些副本。
宿主节点发送给远程节点
1:本地节点写命中:Invalidate(K)
作废远程Cache中包含地址K的数据块。
2:本地节点读不命中,远程节点独占 :Fetch(K)
从远程Cache中取出包含地址K的数据块,并将之送到宿主结点和存储器。把远程Cache中那个块的状态改为“共享”
3:本地节点写不命中,远程节点独占 :Fetch&Inv(K)
从远程Cache中取出包含地址K的数据块,并将之送到宿主结点和存储器。然后作废远程Cache中的那个块。
宿主节点发送给本地节点:
1:本地节点读orr写不命中 DReply(D)
D表示数据内容。
把从宿主存储器获得的数据返回给本地Cache。
远程节点发送给宿主节点
1:本地节点读写不命中,且远程独占WtBack(K,D)
把远程Cache中包含地址K的数据块写回到宿主结点中, 该消息是远程结点对宿主结点发来的“取数据”或“取/作废”消息的响应。
本地节点发送给被替换块的宿主节点的信息
1:本地节点读/写不命中,发生替换,被替换的Cache块状态为共享
MdSharer(P,K)
用于当本地Cache中需要替换一个包含地址K的块、且该块未被修改过但是存有其他块的S信息orM嘻嘻的情况。这个消息发给该块的宿主结点,请求它将P从共享集中删除。如果删除后共享集变为空集,则宿主结点还要将该块的状态改变为“未缓存”(U)。
2:本地节点读/写不命中,发生替换,本地节点Cache块状态为M
WtBack2(P,K,D)
用于当本地Cache中需要替换一个包含地址K的块、且该块已被修改过的情况。这个消息发给该块的宿主结点,完成两步操作:①把该块写回;②进行与MdSharer相同的操作。
在基于目录的协议中,目录承担了一致性协议操作的主要功能。
1;本地结点把请求发给宿主结点中的目录,再由目录控制器有选择地向远程结点发出相应的消息。
2;发出的消息会产生两种不同类型的动作:1更新目录状态;2使远程结点完成相应的操作
目录协议中的存储块状态:
未缓冲:该块尚未被调入Cache。所有处理器的Cache中都没有这个块的副本。
共享:该块在一个或多个处理机上有这个块的副本,且这些副本与存储器中的该块相同。
独占:仅有一个处理机有这个块的副本,且该处理机已经对其进行了写操作,所以其内容是最新的,而存储器中该块的数据已过时。(这个处理机称为该块的拥有者。)
(这个独占不光指的事内存,也有存储器)
目录的状态以及相关的操作:
对于本地翻来的消息:1,向远程结点发送消息以完成相应的操作。这些远程结点由共享集合指出;2修改目录中该块的状态;3更新共享集合。
本地可能发送5个消息:
1-读不命中 (针对请求数据)
2-写不命中(针对请求数据)
3-作废(写命中时)(针对请求数据)
4-从共享集合中删除(针对替换数据)
5-本地数据写回(针对替换数据)
CPU读命中和读不命中:
思考:
I读不命中,尝试去接受共享rdMiss->S,
I不可能读命中
S读命中就还是S,
S读不命中发个消息Rdmiss,然后当前块被替换,这个cpu加入到共享集
M读命中,还是M
M读不命中,会被替换,所以要写回(Rtback2)然后其wtMiss,要求别人共享给他(共享的这个人:S or M or 存储器, 如果是 M的话也要写回)
CPU的写命中和写不命中:
思考:
I不可能写命中。
I如果写不命中,会发出Wtmiss(要求别人去共享or 存储器去读),->M
S写命中,那么其他的share的这个版本的就应该被作废,发出Invalidate
S写不命中,会要求把cpu提出原本的共享集,Mdsharer,然后发Wtmiss,要求别人共享,然后写
M写命中,没啥变化
M写不命中,会要求页替换发送Wtback2,然后发Wtmiss
去思考一下远程节点方的变化
也就收到fetch,fetch&inv,wtback,Invalidate,
I不会接受到什么,
S接受到I会变成无效
M接收到Fetch(要求写回数据),会写回Wtback保证cache和内存一致,然后->S
M接受到Fev&Inv(写回并且要求让数据无效),数值无效了,但是要同步给内存
太多了,
临时总结:
本地cache块
I在本地,只可能读写不命中
S和M4个情况都可能
看看远程节点尼:
M要不就是让他共享 or 共享然后无效
I没有让他能做的啥
S可能会因为别人写,然后无效
看看存储块*****:
存储块就只有三个状态(未缓存,共享,独占)
可能收到本地节点的读不命中
如果是本地未缓存,发送DReply,把需要的数据送回去,然后变成S(唯一共享节点)
如果是Shared(但是目标的东西没有加入共享),发出DReply,然后目标P加入共享集合
如果是独占,将fetch发给拥有者,然后将它所返回给宿主结点的数据写入存储器,并进而把该数据送回本地处理机,将本地处理机加入共享集合。(不独占了就写回,保持一致)
收到本地节点的写不命中
U:发DReply,先去取过来,然后再写,把P加入共享(此时只有P一个,且和磁盘的不一样)
如果该块是E(肯定不在P上,不然就是写命中),那么就会让这个块的拥有者写回存储器,然后取回并作废这个数据(Fet&Inv)写回,然后原集合置空,自己再去写,然后更新共享集合(P)
如果该块是S(肯定我们自己没共享),那么这个块会先取回这个块,然后让共享的or全部作废,然后独占,
如果收到了本地节点的作废
思考什么时候会发出作废?写命中会吗?(只会SorM可能写命中,M不会发,S会发)
本质就是作废掉原来的共享集合,所有只有S会收到
如果收到了远程节点的写回
只有E会收到,一般是M写不命中的时候会发出
如果收到了Mdshare(丛集合中删除)
可能删除之后集合变成了空,如果不是空,那么这个块只是少了一个
一些总结
如果一个块是未缓存状态的话,可以回接受到读不命中和写不命中
RdMiss(读不命中)
将所要访问的存储器数据送往请求方处理机,且该处理机成为该块的唯一共享结点,本块的状态变成共享。(不是独占,独占有个和存储器不一样的意思)
WtMiss(写不命中)
将所要访问的存储器数据送往请求方处理机,该块的状态变成独占,表示该块仅存在唯一的副本。其共享集合仅包含该处理机,指出该处理机是其拥有者。
当一个块处于共享状态时,其在存储器中的数据是当前最新的,对该块发出的请求及其处理操作为:(暗含了和存储器一致)
RdMiss
将存储器数据送往请求方处理机,并将其加入共享集合。
WtMiss
将数据送往请求方处理机,对共享集合中所有的处理机发送作废消息,且将共享集合改为仅含有该处理机,该块的状态变为独占。
Invalidate
对共享集合中除请求方以外的所有的处理机发送作废消息,且将共享集合改为仅含有该处理机,该块的状态变为独占。
MdSharer
将请求方处理机从共享集合中删除,如果共享集合变为空,该块的状态变为未缓冲。
当某块处于独占状态时,该块的最新值保存在共享集合所指出的唯一处理机(拥有者)中。有三种可能的请求:
RdMiss
将“取数据”的消息发往拥有者处理机,将它所返回给宿主结点的数据写入存储器,并进而把该数据送回请求方处理机,将请求方处理机加入共享集合。
此时共享集合中仍保留原拥有者处理机(因为它仍有一个可读的副本)。
将该块的状态变为共享。
WtMiss
该块将有一个新的拥有者。
给旧的拥有者处理机发送消息,要求它将数据块送回宿主结点写入存储器,然后再从该结点送给请求方处理机。
同时还要把旧拥有者处理机中的该块作废。把请求处理机加入共享者集合,使之成为新的拥有者。
该块的状态仍旧是独占。
WtBack2(写回)
当一个块的拥有者处理机要从其Cache中把该块替换出去时,必须将该块写回其宿主结点的存储器中,从而使存储器中相应的块中存放的数据是最新的(宿主结点实际上成为拥有者);
该块的状态变成未缓冲,其共享集合为空。(结合看看M收到写不命中的时候是不是就是发出一个写回加上一个Wtmiss)
请求数据
替换数据:
结合过程来看:
流程来看:
存储器读不命中:
P去读取K上的数据,K没有缓存,远程节点也没有,从主存读入然后发给本地cache
如果原本是共享的集合
一样的思想,选择从远程节点or主存拿到,然后把P加入共享,继续
如果原来的S有一个数据,且是在共享,但是目标数据是未缓存
选择先删除mdsharer,然后拿到未缓存数据后发给P,P加入共享集
如果当前数据是shared的,但是只有这一个,
如果当前数据是:共享,但是目标数的位置在目录中是独占
写回当前的独占,然后共享另外一个独占,两个写回
看看写不命中:
看看写命中:
太多了
目录的三种结构:
(不同的目录协议的区别在存储器块的状态和个数不同,目录结构的不同)
分为全映像目录,有限映像目录和链式目录
全映像目录:
优点:处理比较简单,速度也比较快。
缺点:
存储空间的开销很大。
目录项的数目与处理机的个数N成正比,而目录项的大小(位数)也与N成正比,因此目录所占用的空间与N2成正比。
可扩放性很差。
(下图是一项)
有限映像目录:
(希望提高扩放性和减少空间占用)
核心思想:采用位数固定的目录项目
限制同一数据块在所有Cache中的副本总数。
例如,限定为常数m。则目录项中用于表示共享集合所需的二进制位数为:m×log2N。
目录所占用的空间与N×[log2N]成正比。
缺点: 当同一数据的副本个数大于m时,必须做特殊处理。当目录项中的m个指针都已经全被占满,而某处理机又需要新调入该块时,就需要在其m个指针中选择一个,将之驱逐,以便腾出位置,存放指向新调入块的处理机的指针。
链式目录:
用一个目录指针链表来表示共享集合。当一个数据块的副本数增加(或减少)时,其指针链表就跟着变长(或变短)。
由于链表的长度不受限制,因而带来了以下优点:既不限制副本的个数,又保持了可扩展性。
链式目录的两个实现方法:
单链法:当Cache中的块被替换出去时,需要对相应的链表进行操作——把相应的链表元素(假设是链表中的第i个)删除。实现方法有以下两种:
遍历,找到第i个,单独删除第i个
遍历找到第i个,删除第i个及其之后的
双链法:
在替换时不需要遍历整个链表。
节省了处理时间,但其指针增加了一倍,而且一致性协议也更复杂了。