如果TLB和页表都需要两次内存访问,那么是什么让TLB更快呢?

5

wikipedia得知:

页面表通常存储在主内存中,用于记录虚拟页面在物理内存中的位置。使用该方法需要两次内存访问(一次是页面表项,一次是字节),才能访问一个字节。首先查找页面表以获取帧编号,其次通过帧编号和页面偏移量确定实际地址。因此,任何简单的虚拟内存方案都会导致内存访问时间加倍。因此,使用TLB可以减少访问页面表方法所需的时间。

鉴于此,我想知道为什么TLB实际上更快,因为据我所知,它只是页面表的一个更小、精确的副本。

你仍然需要访问TLB以查找物理地址,然后一旦你获得了物理地址,你仍然需要访问物理地址处的数据,这与页面表一样需要二次查找。

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

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

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


如有任何疑问,请随时提出。 - Sumeet
由于现代CPU中的多级分页(请参见我的答案),假设读取页面表需要一个内存访问是不正确的。 - 0x4d45
4个回答

9

我知道这个问题已经存在三年了,但是因为它仍然很相关,并且仍然出现在搜索引擎中,所以我会尽力提供一个完整的答案。

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

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

典型的访问时间为小于1纳秒的TLB和100纳秒的主内存
TLB访问是L1缓存命中的一部分,如果它们都在L1d高速缓存中命中,现代CPU可以每个时钟周期执行2次读取

其原因有两点:

  1. TLB位于CPU内部,而主内存(即页表)则不是。
  2. TLB - 像其他缓存一样 - 由快速且昂贵的SRAM制成,而主内存通常由缓慢且廉价的DRAM组成(可在此处阅读更多信息)。

因此,如果假设TLB和页表都只需要一次内存访问是正确的,则TLB命中仍将使内存访问时间减半。然而,接下来我们将看到,这个假设是不正确的,并且拥有TLB的好处甚至更大。

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

这真的是问题的关键。

现代CPU倾向于使用多级页表以节省内存。最值得注意的是,x86-64页表当前由多达四个级别组成(第五个可能即将到来)。这意味着通过页表访问内存中的单个字节需要高达五次内存访问:四次用于访问页表,一次用于数据。显然,如果没有TLB,成本将无法承受。很容易看出为什么CPU和操作系统工程师会花费很多精力来尽量减少TLB未命中的频率。

最后,请注意,即使这个解释在某种程度上是简化了,因为它忽略了数据缓存等其他因素。现代桌面CPU的详细机制是复杂和不透明的。有关该主题的更详细讨论,请参见此线程

在现代CPU上,页面表访问可以并且通常被数据缓存缓存,但是在页面遍历中下一个访问依赖于第一个访问的结果(指向页面表下一级的指针),因此即使所有访问都命中L1d缓存,一个4级页面遍历也会产生大约4x4个周期 = 16个周期的延迟。这对于流水线来说要比现代英特尔CPU中L1d缓存命中负载的~3到4个周期TLB延迟更难隐藏(当然,这种情况下数据和指令访问都使用TLB)。


1
事实上,TLB是一种快速的CAM,通常与L1缓存并行访问(在从集合中获取标签/数据时)。VIPT Cache:TLB和Cache之间的连接?。这就是现代微架构在命中dTLB和L1d缓存时每个时钟周期可以运行2个负载的原因。 - Peter Cordes

4
你的假设是正确的,使用TLB的方法仍然需要2次访问。但是使用TLB的方法更快,因为:

TLB由称为关联存储器的更快速的存储器制成。

通常我们对物理内存进行两次访问,但是使用TLB只需一次访问TLB,另一次访问物理内存。

关联存储器更快,因为它是内容可寻址存储器,但也更昂贵,因为需要额外的逻辑电路。

您可以在此处阅读有关内容可寻址存储器的信息here

这个答案不仅误导,而且部分不正确,它回答了一个完全不同的问题(“为什么TLB访问时间恒定?”)。使得TLB比主存储器更快的不是内容可寻址性 - 这只意味着访问时间是恒定的,这对于主存储器也是正确的。另外,由于多级分页的存在,两种情况下都需要两次内存访问的假设是不正确的(请查看我的答案)。 - 0x4d45
我不会说“通常”。是否有任何真实的CPU设计采用分页虚拟内存,没有至少一个小的TLB,例如至少1个条目?我认为这不是你的意思,但更好的措辞可能是“如果没有TLB,我们将不得不遍历页面表(通过L1d高速缓存访问)进行每次加载、存储和代码获取,每个体系结构内存访问需要额外2到4次访问”。 - Peter Cordes

3
具体实现情况而定。一般来说,TLB是存在于CPU内部的缓存。
你仍然需要访问TLB以查找物理地址,然后获取该地址处的数据,这就像使用页表进行两次查找一样。
相比通过内存总线访问数据,CPU可以更快地访问缓存。因为它需要对两个不同位置进行访问(一个较快,一个较慢)。此外,内存位置也可能被缓存在CPU中,这种情况下,不需要通过内存总线进行访问。

1
除此以外,这个答案不完整,也遗漏了现代 CPU 使用多级分页(请参见我的回答),这意味着读取页面表需要多次内存访问,而不仅仅是一次。另外,在这个问题中提到缓存会更好。 - 0x4d45

0

我认为@ihohen已经说得很清楚了,但是作为一个学生,为了未来的学生们,简单地解释一下:
"在单级分页中,如果没有TLB,你需要访问主存储器两次:
第一次是为了在页表中查找逻辑地址的翻译(页表位于主存储器中),第二次是为了实际访问内存块"。
现在有了TLB,你只需要进行一次访问(第二次),因为找到翻译的步骤(希望如此)将在不需要访问主存储器的情况下完成,因为你会在CPU中找到放置TLB的翻译"。

所以当我们说TLB将访问时间缩短了2倍时,我们指的是大约,如果我们忽略TLB未命中的情况,并考虑最简单的分页模型(单级分页),那么可以说TLB将加速进程2倍。

会有很多变化,因为首先今天的计算机将使用先进的分页技术(多级、需求分页等),但这句话是一个直观的解释,说明为什么TLB的想法比简单的页表更有帮助。

Silberschatz的《操作系统》一书提出了另一种(稍微详细一些)用于测量TLB访问时间的数学类型:
考虑:
h:TLB命中率
τ:访问主存储器的时间
e:查找TLB注册表所花费的时间
t = h * (e + τ) + (1-h)*(e + 2τ)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接