如果它们都需要两次内存访问,什么使 TLB 比页表更快?

m0m*_*eni 4 memory paging operating-system cpu-architecture tlb

刚刚离开维基百科

页表通常存储在主内存中,跟踪虚拟页面在物理内存中的存储位置。该方法使用两次内存访问(一次用于页表条目,一次用于字节)来访问一个字节。首先,在页表中查找帧号。其次,带有页偏移量的帧号给出了实际地址。因此,任何简单的虚拟内存方案都会使内存访问时间加倍。因此,TLB 用于减少在页表方法中访问内存位置所花费的时间。

因此,我很好奇为什么 TLB 实际上更快,因为据我所知,它只是页表的一个更小、更精确的副本。

您仍然需要访问TLB以找到物理地址,然后一旦获得了物理地址,您仍然需要实际访问物理地址处的数据,这与页表一样是两次查找。

我只能想到TLB更快的两个原因:

  • 在 TLB 或页表中查找地址不是 O(n)(我假设它像哈希表一样是 O(1))。因此,由于 TLB 小得多,因此查找速度更快。同样在这种情况下,为什么不使用哈希表而不是 TLB?

  • 我错误地解释了 TLB 的工作原理,它实际上并没有进行两次访问。

iho*_*nen 8

我意识到这个问题已经三年了,但由于它仍然具有相关性,并且仍然出现在搜索引擎中,我会尽力提供完整的答案。

通过 TLB 而不是页表访问主内存更快,主要有两个原因:

1. TLB 比主存(页表所在的位置)快。

TLB 的典型访问时间为 <1 ns,主存储器为 100 ns
TLB 访问是 L1 缓存命中的一部分,如果现代 CPU都命中 L1d 缓存,则每个时钟可以执行 2 次加载

造成这种情况的原因有两个:

  1. TLB 位于 CPU 内,而主存——因此页表——不在。
  2. TLB 与其他缓存一样,由快速且昂贵的 SRAM 组成,而主存储器通常由速度慢且价格低廉的 DRAM 组成(在此处阅读更多内容)。

因此,如果 TLB 和页表都只需要一次内存访问的假设是正确的,那么粗略地说,TLB 命中仍会将内存访问时间减半。然而,正如我们接下来将看到的,这个假设是正确的,拥有 TLB 的好处更大。

2. 访问页表通常需要多次内存访问。

这确实是问题的关键。

现代 CPU 倾向于使用多级页表以节省内存。最值得注意的是,x86-64 页表目前最多由四层组成(第五层可能即将到来)。这意味着通过页表访问内存中的单个字节需要最多五次内存访问:四次用于页表,一次用于数据。显然,如果没有 TLB,成本将高得难以承受;很容易理解为什么 CPU 和操作系统工程师付出了很多努力来最小化 TLB 未命中的频率。

最后,请注意,即使这种解释也有些简化,因为它忽略了数据缓存等。现代台式机 CPU 的详细机制很复杂,并且在某种程度上尚未公开。例如,有关该主题的更详细讨论,请参阅此线程

页表访问可以并且由现代 CPU 上的数据缓存进行缓存,但是页遍历中的下一次访问取决于第一次访问的结果(指向页表下一级的指针),因此 4 级即使所有访问都命中 L1d 缓存,页面遍历也会有大约 4x 4 个周期 = 16 个周期的延迟。对于管道来说,隐藏的时间比大约 3 到 4 个周期的 TLB 延迟要多得多,后者是现代英特尔 CPU(当然使用 TLB 进行数据和指令访问)中 L1d 缓存命中负载的一部分。