使用相同的标记和偏移位访问和更新 2 路关联缓存

Accessing and updating 2-way associative cache with same tag and offset bits

我对如何在 2 路关联缓存上访问数据感到困惑。

例如,C = ABS

C = 32KB
A = 2
B = 32bits
S = 256

offset = lg(B) = 5
index = lg(S) = 8
tag = 32 - offset - index = 19

假设我有我有以下地址

tag                    | index    | offset
1000 0000 0000 0000 000|0 0000 000|1 0000
1000 0000 0000 0000 000|0 0000 000|0 0000
1000 0000 0000 0000 000|0 0000 000|1 1010

我的缓存看起来像

index   valid dirty tag      data            valid dirty tag     data
0:      1     0     0x80...   some data1     1     0     0x80... some data2
1:         .                                     .
2:         .                                     .  
3:         .                                     .

当索引位和标记位相同时,如何确定应该从两个缓存数组中的哪一个(data1 与 data2)获取数据?

同样,当我需要使用相同的索引和标记位更新缓存时,如何确定我应该踢出两个数组中的哪些数据?

我认为它与偏移位有关,但我不太确定如何使用偏移位或者它们在缓存数组中究竟代表什么或映射到什么。

How do I determine which of the two cache array I should take the data from (data1 vs data2) when the index and tag bits are the same?

您的缓存是如何进入这种状态的?具有相同索引和标记的访问将命中而不是分配第二个条目。

由于 homonym or synonym problems caused by virtual indexing (or tagging),可能会在缓存中出现两次相同的物理内存行(具有不同的索引或标记),但这种情况在正确设计的缓存中是不可能的。


how do I determine which of the data in the two array I should kick out when I need to update the cache with the same index and tag bits?

在这种情况下你不驱逐;这是缓存命中。

索引select是一组标签。这 2 个标签(在您的情况下)与地址的标签位匹配。如果一个匹配,那就是一个成功。如果没有,那就是失手了。


因此,当您需要驱逐现有行之一时,具有相同索引但 不同标记 的访问。 The usual replacement policy is LRU。实现这一点的一种方法是让集合中的位置变得重要。每次访问一行时,它的标签都会移动到 MRU 位置。当必须从集合中逐出一行时,将逐出 LRU 位置。这将是最近访问最少的行。

通常新添加的行会进入 MRU 位置,但是自适应地添加到 LRU 位置可以避免在循环巨型数组时驱逐有价值的数据。请参阅 this blog post about Intel IvyBridge's adaptive L3 replacement policy 进行一些巧妙的实验测试以研究硬件行为,以及一些很好的解释。


I am thinking it has to do with the offset bits

不,一行中的偏移位 select 字节。 hit/miss/replacement 不关心这个。缓存访问硬件使用偏移量和大小来 select 在找到正确的行后要读取或更新的字节范围。