快表 (Translation Lookaside Buffer, TLB)。这是对基本地址变换机构的一次"涡轮增压"升级。
我们继续使用那个**智能秘书(地址变换机构)**的比喻。
- 你(CPU):需要频繁查阅论文。
- 活页本(内存):存放着论文内容和完整的目录(慢表/页表)。
- 智能秘书(硬件MMU):负责地址转换。
1. 问题的根源:秘书的"记忆力"太差了
在基本地址变换机构中,我们的秘书虽然工作流程标准,但有个致命缺点:他是个"金鱼记忆"。
每次你问他:"论文第5页在哪?",他都会老老实实地跑去活页本里翻找完整的目录,找到后告诉你,然后立刻就把这个信息忘了。下一秒你再问他"论文第5页在哪?",他又会重复一遍完整的查找流程。
这个"跑去翻目录"的动作(访问内存中的页表),是非常耗时的。而我们知道,程序运行时具有局部性原理 :在某段时间内,你很可能会反复查阅同一页或相邻几页的内容。让秘书每次都去翻一遍大部头的完整目录,实在是太低效了!
2. 解决方案:给秘书配一个"便签本"------快表(TLB)
为了提升效率,我们给这位秘书配了一个高速的、小巧的"便签本"(快表/TLB)。
- 快表的定义 :
- 它是一个联想寄存器 (Associative Memory) ,你可以把它想象成一种"超级便签本"。它的特点是可以按内容快速查找。你只要喊出"第5页!",它就能瞬间告诉你第5页对应的物理纸张号,而不需要像普通内存那样按地址一个一个找。
- 它的访问速度极快,几乎和CPU寄存器一样快,远胜于访问内存。
- 快表里存什么 :
- 它存放的是最近刚刚被使用过的"目录项"的副本 。比如,秘书刚查完"第5页 -> 在第_8_张物理纸上",他就会顺手把这个
(5, 8)
的映射关系记在他的便签本上。
- 它存放的是最近刚刚被使用过的"目录项"的副本 。比如,秘书刚查完"第5页 -> 在第_8_张物理纸上",他就会顺手把这个
- 为什么不能存整个目录 :
- 这种"超级便签本"的造价极其昂贵。用同等成本,能买一个巨大仓库的普通活页纸(内存),却只能买到一小本便签本(快表)。所以,快表的容量非常有限,只能存放一小部分最常用的目录项。
3. 带有快表的"升级版"地址变换流程
现在,秘书的工作流程变得更加智能和高效了:
你(CPU)发出指令:"我要找逻辑地址 A
处的内容!"
-
第一步:拆分指令 (同前)
- 秘书拿到逻辑地址
A
,瞬间拆分成页号P
和 页内偏移量W
。
- 秘书拿到逻辑地址
-
第二步:先查"便签本" (查询快表)
-
秘书首先 会以极快的速度扫描他的便签本(快表),看看上面有没有记录页号
P
的条目。 -
快表命中 (TLB Hit)!
- 情况 :太棒了!便签本上正好有
(P, P')
这条记录。 - 流程 :秘书直接从便签本上读出物理块号
P'
,然后用它和偏移量W
拼接成最终物理地址。 - 时间成本 :查询快表(极快,可忽略) + 一次内存访问(访问目标数据)。效率极高!
- 情况 :太棒了!便签本上正好有
-
快表未命中 (TLB Miss)!
- 情况 :便签本上没有记录页号
P
的信息。 - 流程 :秘书只好启动他的"老办法": a. 安全检查 :检查页号
P
是否越界(对比PTLR)。 b. 查询"大目录" (访问内存中的页表) :根据PTBR和P
,计算出页表项的内存地址,第一次访问内存 ,取出物理块号P'
。 c. 更新"便签本" :在把P'
交给CPU之前,秘书会做一件重要的事------把刚刚查到的这个(P, P')
的映射关系,写到他的便签本(快表)上 。如果便签本满了,就按某种算法(如LRU - 最近最少使用)擦掉一条最旧的记录,再写入新的。 d. 形成物理地址并访问 :用P'
和W
形成物理地址,然后第二次访问内存,去取真正的数据。 - 时间成本 :查询快表(极快) + 两次内存访问。效率和没有快表时一样。
- 情况 :便签本上没有记录页号
-
4. 为什么快表能大幅提升性能?
快表的威力来源于局部性原理 (Principle of Locality)。
- 时间局部性:如果一个数据被访问了,那么它在不久的将来很可能被再次访问。
- 空间局部性:如果一个数据被访问了,那么它附近的数据很可能即将被访问。
这意味着,一旦一个页面的页表项因为"快表未命中"而被加载到快表中,接下来的一连串 对该页面的访问,都会大概率地在快表中命中。
举例:一个循环执行100次,循环体内的代码和数据都在同一个页面上。
- 第一次访问:快表未命中,耗时=2次访存时间。页表项被加载到快表。
- 后99次访问:全部快表命中,每次耗时=1次访存时间。
- 总耗时 ≈
1 * (2*T) + 99 * (1*T)
,平均每次访问耗时略高于1*T
。 - 对比无快表 :
100 * (2*T)
,平均每次耗时2*T
。
性能提升接近一倍!
必会题与详解
题目一:请详细描述带有快表(TLB)的地址变换全过程,并说明"快表命中"和"快表未命中"两种情况下的主要区别。
答案详解:
全过程:
- CPU产生一个逻辑地址,将其发送给MMU(地址变换机构)。
- MMU将逻辑地址拆分为页号P 和页内偏移量W。
- MMU首先使用页号P在快表(TLB)中进行快速的并行查找。
- 情况一:快表命中 (TLB Hit)
- 在快表中找到了与P匹配的页表项,直接从中取出物理块号P'。
- 将物理块号P'与页内偏移量W拼接,形成最终的物理地址。
- 使用该物理地址访问内存。
- 整个过程只需要一次内存访问(访问目标数据)。
- 情况二:快表未命中 (TLB Miss)
- MMU需要继续访问内存中的慢表(页表)。
- 首先,检查页号P是否小于页表长度寄存器PTLR的值,进行越界判断。
- 然后,根据页表起始地址寄存器PTBR和页号P,计算出页表项在内存中的地址,第一次访问内存,读取该页表项,得到物理块号P'。
- 将这个刚从内存中读出的页表项(包含P和P')写入快表。如果快表已满,则根据替换算法(如LRU)替换掉一个旧的条目。
- 将物理块号P'与页内偏移量W拼接,形成最终的物理地址。
- 使用该物理地址第二次访问内存,访问目标数据。
- 整个过程需要两次内存访问。
主要区别:
- 访存次数 :快表命中时,总共只需一次 内存访问;快表未命中时,需要两次内存访问。
- 时间开销:由于访存是主要耗时操作,快表命中的时间开销大约是快表未命中时的一半。
- 快表操作 :快表命中时,只对快表进行读 操作;快表未命中时,还需要对快表进行写操作(更新快表)。
题目二:快表(TLB)和高速缓存(Cache)都是为了提升系统性能而设计的高速存储部件,请问它们在功能上有什么本质区别?
答案详解:
尽管TLB和Cache都是高速缓存,但它们缓存的内容和目的完全不同。
- 快表 (TLB) :
- 功能 :专门用于加速地址转换的过程。
- 缓存内容 :它缓存的是页表项 (Page Table Entries),即"逻辑页号"到"物理块号"的映射关系。
- 工作阶段 :它工作在CPU发出逻辑地址,到最终形成物理地址的中间阶段。
- 高速缓存 (Cache) :
- 功能 :专门用于加速数据获取的过程。
- 缓存内容 :它缓存的是内存中数据或指令的副本。
- 工作阶段 :它工作在CPU已经得到物理地址之后。CPU会先用物理地址去Cache中查找,如果命中,就直接从Cache取数据,无需访问内存;如果未命中,才去访问内存,并将取回的数据放入Cache。
简单来说:TLB是用来找"地址"的缓存,Cache是用来找"数据"的缓存。一个完整的CPU访存过程可能是:先查TLB得到物理地址,再用物理地址查Cache获取数据。
题目三:在一个分页系统中,快表的命中率为90%,访问一次快表需要1ns,访问一次内存需要100ns。请计算该系统访问一次内存的平均有效访问时间(EAT)。
答案详解:
有效访问时间 (Effective Access Time, EAT) 是综合考虑了命中和未命中两种情况的加权平均时间。
-
快表命中时的时间:
- 访问快表(1ns)+ 访问内存取数据(100ns)= 101ns
-
快表未命中时的时间:
- 访问快表(1ns)+ 访问内存查页表(100ns)+ 访问内存取数据(100ns)= 201ns
-
计算加权平均时间:
- EAT = 命中率 * 命中时的时间 + (1 - 命中率) * 未命中时的时间
- EAT =
0.90 * 101ns + (1 - 0.90) * 201ns
- EAT =
0.90 * 101ns + 0.10 * 201ns
- EAT =
90.9ns + 20.1ns
- EAT = 111ns
结论:引入快表后,尽管未命中的代价很高,但由于高达90%的命中率,系统的平均访存时间从原来的200ns(无快表时)显著降低到了111ns,性能提升巨大。