实验八:多Cache一致性的模拟分析
一、实验目的
1:加深对多 Cache 一致性的理解。
2:进一步掌握解决多 Cache一致性的目录协议和监听协议的基本思想。
3:掌握在各种情况下, 目录协议和监听协议是如何工作的,能给出要进行什么样的操作以及 状态的变化情况。
二、实验平台
多 Cache一致性目录协议模拟器和监听协议模拟器
三、实验内容和步骤
Part I:多 Cache 一致性目录协议的模拟与分析
1:掌握多 Cache一致性目录协议模拟器的使用方法
点击【帮助】——【使用说明】,即可查看目录法模拟器的使用方法。
【0:基本显示】
该模拟器模拟4个CPU(A、B、C、D)访存的工作过程。每个CPU中都有一个Cache,该Cache包含4个块,其块地址为0~3。分布式共享存储器中有32个块,其块地址为0~31。Cache中每个块的状态用色块来表示,其中灰色表示“无效”状态,淡青色表示“共享”,橘红色表示“独占”。主存中块的状态由其右边的目录项的颜色来表示,未缓冲状态由黄色来表示,其他两种状态同Cache块。
对于每个CPU,可以指定所要进行的访问是读还是写(从列表中选),并在输入框中输入所要访问的主存块号,然后用鼠标点击在其右边的标有+的按钮,模拟器就将开始演示该在执行过程中,模拟器会在窗口的左上角显示相关的信息。
该模拟器的主菜单有4个:配置,操作,统计,帮助。
【1:配置】
该菜单用于进行配置参数的显示与设置。你可以修改动画播放速度:把游标往右边拖搜可提高播放速度,往左边拖拽可降低播放速度。你还可以选择是否进行优化传块。优化传块是指当要访问的块在某个Cache中,且处于独占状态时,可以不用等该块写回主存后再从主存调块,而是可以直接将该块传送给发出访问请求的结点。
本模拟器采用直接映象方法和写回法。
【2:操作】
可以通过该菜单中的选项来控制模拟器的执行。该菜单下有以下3个选项:单步执行、连续执行、复位。
- 单步执行:选用该方式后,点击鼠标或点击左上角的“步进”按钮,都会使模拟器前进一步。
- 连续执行:选用该方式后,用鼠标点击标有+的按钮,模拟器会连续演示整个过程,直至该访问结束。
- 复位:使模拟器复位,回到初始状态。
【3:统计】
该菜单用于显示模拟器的统计结果,包括各处理机的访问次数、命中次数、不命中次数以及命中率。
【4:帮助】
该菜单下有“关于”和“使用说明”两个选项。
2:对于以下访问序列, 写出目录协议所进行的操作
所进行的访问 | 目录协议所进行的操作 |
CPU A 读第 6 块 | CPU读Cache A Cache A不命中 本地向宿主发读不命中(A,6)消息 宿主把数据块送给本地 共享集合为{A} CPU读Cache A第2行 |
CPU B 读第 6 块 | CPU读Cache B Cache B不命中 本地向宿主发读不命中(B,6)消息 宿主把数据块送给本地 共享集合为{A,B} CPU读Cache B第2行 |
CPU D 读第 6 块 | CPU读Cache D Cache D不命中 本地向宿主发读不命中(D,6)消息 宿主把数据块送给本地 共享集合为{A,B,D} CPU读Cache D第2行 |
CPU B 写第 6 块 | CPU写Cache B Cache B命中 本地向宿主发写命中(B,6)消息 宿主向远程结点A发作废(6)消息 宿主向远程结点D发作废(6)消息 共享集合为{B} CPU写Cache B第2行 |
CPU C 读第 6 块 | CPU读Cache C Cache C不命中 本地向宿主结点发读不命中(C,6)消息 宿主给远程发取数据块(6)的消息(写回) 远程把数据块送给宿主结点(写回ing) 宿主把数据块送给本地结点(写回主存后再写cache) 共享集合为{B,C} CPU读Cache C第2行 |
CPU D 写第 20 块 | CPU写Cache D Cache D不命中 本地向宿主结点发写不命中(D,20)消息 宿主把数据块送给本地结点 共享集合为{D} CPU写Cache D第0行 |
CPU A 写第 20 块 | CPU写Cache A Cache A不命中 本地向宿主结点发写不命中(A,20)消息 宿主给远程结点发送取并作废(20)的消息 远程把数据块送给宿主结点(写回),把Cache中的该块作废 宿主把数据块送给本地结点 共享集合为{A} CPU写Cache A第0行 |
CPU D 写第 6 块 | CPU写Cache D Cache D不命中 本地向宿主结点发写不命中(D,6)消息 宿主给远程结点发送取并作废(6)的消息 宿主给远程结点发送取并作废(6)的消息 宿主把数据块送给本地结点 共享集合为{D} CPU写Cache D第2行 |
CPU A 读第 12 块 | CPU读Cache A Cache A不命中 本地向被替换块的宿主结点发写回(替换第20块后需要写回,因为只有1个副本)并修改共享集(A,20)消息 本地向宿主结点发读不命中(A,12)消息 宿主把数据块送给本地结点 共享集合为{A} CPU读Cache A第0行 |
【访问序列】
【Cache模拟器统计信息】
3:自己编写一个访问序列, 写出目录协议所进行的操作
所进行的访问 | 是否发生替换 | 是否发生写回 | 目录协议所进行的操作 |
CPU A 读第 5 块 | 否 | 否 | 读cache A,不命中 本地:向宿主结点发读不命中(A,5)消息 宿主:把数据块送给本地结点 共享集合为:{A} 数据送入cache A的第1行,由CPU A读取 |
CPU B 读第 5 块 | 否 | 否 | 读cache B,不命中 本地:向宿主结点发读不命中(B,5)消息 宿主:把数据块送给本地结点 共享集合为:{A,B} 数据送入cache B的第1行,由CPU B读取 |
CPU C 读第 5 块 | 否 | 否 | 读cache C,不命中 本地:向宿主结点发读不命中(C,5)消息 宿主:把数据块送给本地结点 共享集合为:{A,B,C} 数据送入cache C的第1行,由CPU C读取 |
CPU B 写第 5 块 | 否 | 否 | 写cache B,命中 本地:向宿主结点发写命中(B,5)消息 宿主:向远程结点A发作废(5)消息 宿主:向远程结点C发作废(5)消息 共享集合为:{B} CPU B写cache B第1行【独占】 |
CPU D 读第 5 块 | 否 | 是 | 读cache D,不命中 本地:向宿主结点发读不命中(D,5)消息 宿主:给远程结点发取数据块(5)的消息 远程:把数据块送给宿主结点【cache B第1行对应的主存第5块,写回主存】 宿主:把数据块送给本地结点 共享集合为:{B,D} 数据送入cache D的第1行,由CPU D读取 |
CPU B 写第 21 块 | 是 | 否 | 写cache B,不命中 本地:向被替换块的宿主结点发修改共享集(B,5)消息【cache B第1行对应的主存第5块替换为第21块】 本地:向宿主结点发写不命中(B,21)消息 宿主:把数据块送给本地结点 共享集合为:{B} CPU B写cache B第1行【独占】 |
CPU A 写第 23 块 | 否 | 否 | 写cache A,不命中 本地:向宿主结点发写不命中(A,23)消息 宿主:把数据块送给本地结点 共享集合为:{A} CPU A写cache A第3行【独占】 |
CPU C 写第 23 块 | 否 | 是 | 写cache C,不命中 本地:向宿主结点发写不命中(C,23)消息 宿主:给远程结点发送取并作废(23)的消息 远程:把数据块送给宿主结点,把cache中的该块作废【cache A第3行对应的主存第23块,写回主存】 宿主:把数据块送给本地结点 共享集合为:{C} CPU C写cache C第3行【独占】 |
CPU B 读第 29 块 | 是 | 是 | 读cache B,不命中 本地:向被替换块的宿主结点发写回并修改共享集(B,21)消息【cache B第1行对应的主存第21块替换为第29块,并写回主存第21块】 本地:向宿主结点发读不命中(B,29)消息 宿主:把数据块送给本地结点 共享集合为:{B} 数据送入cache B的第1行,由CPU B读取 |
CPU B 写第 5 块 | 是 | 否 | 写cache B,不命中 本地:向被替换块的宿主结点发修改共享集(B,29)消息【cache B第1行对应的主存第29块替换为第5块】 本地:向宿主结点发写不命中(B,5)消息 宿主:向远程结点发作废(5)消息 宿主:把数据块送给本地结点 共享集合为:{B} CPU B写cache B第1行【独占】 |
【访问序列】
【Cache模拟器统计信息】
4:根据上述结果,画出相关的状态转换图(仅画出与上表有关的部分)
5:目录协议的基本思想是什么?
目录协议的核心:物理存储器中共享数据块的状态及相关信息存在目录中。
PART II:多 Cache 一致性监听协议的模拟与分析
1:掌握多 Cache 一致性监听协议模拟器的使用方法
点击【帮助】——【使用说明】,即可查看目录法模拟器的使用方法。
2:对于以下访问序列,写出监听协议所进行的操作
所进行的访问 | 是否发生替换 | 是否发生写回 | 监听协议所进行的操作 |
CPU A 读第 5 块 | 否 | 否 | CPU读Cache A Cache A不命中 总线不命中 数据从存储器第5块送入Cache A第1块 CPU读Cache A第1块,显示共享 |
CPU B 读第 5 块 | 否 | 否 | CPU读Cache B Cache B不命中 总线不命中 数据从存储器第5块送入Cache B第1块 CPU读Cache B第1块,显示共享 |
CPU C 读第 5 块 | 否 | 否 | CPU读Cache C Cache C不命中 总线不命中 数据从存储器第5块送入Cache C第1块 CPU读Cache C第1块,显示共享 |
CPU B 写第 5 块 | 否 | 否 | CPU写Cache B Cache B命中 总线作废 Cache A第1块和Cache B第1块作废 存储器第5块tag,送入Cache B第1块 CPU写Cache B第1块,显示独占 |
CPU D 读第 5 块 | 否 | 是 | CPU读Cache D Cache D不命中 Cache B写回存储器第5块 数据从存储器第5块送入Cache D第1块 CPU读Cache D第1块,显示共享 Cache B第1块,显示共享 |
CPU B 写第 21 块 | 是 | 否 | CPU写Cache B Cache B不命中 总线写不命中 存储器第21块tag,送入Cache B第1块,发生块内替换 CPU写Cache B第1块,显示独占 |
CPU A 写第 23 块 | 否 | 否 | CPU写Cache A Cache A不命中 总线写不命中 存储器第23块tag,送入Cache A第3块 CPU写Cache A第3块,显示独占 |
CPU C 写第 23 块 | 否 | 是 | CPU写Cache C Cache C不命中 总线写不命中 Cache A写回存储器第23块 存储器第23块tag,送入Cache C第3块 CPU写Cache C第3块,显示独占 |
CPU B 读第 29 块 | 是 | 是 | CPU读Cache B Cache B不命中 Cache B写回存储器第21块 总线读不命中 数据从存储器第29块送入Cache B第1块,发生块内替换 CPU读Cache B第1块,显示共享 |
CPU B 写第 5 块 | 是 | 否 | CPU写Cache B Cache B不命中 总线写不命中 存储器第5块tag,送入Cache B第1块 总线作废Cache C第1块 CPU写Cache B第1块,显示独占 |
【访问序列】
【Cache模拟器统计信息】
3:自己编写一个访问序列, 写出监听协议所进行的操作
所进行的访问 | 是否发生替换 | 是否发生写回 | 监听协议所进行的操作 |
CPU A 读第 6 块 | 否 | 否 | 读cache A,不命中 向总线发送不命中 数据从存储器第6块送入cache A第2行 CPU A读cache A第1行,显示共享 |
CPU B 读第 6 块 | 否 | 否 | 读cache B,不命中 向总线发送不命中 数据从存储器第6块送入cache B第2行 CPU B读cache B第1行,显示共享 |
CPU D 读第 6 块 | 否 | 否 | 读cache D,不命中 向总线发送不命中 数据从存储器第6块送入cache D第2行 CPU D读cache D第1行,显示共享 |
CPU B 写第 6 块 | 否 | 否 | 写cache B,命中 向总线发送(6)作废消息 作废掉cache A第2行、cache D第2行 CPU B写cache B第2行,显示独占 |
CPU C 读第 6 块 | 否 | 是 | 读cache C,不命中 向总线发送不命中 将cache B第2行对应的(6)写回存储器 数据从存储器第6块送入cache C第2行 CPU C读cache C第2行,显示共享 |
CPU D 写第 20 块 | 否 | 否 | 写cache D,不命中 向总线发送不命中 数据从存储器第20块送入cache D第0行 CPU D写cache D第0行,显示独占 |
CPU A 写第 20 块 | 否 | 是 | 写cache A,不命中 向总线发送不命中 将cache D第0行对应的(20)写回存储器 作废掉cache D第0行 数据从存储器第20块送入cache A第0行 CPU A写cache A第0行,显示独占 |
CPU D 写第 6 块 | 否 | 否 | 写cache D,不命中 向总线发送不命中 数据从存储器第6块送入cache D第2行 作废掉cache B第2行、cache C第2行 CPU D写cache D第2行,显示独占 |
CPU A 读第 12 块 | 是 | 是 | 读cache A,不命中 将cache A第0行对应的(20)写回存储器 向总线发送不命中 数据从存储器第12块送入cache A第0行 CPU A读cache A第0行,显示共享 |
【访问顺序】
【Cache模拟器统计信息】
4:根据上述结果,画出相关的状态转换图(仅画出与上表有关的部分)
5:监听协议的基本思想是什么?
监听协议的核心:Cache中保存各块的共享状态,共享总线,总线监听。
四、实验总结
1:监听协议是基于总线的。在监听协议中,所有的缓存控制器都通过总线来监听其他缓存控制器的操作。当一个缓存控制器修改了共享数据时,它会通过总线发送一个信号,让其他缓存控制器将对应的缓存行置为无效。这样,其他缓存控制器在需要访问这个缓存行时,就会重新从内存中读取最新的数据,保证了数据的一致性。
2:目录协议是集中式的。在目录协议中,每个缓存控制器都维护了一个目录表,用于记录共享数据的状态和位置。当一个缓存控制器修改了共享数据时,它会向目录表发送一个更新请求,将对应的缓存行置为无效或者共享状态。其他缓存控制器在需要访问这个缓存行时,需要先向目录表发出请求,获取该数据的状态和位置信息,然后根据相应的状态进行操作。
3:监听协议的特点分析:
优点:核数较少时,总线压力较小,成本低,效果好。
缺点:需要通过总线广播一致性相关信息. 总线上能够连接的处理器数目有限。当核数增多时,总线冲突增加, 监听带宽成为瓶颈。
4:目录协议的特点分析:
优点:使用集中目录来记录每个cache块的状态,不需要总线广播一致性信息, 总线压力小。
缺点:需要维护目录数据结构, 随着核数增加时目录的开销变大。
5:在设计和选择cache一致性协议时,需要综合考虑系统规模、性能需求、开销以及硬件限制等方面的因素。不同的协议适用于不同的场景。
6:实现cache一致性的关键——跟踪记录共享数据块的状态。