在严格包含的缓存层次结构中处理缓存块大小的最常见技术是对强制包含属性的所有缓存级别使用相同大小的缓存块。与更高级别的缓存使用更大的块相比,这会导致更大的标签开销,这不仅会使用芯片面积,而且还会增加延迟,因为更高级别的缓存通常使用分阶段访问(在访问数据部分之前检查标签)。然而,它也在一定程度上简化了设计,并减少了数据未使用部分造成的容量浪费。它不需要在 128 字节缓存块中占用大部分未使用的 64 字节块来补偿额外 32 位标记的面积损失。此外,可以通过相对简单的预取来提供利用更广泛空间局部性的更大缓存块效果,
一种不太常见的技术将缓存块划分为扇区。将扇区大小与较低级别缓存的块大小相同可以避免过度反向无效的问题,因为较高级别缓存中的每个扇区都有自己的有效位。(为每个扇区提供所有一致性状态元数据而不仅仅是有效性可以避免在一个块中至少一个扇区没有脏/修改和一些一致性开销时使用过多的回写带宽[例如,如果一个扇区处于共享状态而另一个扇区处于共享状态。在独占状态下,对独占状态下的扇区的写入可能不涉及一致性流量——如果使用的是 snoopy 而不是目录一致性]。)
当标签在处理器芯片上但数据在芯片外时,扇区缓存块的面积节省尤其显着。显然,如果数据存储占用的面积与处理器芯片的大小相当(这并非不合理),那么带有 64 字节块的 32 位标签将占用大约 16(~6%)的处理器面积,而 128-字节块将需要一半。(IBM 于 2009 年推出的 POWER6+ 可能是使用处理器芯片内标签和处理器外数据的最新处理器。像 IBM 那样将数据存储在更高密度的嵌入式 DRAM 和低密度 SRAM 中的标签夸大了这一点影响。)
需要注意的是,英特尔使用“缓存行”来指代较小的单元,而“缓存扇区”则指代较大的单元。(这是我在解释中使用“高速缓存块”的原因之一。)使用英特尔的术语,高速缓存行的大小在高速缓存级别之间变化是非常不寻常的,无论级别是严格包含、严格排他还是使用其他一些包容性政策。
(严格排除通常使用更高级别的缓存作为受害者缓存,其中来自较低级别缓存的驱逐被插入到更高级别的缓存中。显然,如果块大小不同并且未使用扇区,那么驱逐将需要其余的从某处读取的较大块,如果存在于较低级别的缓存中则无效。[理论上,严格排除可以与不灵活的缓存绕过一起使用,其中 L1 驱逐将绕过 L2 并转到 L3,而 L1/L2 缓存未命中只会是分配给L1或L2,绕过 L1 进行某些访问。我所知道的最接近此实现的是 Itanium 绕过 L1 进行浮点访问。但是,如果我没记错的话,L2 包括 L1。])