缓存缺失计算问询:直接映射、2路组相联场景及数组起始地址含义
嘿,我来一步步帮你拆解这个问题——先把地址含义讲明白,再分别分析两种缓存策略下的缺失数~
先解释「A起始地址为0,B起始地址为16」的含义
因为题目里明确每个整数占4字节(也就是1字),所以:
- 数组A的4个元素对应的内存地址依次是:
0(A[0])、4(A[1])、8(A[2])、12(A[3]) - 数组B的4个元素对应的内存地址依次是:
16(B[0])、20(B[1])、24(B[2])、28(B[3])
另外补充缓存的基础参数:缓存总大小64字节,块大小1字(4字节),所以缓存一共能容纳 64 / 4 = 16 个缓存块;初始状态缓存为空,所有第一次访问的内存块都会触发缓存缺失。
a) 直接映射缓存的缺失数分析
直接映射缓存的核心规则是:缓存索引 = (内存块号) % 缓存总块数。这里的内存块号 = 内存地址 / 4(因为每个块占4字节),缓存总块数是16,所以可以简化为:索引 = (地址 / 4) % 16。
先计算每个元素对应的内存块号和缓存索引:
| 元素 | 内存地址 | 内存块号 | 缓存索引 |
|---|---|---|---|
| A[0] | 0 | 0 | 0%16=0 |
| A[1] | 4 | 1 | 1%16=1 |
| A[2] | 8 | 2 | 2%16=2 |
| A[3] | 12 | 3 | 3%16=3 |
| B[0] | 16 | 4 | 4%16=4 |
| B[1] | 20 | 5 | 5%16=5 |
| B[2] | 24 | 6 | 6%16=6 |
| B[3] | 28 | 7 | 7%16=7 |
接下来看循环执行过程:
外层循环i=0(第一次遍历):
缓存初始为空,所有元素都是第一次访问,每读一个元素就触发一次缺失:- j=0:读A[0](缺失)、读B[0](缺失)→ 2次缺失
- j=1:读A[1](缺失)、读B[1](缺失)→ 2次缺失
- j=2:读A[2](缺失)、读B[2](缺失)→ 2次缺失
- j=3:读A[3](缺失)、读B[3](缺失)→ 2次缺失
这一轮累计8次缺失,且所有A、B的元素都已经缓存到对应索引位置。
外层循环i=1(第二次遍历):
所有元素对应的缓存块都已经存在,所以每一次读取都命中缓存,没有缺失。
直接映射下总缓存缺失数:8次
b) 2路组相联缓存的缺失数分析
2路组相联缓存的规则是:
- 组数 = 缓存总块数 / 路数 = 16 / 2 = 8组
- 缓存索引 = (内存块号) % 组数 → 简化为
索引 = (地址 / 4) % 8
先计算每个元素对应的缓存索引:
| 元素 | 内存地址 | 内存块号 | 缓存索引 |
|---|---|---|---|
| A[0] | 0 | 0 | 0%8=0 |
| A[1] | 4 | 1 | 1%8=1 |
| A[2] | 8 | 2 | 2%8=2 |
| A[3] | 12 | 3 | 3%8=3 |
| B[0] | 16 | 4 | 4%8=4 |
| B[1] | 20 | 5 | 5%8=5 |
| B[2] | 24 | 6 | 6%8=6 |
| B[3] | 28 | 7 | 7%8=7 |
2路组相联中,每个组可以存储2个不同的内存块,只要组内还有空位,就不会替换已缓存的块。
循环执行过程:
外层循环i=0(第一次遍历):
缓存初始为空,所有元素第一次访问都触发缺失,累计8次缺失。此时每个组(0-7)都只缓存了一个对应的块(组0存A[0],组1存A[1]…组7存B[3]),每个组还有1个空位。外层循环i=1(第二次遍历):
所有元素对应的缓存块都已经存在于对应组中,所以每一次读取都命中缓存,没有缺失。
2路组相联下总缓存缺失数:8次
内容的提问来源于stack exchange,提问作者tal
相关产品推荐
相关产品推荐

