计算机体系结构,4 路缓存 hit/replacement 混乱

Computer architecture, 4-way cache hit/replacement confustion

我正在尝试在 verilog 中实现 4 路缓存,但我对缓存查找方案有些困惑。假设我有以下规格:

     C = ABS
        C = 1KB
        A = 4
        B = 128 bits (4 DWORD)
        S = C/AB = (8192)/(4*128) = 16

        offset = lg(B) = 7 bits
        index  = lg(S) = 4 bits
        tag    = 32 - offset - index = 21 bits

C: Capacity in data arrays
A: Way-Associativity
B: Block Size (Cacheline)
   How many bytes in a block
S: Number of Sets:
   A set contains blocks sharing the same index

在我的记忆中我有:

H  0000_0000   0000 0000 0000 0000 0000 0000 0|000 0|000 0000    
E  0000_0004
L  0000_0008
L  0000_000C
O  0000_0010   0000 0000 0000 0000 0000 0000 0|000 0|001 0000
   0000_0014
W  0000_0018
O  0000_001C
R  0000_0020   0000 0000 0000 0000 0000 0000 0|000 0|010 0000    
L  0000_0024
D  0000_0028
!  0000_002C

假设我是一个新的开始,我在地址 0x0000_0000 请求加载字,因为我的缓存是空的,我将 HELL 写入索引 0 上的缓存行之一4个数组。

然后我在地址0x0000_0010请求另一个加载字,此时我很困惑。

我的问题是,由于我的标签和索引相同,因此命中,但我的缓存行中没有 O 一词。在这种情况下我的缓存应该做什么?我是否踢出 HELL 并在同一个数组中写入 O WO?如果是这样,我应该如何区分这两个地址,因为我们只查看标记和索引位?

我的另一种想法是,既然它是命中的,那么缓存不应该因为我们找到了匹配项而被驱逐。但是那场比赛没有我要求的实际词。所以如果我不做替换这个逻辑是错误的,但是我的缓存是命中的。我刚刚进入了逐出和缓存命中之间的循环逻辑。

更新后,问题变得清晰:B 应该是以字节为单位的大小,但您使用了以位为单位的大小。地址中正确的偏移位数是 log2(16) = 4。如果将图中的 | 分隔符移动到正确的位置,一切都会正常进行:您会看到每个 16B 块都有一个比上一个高 1 的索引。

H  0000_0000   0000 0000 0000 0000 0000 0000|0000|0000    
E  0000_0004
L  0000_0008
L  0000_000C
O  0000_0010   0000 0000 0000 0000 0000 0000|0001|0000
   0000_0014
...

我还注意到你的地址是前 36 位,多了一个 0000 块。我也仔细检查了索引位的数量:4 个索引位意味着您的 16 组 4 种方式中的每一种。 16 * 4 * 16B = 1024B,所以这适合您的 1kiB 缓存。


您遇到了与 相同的问题,多个内存块进入同一缓存行,但原因不同。这表明您遇到了严重错误,因为一个缓存行必须始终足够大以保存具有相同标记+索引位的地址中的所有数据。