我目前正在研究经典的缓存模拟项目,可以使用一些帮助。我们的任务之一是实现带有下一行预取和LRU替换策略的n路集合关联缓存。到目前为止,这个任务的第一部分和第三部分还没有太大的问题,我有一个工作的n路集合关联缓存和一个工作的LRU策略。然而,下一行预取部分给我带来了一些麻烦。
所以在理论上,我认为我理解下一行预取应该如何工作:我们去访问我们的缓存,访问行X。现在,当我们在访问行X时,我们将继续将X+1带入缓存,现在由于空间局域性原则,在寻找X+1的可能性相当高的情况下,我们最终得到了命中而不是错过。此外,当我们将X+1带入缓存时,我们更新了我们的LRU,因此X+1是该集合最近访问的块。真正让我困惑的是实现它的实际方法和更精细的细节。当我们说X和X+1时,我们具体指的是缓存行的哪些部分?我们应该给下标加1吗?标签吗?整个内存地址?我也知道我们必须警惕溢出。项目指定了一个32字节的缓存行大小和一个16kb的缓存,所以根据我们添加1的位置,它可能会溢出并可能弄乱东西,所以我们也需要注意这一点,我想在某个地方添加一个额外的1,但我不太确定。如有任何帮助,我将不胜感激。
TL;博士:X+1中的X是什么,我们应该在整个地址上加1吗?只有标签位?只有索引?等。
地址空间中下一个32字节的缓存行。在加载地址X时,下一行包含地址X+32
,行大小为32。
可能最简单的实现它作为prefetch(address + linesize)
在线性地址空间中进行添加,并单独调用一个函数,将该地址分解为标签/索引。
但是假设一个简单的索引函数,是等于在索引上加1,如果索引归零,在标签上加进位。从窄添加手动执行携带传播并不比重做shift/and更容易。