计算机组成原理,直接映射方式的cache中,cache的行号是怎么
发布网友
发布时间:2024-09-27 03:15
我来回答
共1个回答
热心网友
时间:2024-10-28 07:41
在直接映射方式的cache中,cache的行号是由tag、index和offset三部分共同决定的。以48位宽的地址为例,每一行cache line对应一个唯一的tag,tag保存的是除去index和offset使用位后的剩余地址位宽部分。cache line大小设定为8 Bytes,故利用地址的低3位来寻址8 Bytes中的某一字节,这部分组合称为offset。由于有8行cache line,为了覆盖所有行,需要使用3位地址部分作为index。tag、index和offset三者结合即可唯一确定一个cache地址。使用下图来直观展示。
直接映射缓存,顾名思义,缓存的大小即为cache size,代表可以缓存的最大数据量。缓存被平均分成相等的块,每块大小称为cache line,通常大小为4-128 Bytes。比如64 Bytes大小的缓存,可被均分为64个字节块(cache line),或者8个8字节块,以此类推。cache线是缓存与主存之间传输数据的最小单位。当CPU尝试加载一个字节数据时,如果缓存缺失,缓存控制器会一次性从主存加载一个cache line大小的数据到缓存中。比如,如果cache line大小为8字节,即使CPU仅读取一个字节,在缓存缺失后,也会从主存加载8字节以填充整个cache line。
假设缓存大小为64 Bytes,且cache line大小为8字节,可以将这块缓存想象为一个数组,共有8个元素,每个元素大小为8字节。现在,假设CPU从地址0x0654读取一个字节,缓存控制器是如何判断数据是否在缓存中命中呢?缓存相对于主存而言非常小,因此只能缓存主存中极小一部分数据。如何在有限大小的缓存中查找数据?现代硬件采用地址散列的方式。接下来,我们看看如何实现这一过程。
我们有8行cache line,cache line大小是8 Bytes。因此,可以利用地址的低3位(图中蓝色部分)来寻址8 bytes中的某一字节,这部分组合被称为offset。同样,为了覆盖所有行,需要使用3位地址部分(图中*部分)查找某一行,这部分地址称为index。这意味着,如果两个不同的地址的位3-bit5完全相同,那么它们经过硬件散列后会找到同一个cache line。因此,在找到cache line后,只能说明访问的地址对应的数据可能存在于这个cache line中,但有可能是其他地址对应的数据。因此,引入了tag array区域,与data array一一对应。
每一个cache line都对应一个唯一的tag,tag中保存了整个地址位宽去除index和offset使用的位剩余部分(图中绿色部分)。tag、index和offset三者组合可以唯一确定一个地址。因此,当根据地址中的index位找到cache line后,取出当前cache line对应的tag,然后与地址中的tag进行比较。如果相等,说明缓存命中;如果不相等,则说明当前cache line存储的是其他地址的数据,这就是缓存缺失。
在上述示例中,cache size为64 Bytes且cache line size为8 bytes。offset、index和tag分别使用3位、3位和42位(假设地址宽度为48位)。现在我们来看另一个例子:512 Bytes缓存大小,64 Bytes cache line大小。根据之前的地址划分方法,offset、index和tag分别使用6位、3位和39位(假设地址宽度为64位)。这样,我们可以画出主存地址0x00-0x88对应的cache分布图。
从图中可以看到,地址0x00-0x3f对应的数据覆盖整个缓存。0x40-0x7f对应的数据也覆盖整个缓存。现在,思考如果一个程序依次访问地址0x00、0x40、0x80会发生什么?首先,应明确0x00、0x40、0x80地址中index部分是一样的。这意味着这三个地址对应的cache line是相同的。
因此,访问0x00地址时,缓存会缺失,然后从主存加载数据到第0行cache line。访问0x40地址时,仍然索引到第0行cache line,但此时cache line中存储的是0x00地址对应的数据,因此仍然会缓存缺失。然后从主存加载0x40地址的数据到第一行cache line中。同样,访问0x80地址时,依然会缓存缺失。这意味着每次访问数据都要从主存中读取,缓存的存在并未提升性能。访问0x40地址时,会将0x00地址缓存的数据替换,这种现象称为缓存颠簸(cache thrashing)。