Cache 分配策略 & 更新策略
- 参考
- https://zhuanlan.zhihu.com/p/102293437
- 《计算机组成与设计 第五版》
1. 分配策略
- 分配策略是指什么情况需要为数据分配cache line。
- 读分配
- 当CPU读数据时,cache缺失,分配一个cache line来缓存从主存中取出的数据。
- 写分配
- 场景:CPU写数据时,cache缺失。
- 当不支持写分配时,写指令直接更新主存的数据。例如:对某一页内存进行初始化操作(全部写0),此时就没必要将对应数据写入cache中。
- 支持写分配时,会首先将主存中的数据加载到cache line中,(变成命中),然后更新cache line的数据/主存的数据。
2. 更新策略
- 更新策略是指当cache命中时,写操作如何更新数据。
- 写直通(Write Through)
- 例如,CPU执行store指令,且cache命中,首先更新cache中的数据,并更新主存中的数据。cache 和主存的数据保持一致。
- 但是性能不佳,因为每次写操作都会引起写主存的操作,这个延时是比较大的,至少100个处理器时钟周期,大大降低处理器性能。
- 上面描述情况的解决方案是:write buffer
- 数据写入cache的同时也写入写缓冲中,之后处理器继续执行。
- 写缓冲不断向主存中写入数据,如果写缓冲满了,那么处理器必须停顿流水线直到写缓冲中出现空闲表项。
- 我认为有点类似乒乓操作。
- 如果主存写操作的速率小于处理器产生写操作的速率,那么多大容量的缓冲都没用,都会很快就满了。
- 即使处理器产生写操作的写速率小于主存写操作速率,也可能会产生停顿,例如出现写burst传输时,此时可以增加写缓冲容量解决。
- 写回(Write Back)
- 仍是CPU执行store指令,且cache命中,我们只更新cache中的数据,而不立即写入主存,此时cache和主存的数据不一致。
- cache line有1个bit(dirty bit)用于记录数据是否被修改过。
- 当cache中的数据要被替换(如:出现写失效),才会写回主存中。
- 需要实现一个write-back buffer。
- 在出现写失效时,需要根据dirty bit判断是否要将cache line中的数据写回到主存中。
- 在主存读取需要填充到cache中的数据时,将cache line中的数据写入write-back buffer中。
- 之后再由buffer写入主存中。
- 写回 & 写直通
- 写直通的写操作可以在一个周期内完成,读取标签的同时将数据写入对应的数据块。
- 如果tag匹配,那么完成写操作,处理器继续执行。
- 如果tag不匹配,那么产生写失效,将主存中对应地址的数据取出送到cache中。
- 写回的写操作至少需要两个周期去处理:第一个周期用于判断tag是否命中,若命中则第二个周期进行cache写操作。
- 不能一个周期就完成的原因:如果在第一个周期就将数据写入,如果tag没有命中,会导致cacheline原有数据未来得及写回主存中,导致数据被破坏。
- 也可以像写直通一样实现一个store buffer。
- 第一个周期,将数据写入store buffer中,同时查找cache,判断是否命中。
- 如果命中,在下一个无用的cache访问周期将新数据从buffer中写入cache。
- 写直通的写操作可以在一个周期内完成,读取标签的同时将数据写入对应的数据块。
3. 实例
- 具体内容可以看这篇文章中的实例。
- 这里只列出我觉得需要特殊注意的地方
- 当发现cache缺失时,会出现CPU从主存中取数据给cache line的情况,此时需要注意dirty bit是否被拉高。
- 如果该bit被拉高,那么cache的数据不能直接覆盖,说明这个数据对应的地址之前发生过写回操作,并没有同步到主存中,如果直接覆盖则会丢失这部分的数据。
- 将被替换这部分数据写回至主存中。
- 将主存中0x28地址(cache line地址对齐,这里应该要被8整除)开始的8个数据写入cache line中,并清除掉dirty bit,将offset找到的数据返回给CPU。
- 当发现cache缺失时,会出现CPU从主存中取数据给cache line的情况,此时需要注意dirty bit是否被拉高。
4. Cache 性能评估
- $ CPU时间 = (CPU执行的时钟周期数 + 等待存储访问的时钟周期数) * 时钟周期 $
- 假设等待存储访问的时钟周期数主要来自于cache引起的,下面根据读和写分开讨论。
- 读操作带来的停顿周期数 只由读失效带来。\[读操作带来的停顿周期数=\frac{读操作数目}{程序}*\frac{读失效次数}{指令数目}*读失效代价 \]
- 写操作带来的停顿周期数
- 写直通策略
- 有两个停顿的来源,写失效和写缓冲停顿。后者为buffer满时仍进行写操作引发的停顿。
\[写操作带来的停顿周期数 = \frac{写操作数目}{程序}*\frac{写失效次数}{指令数目}*写失效代价+写缓冲满时的停顿周期 \] - 写回策略
- 停顿主要来源于cache line要被替换,并需要将原数据写回主存中。
- 写直通策略
- 读操作带来的停顿周期数 只由读失效带来。
- 前面介绍是未命中时对性能的影响,但是除了失效率,还有命中时间也会对性能有很大的影响。
- 举例:增大Cache的容量(主要是Cache line的个数),更大的Cache需要更久的命中时间。这个命中时间可以算在CPU执行的时钟周期数上。
- 定义 平均存储访问时间(AMAT) 将Cache的命中时间也考虑在内,公式如下。\[AMAT = 命中时间+失效率*失效代价 \]