直接映射、组相连、全相联

文章介绍了直接映射高速缓存的工作原理,包括组选择、行匹配和字抽取步骤,讨论了冲突不命中和抖动现象。同时,解释了为何使用中间位作为索引以优化空间局部性。另外,对比了直接映射与组相联cache的差异,后者允许每个组包含多个cacheline,提高了缓存效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

直接映射高速缓存

判断是否命中,获取目标数据的过程一共分为三步,分别是组选择、行匹配以及字抽取

组选择:根据组索引进行

行匹配:对比tag值,因此,行匹配最终的结果无非就是命中或者不命中。命中后进行字抽取。

字抽取:通俗点讲,就是从数据块的什么位置开始抽取数据。

冲突不命中,抖动:x[0]~x[3]的块被加载回组0,覆盖掉y[0]~y[3]的块。因而现在我们就有了一个冲突不命中,而且实际上后面每次对×和y的引用都会导致冲突不命中,因为我们在x和y的块之
间抖动(thrash)。术语“抖动”描述的是这样一种情况,即高速缓存反复地加载和驱逐相同的高
速缓存块的组。

为什么用中间的位来做索引?
你也许会奇怪,为什么高速缓存用中间的位来作为组索引,而不是用高位。为什么用中间的位更好,是有很好的原因的。图6-33说明了原因。如果高位用做索引,那么一些连续的存储器块就会映射到相同的高速缓存块。例如,在图中,头四个块映射到第一个高速缓存组,第二个四个块映射到第二个组,依此类推。如果一个程序有良好的空间局部性,顺序扫描一个数组的元素,那么在任何时刻,高速缓存都只保存着一个块大小的数组内容。这样对高速缓存的使用效率很低。相比较而言,以中间位作为索引,相邻的块总是映射到不同的高速缓存行。在这种情况下,高速缓存能够存放整个大小为C的数组片,这里C是高速缓存的大小。

组相连

与直接映射不同,组相联cache的每个set允许包含多个cache line,1<E<C/B(C为cache大小,B为每个block大小)

### 缓存映射方式中的直接映射相连对比 #### 直接映射缓存 (Direct Mapped Cache) 在直接映射缓存中,每个主存块仅能映射到特定的一个缓存位置。这意味着如果两个不同的内存地址具有相同的索引位,则它们会竞争同一个缓存槽。这种设计简单易实现,硬件开销较小。 对于给定的内存地址,其对应的缓存行由该地址的一部分决定,这部分通常称为索引字段。由于一对一的关系,在查找过程中只需要比较标签部分即可确认是否存在命中情况[^1]。 ```python def direct_mapped_cache_lookup(address, cache): index = extract_index_bits(address) tag = extract_tag_bits(address) cached_line = cache[index] if cached_line.tag == tag and cached_line.valid: return "Hit" else: return "Miss" ``` #### 相联缓存 (Set Associative Cache) 相比之下,相联缓存提供了更高的灵活性。在这种结构下,每内含有多个页面(例如四个),允许来自不同区域的数据存储在同一集合内的任意位置。这减少了冲突的可能性并提高了性能。 具体来说,当访问某个物理地址时,先通过计算得出所属集号;之后再在这个集中逐一对比各个条目的标记来判断是否有匹配项存在。这种方式虽然增加了复杂度但是有效缓解了因频繁替换而导致的有效数据丢失问题。 ```python def set_associative_cache_lookup(address, cache_sets): set_number = calculate_set_number(address) tag = extract_tag_bits(address) current_set = cache_sets[set_number] for line in current_set.lines: if line.tag == tag and line.valid: return "Hit" return "Miss" ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值