VIPT缓存:TLB和缓存之间的连接?

VIPT Cache: Connection between TLB & Cache?

我只是想澄清一下这个概念,并且可以找到足够详细的答案,这些答案可以阐明硬件中的一切实际工作原理。请提供任何相关详细信息。

对于 VIPT 缓存,内存请求会并行发送到 TLB 和缓存。

我们从 TLB 中得到转换后的物理地址。 从缓存索引我们得到一个标签列表(例如,从属于一个集合的所有缓存行)。

然后将翻译后的TLB地址与标签列表进行匹配,寻找候选者。

有人可以解释一下 "actually" 这通常是如何实现的,以及缓存模块和 TLB(MMU) 模块之间的连接吗?

我知道这取决于具体的架构和实现。 但是,当有 VIPT 缓存时,你知道的实现是什么?

谢谢。

在这个细节级别,您必须将“缓存”和“TLB”分解为它们的组成部分。它们在使用 VIPT 速度黑客的设计中非常紧密地互连,该设计使用与标签获取并行翻译的 VIPT 速度黑客(即利用索引位全部低于页面偏移量,因此被“免费”翻译。相关:Why is the size of L1 cache smaller than that of the L2 cache in most of the processors?)

L1dTLB 本身就是一个 small/fast Content addressable memory with (for example) 64 entries and 4-way set associative (Intel Skylake)。大页面通常使用并行检查的第二个(和第三个)数组来处理,例如32-entry 4-way for 2M pages, and for 1G pages: 4-entry fully (4-way) associative.

但是现在,请简化您的心智模型并忘掉大页面。 L1dTLB是一个单独的CAM,检查它是一个单独的查找操作。

“缓存”至少包括以下部分:

  • 存储标签+数据的SRAM数组
  • 根据索引位获取一组数据+标签的控制逻辑。 (高性能 L1d 缓存通常与标签并行地获取集合的所有方式的数据,以减少命中延迟,而不是像使用更大、关联性更高的缓存那样等到正确的标签 selected。)
  • 比较器根据翻译后的地址检查标签,select 如果其中一个匹配则检查正确的数据,否则会触发错误处理。 (一旦命中,更新 LRU 位以将此方式标记为最近使用过)。有关不带 TLB 的 2 路关联高速缓存的基础知识图,请参阅 https://courses.cs.washington.edu/courses/cse378/09wi/lectures/lec16.pdf#page=17。圆圈内的 = 是比较器:如果标签宽度输入相等,则生成布尔真输出。

L1dTLB 与 L1D 缓存并没有真正分开。我实际上并不设计硬件,但我认为 现代高性能设计中的加载执行单元是这样工作的 :

  • AGU 从寄存器 + 偏移量生成地址。

    (有趣的事实:Sandybridge 系列为简单寻址模式乐观地简化了此过程:[reg + 0-2047] 的加载使用延迟比其他寻址模式低 1c,如果 reg 值与 reg+disp.)

  • 索引位来自地址的页内偏移部分,因此不需要从虚拟地址转换为物理地址。或者翻译是空操作。只要 L1_size / associativity <= page_size,这种具有 PIPT 缓存非混叠的 VIPT 速度就可以工作。例如32kiB / 8 路 = 4k 页。

    索引位select一组。为该组的所有方式并行获取标签+数据。 (这会消耗能量来节省延迟,并且可能只对 L1 值得。更高的关联性(每组更多方式)L3 缓存绝对不是)

  • 在L1dTLB CAM数组中查找地址的高位。

  • 标签比较器接收转换后的物理地址标签和从该集合中提取的标签。

  • 如果有标签匹配,缓存从数据中提取正确的字节用于匹配的方式(使用地址的偏移行内低位和操作数大小) .

或者不是获取完整的 64 字节行,它可以更早地使用偏移位从每个方向获取一个(对齐的)字。 CPU没有高效未对齐负载的肯定是这样设计的。我不知道这样做是否值得为 CPU 上支持未对齐负载的简单对齐负载节省电力。

但现代英特尔 CPUs(P6 及更高版本)对未对齐的加载微指令没有惩罚,即使是 32 字节向量,只要它们不跨越高速缓存行边界。基于行内偏移量、操作数大小和特殊属性,如零或符号扩展,或广播负载。因此,一旦完成标记比较,来自 selected 方式的 64 字节数据可能会进入一个已配置的多路复用器网络,该网络会获取正确的字节并进行广播或符号扩展。

AVX512 CPUs 甚至可以进行 64 字节的整行加载。


如果在 L1dTLB CAM 中没有匹配项,整个缓存提取操作将无法继续。我不确定 CPUs 是否/如何管理它,以便在解决 TLB 未命中时其他负载可以继续执行。该过程涉及检查 L2TLB(Skylake:统一的 1536 条目 12 路用于 4k 和 2M,16 条目用于 1G),如果失败则使用页面遍历。

我假设 TLB 未命中会导致标签+数据提取被丢弃。一旦找到所需的翻译,它们将被重新获取。当其他负载正在 运行ning 时,没有地方可以存放它们。

在最简单的情况下,它可以在翻译准备就绪时重新运行整个操作(包括从 L1dTLB 获取翻译),但它可以通过快捷方式降低 L2TLB 命中的延迟处理并直接使用翻译,而不是将其放入 L1dTLB 并再次取出。

显然,这需要 dTLB 和 L1D 真正设计在一起并紧密集成。因为他们只需要互相交谈,所以这是有道理的。硬件页面遍历通过 L1D 缓存获取数据。 (页表总是有已知的物理地址,以避免 catch 22 / 先有鸡还是先有蛋的问题)。

is there a side-band connection from TLB to the Cache?

我不会称之为边带连接。 L1D 缓存是 only 使用 L1dTLB 的东西。同样,L1iTLB 仅由 L1I 缓存使用。

如果有2级TLB,一般是统一的,所以L1iTLB和L1dTLB如果漏了都会检查。就像拆分L1I和L1D缓存,如果不命中,通常会检查一个统一的L2缓存。

外部缓存(L2、L3)非常普遍 PIPT。转换发生在 L1 检查期间,因此物理地址可以发送到其他缓存。