操作系统导论——第19章 分页:快速地址转换(TLB)

news2025/4/18 6:08:50

        使用分页作为核心机制来实现虚拟内存,可能会带来较高的性能开销。使用分页,就要将内存地址空间切分成大量固定大小的单元(页),并且需要记录这些单元的地址映射信息。因为这些映射信息一般存储在物理内存中,所以在转换虚拟地址时,分页逻辑上需要一次额外的内存访问。每次指令获取、显式加载或保存,都要额外读一次内存以得到转换信息,这慢得无法接受。因此我们面临如下问题:

                                                关键问题:如何加速地址转换

        如何才能加速虚拟地址转换,尽量避免额外的内存访问?需要什么样的硬件支持?操作系统该如何 支持?

         硬件。增加所谓的地址转换旁路缓冲存储器(TLB 地址转换缓存),它就是频繁发生的虚拟到物理地址转换的硬件缓存。对每次内存访问,硬件先检查TLB,看看其中是否有期望的转换映射,如果有,就完成转换(很快),不用访问页表 (其中有全部的转换映射)。

一、TLB 的基本算法

        图 19.1 展示了一个大体框架,说明硬件如何处理虚拟地址转换,假定使用简单的线性页表(即页表是一个数组)和硬件管理的 TLB(硬件承担许多页表访问的责任)。

        硬件算法的大体流程如下:首先从虚拟地址提取页号(VPN)(见图19.1第1行),然后检查 TLB 是否有该 VPN 的转换映射(第2行)。如果有,我们有了 TLB 命中(TLB hit),这意味着 TLB 有该页的转换映射。成功!接下来我们就可以从相关的 TLB 项中取出页帧号(PFN),与原来虚拟地址中的偏移量组合形成期望的物理地址(PA),并访问内存(第5~7 行),假定保护检查没有失败(第4行)。

         如果 CPU 没有在 TLB 中找到转换映射(TLB未命中),我们有一些工作要做。在本例中,硬件访问页表来寻找转换映射(第11~12行),并用该转换映射更新 TLB(第 18 行),假设该虚拟地址有效,而且我们有相关的访问权限(第 13、15 行)。上述系列操作开销较大,主要是因为访问页表需要额外的内存引用(第12行)。最后,当 TLB 更新成功后,系统会重新尝试该指令,这时 TLB 中有了这个转换映射,内存引用得到很快处理。

         TLB 和其他缓存相似,前提是在一般情况下,转换映射会在缓存中(即命中)。如果是这样,只增加了很少的开销,因为 TLB 处理器核心附近,设计的访问速度很快。如果 TLB 未命中,就会带来很大的分页开销。必须访问页表来查找转换映射,导致一次额外的内存引用(或者更多,如果页表更复杂)。因此,我们希望尽可能避免 TLB 未命中

二、示例:访问数组

         弄清楚 TLB 的操作,来看一个简单虚拟地址追踪,看看TLB如何提高性能。在本例中,假设有一个由10个4字节整型数组成的数组,起始虚地址是100。 进一步假定,有一个8位的小虚地址空间页大小为16B。 我们可以把虚地址划分为 4 位的VPN(有16个虚拟内存页) 4位的偏移量(每个页中有16个字节)

        图19.2 展示了该数组的布局,在系统的 16 个 16 字节的页上。数组的第一项(a[0])开始于(VPN=06, offset=04),只有 3 个 4字节整型数存放在该页。数组在下一页(VPN=07)继续,其中有接下来4项(a[3] … a[6])。 10 个元素的数组的最后3项(a[7] … a[9])位于地址空间的下一页(VPN=08)。

考虑一个简单的循环,访问数组中的每个元素,类似下面的 C 程序:

int sum=0;
for (i=0;i<10;i++){
  sum+=a[i];
}

        当访问第一个数组元素(a[0])时,CPU 会看到载入虚存地址 100。硬件从中提取 VPN(VPN=06),然后用它来检查 TLB,寻找有效的转换映射。假设这里是程序第一次访问该数组,结果是 TLB 未命中

        接下来访问 a[1],TLB 命中!因为数组的第二个元素在第一个元素之后,它们在同一页。因为我们之前访问数组的第一个元素时,已经访问了这一页,所以TLB 中缓存了该页的转换映射。因此成功命中。访问a[2]同样成功(再次命中),因为它和a[0]、 a[1]位于同一页。 

         遗憾的是,当程序访问 a[3] 时,会导致 TLB 未命中。但同样,接下来几项(a[4] … a[6]) 都会命中TLB,因为它们位于内存中的同一页。最后,访问 a[7] 会导致最后一次TLB未命中。系统会再次查找页表,弄清楚这个虚拟页在物理内存中的位置,并相应地更新TLB。最后两次访问(a[8]、a[9])受益于这次 TLB 更新,当硬件在 TLB 中查找它们的转换映射时,两次都命中。

         我们来总结一下这 10 次数组访问操作中 TLB 的行为表现:未命中、命中、命中、未命中、命中、命中、命中、未命中、命中、命中。命中的次数除以总的访问次数,得到 TLB 命中率(hit rate)为 70%。即使这是程序首次访问该数组,但得益于空间局部性(spatial locality),TLB 还是提高了性能。数组的元素被紧密存放在几页中(即它们在空间中紧密相邻),因此只有对页中第一个元素的访问才会导致 TLB 未命中。

        时间局部性:最近访问过的指令或数据项可能很快会再次访问。想想循环中的循环变量或指令,它们被多次反复访问。

        空间局部性:当程序访问内存地址 x 时,可能很快会访问邻近 x 的内存。

三、处理 TLB 未命中

        硬件或软件(操作系统)。以前的硬件有复杂的指令集(有时称为复杂指令集计算机,Complex-Instruction Set Computer,CISC)硬件全权处理 TLB 未命中。为了做到这一点,硬件必须知道页表在内存中的确切位置(通过页表基址寄存器, page-table base register,在图 19.1 的第 11 行使用),以及页表的确切格式。发生未命中时, 硬件会“遍历”页表,找到正确的页表项,取出想要的转换映射,用它更新 TLB,并重试该指令。这种“旧”体系结构有硬件管理的TLB,一个例子是x86架构,它采用固定的多级页表(multi-level page table)

         更现代的体系结构,都是精简指令集计算机,Reduced-Instruction Set Computer,RISC,有所谓的软件管理 TLB(software- managed TLB)。发生 TLB 未命中时,硬件系统会抛出一个异常(见图19.3第11行),这会暂停当前的指令流,将特权级提升至内核模式跳转至陷阱处理程序(trap handler)。接下来你可能已经猜到了,这个陷阱处理程序是操作系统的一段代码,用于处理 TLB未命中。 这段代码在运行时,会查找页表中的转换映射,然后用特别的“特权”指令更新 TLB,并从陷阱返回。此时,硬件会重试该指令(导致TLB命中)。

         首先,这里的从陷阱返回指令稍稍不同于之前提到的服务于系统调用的从陷阱返回。在后一种情况下,从陷阱返回应该继续执行陷入操作系统之后那条指令,就像从函数调用返回后,会继续执行此次调用之后的语句。在前一种情况下, 在从 TLB 未命中的陷阱返回后硬件必须从导致陷阱的指令继续执行。这次重试因此导致该指令再次执行,但这次会命中 TLB。因此,根据陷阱或异常的原因,系统在陷入内核时必须保存不同的程序计数器,以便将来能够正确地继续执行。

          第二,在运行 TLB 未命中处理代码时,操作系统需要格外小心避免引起 TLB 未命中的无限递归。有很多解决方案,例如,可以把 TLB未命中陷阱处理程序直接放到物理内存中 [它们没有映射过(unmapped),不用经过地址转换]。或者在 TLB 中保留一些项,记录永久有效的地址转换,并将其中一些永久地址转换槽块留给处理代码本身,这些被监听的(wired) 地址转换总是会命中 TLB

         软件管理的方法,主要优势是灵活性:操作系统可以用任意数据结构来实现页表,不需要改变硬件。另一个优势是简单性。从 TLB 控制流中可以看出(见图19.3的第 11 行, 对比图19.1 的第11~19 行),硬件不需要对未命中做太多工作,它抛出异常,操作系统的未命中处理程序会负责剩下的工作

四、TLB 内容

         硬件 TLB 中的内容。典型的 TLB 有 32 项、64 项或 128 项,并且是全相联的(fully associative)。基本上,这就意味着一条地址映射可能存在TLB中的任意位置,硬件会并行地查找TLB,找到期望的转换映射。一条TLB项内容可能像下面这样:

         更有趣的是“其他位”。例如,TLB通常有一个有效(valid)位,用来标识该项是不是有效地转换映射。通常还有一些保护(protection)位,用来标识该页是否有访问权限。例如,代码页被标识为可读和可执行,而堆的页被标识为可读和可写。还有其他一些位,包括地址空间标识符(address-space identifier)、脏位(dirty bit)等。

五、上下文切换时对 TLB 的处理

         有了TLB,在进程间切换时(因此有地址空间切换),会面临一些新问题。具体来说,TLB 中包含的虚拟到物理的地址映射只对当前进程有效,对其他进程是没有意义的。所以在发生进程切换时,硬件或操作系统(或二者)必须注意确保即将运行的进程不要误读了之前进程的地址映射。

         来看一个例子,当一个进程(P1)正在运行时,假设 TLB 缓存了对它有效的地址映射,即来自 P1 的页表。对这个例子,假设 P1 的 10号虚拟页映射到了 100 号物理帧。

        在该例中,假设还有一个进程(P2),操作系统不久后决定进行一次上下文切换,运行 P2。这里假定 P2 的 10 号虚拟页映射到170号物理帧。如果这两个进程的地址映射都在TLB中,TLB的内容如表 19.1 所示。

         在上面的 TLB 中,很明显有一个问题:VPN 10 被转换成了 PFN 100(P1)和 PFN 170(P2),但硬件分不清哪个项属于哪个进程。所以还需要做一些工作,让 TLB 正确而高效地支持跨多进程的虚拟化。关键问题是:

                                        关键问题:进程切换时如何管理TLB的内容

        如果发生进程间上下文切换,上一个进程在 TLB 中的地址映射对于即将运行的进程是无意义的。 硬件或操作系统应该做些什么来解决这个问题呢?

        一种方法是在上下文切换时,简单地清空(flush)TLB, 这样在新进程运行前TLB就变成了空的。如果是软件管理 TLB 的系统,可以在发生上下文切换时,通过一条显式(特权)指令来完成。如果是硬件管理 TLB,则可以在页表基址寄存器内容发生变化时清空TLB(注意,在上下文切换时,操作系统必须改变页表基址寄存器(PTBR) 的值)。不论哪种情况,清空操作都是把全部有效位(valid)置为0,本质上清空了TLB。 

         上下文切换的时候清空 TLB,这是一个可行的解决方案,进程不会再读到错误的地址映射。但是,有一定开销:每次进程运行,当它访问数据和代码页时,都会触发TLB未命中。如果操作系统频繁地切换进程,这种开销会很高

         为了减少这种开销,一些系统增加了硬件支持,实现跨上下文切换的 TLB共享。比如有的系统在 TLB 中添加了一个地址空间标识符(Address Space Identifier,ASID)。可以把 ASID 看作是进程标识符(Process Identifier,PID),但通常比 PID 位数少(PID一般32位, ASID 一般是8位)。

         如果两个进程共享同一物理页(例如代码段的页),就可能出现这种情况。在上面的例子中,进程 P1 和进程 P2 共享101号物理页,但是 P1 将自己的10号虚拟页映射到该物理页,而P2将自己的50号虚拟页映射到该物理页。共享代码页(以二进制或共享库的方式) 是有用的,因为它减少了物理页的使用,从而减少了内存开销。

六、TLB 替换策略

         TLB 和其他缓存一样,还有一个问题要考虑,即缓存替换(cache replacement)。具体来 说,向 TLB 中插入新项时,会替换(replace)一个旧项,这样问题就来了:应该替换哪一个?

                                           关键问题:如何设计TLB替换策略

        在向TLB 添加新项时,应该替换哪个旧项?目标当然是减小TLB未命中率(或提高命中率),从而改进性能

         一种常见的策略是替换最近最少使用(least-recently-used,LRU)的项。LRU 尝试利用内存引用流中的局部性,假定最近没有用过的项,可能是好的换出候选项。另一种典型策略就是随机(random)策略,即随机选择一项换出去。这种策略很简单,并且可以避免一种极端情况。例如,一个程序循环访问 n+1 个页,但TLB大小只能存放 n个页。 这时之前看似“合理”的LRU策略就会表现得不可理喻,因为每次访问内存都会触发TLB 未命中,而随机策略在这种情况下就好很多。

七、实际系统的 TLB 表项

         真实的 TLB,来自 MIPS R4000,是一种现代的系统,采用软件管理 TLB。图 19.4 展示了稍微简化的 MIPS TLB 项。

 

         MIPS R4000 支持 32 位的地址空间,页大小为4KB。所以在典型的虚拟地址中,预期会看到20位的VPN和12位的偏移量。但是,你可以在TLB中看到,只有19位的VPN。 事实上,用户地址只占地址空间的一半(剩下的留给内核),所以只需要19位的 VPN。VPN 转换成最大24位的物理帧号(PFN),因此可以支持最多有64GB(2^38)物理内存(2^24个4KB内存页)的系统。

        MIPS TLB 还有一些有趣的标识位。比如全局位(Global,G),用来指示这个页是不是所有进程全局共享的。因此,如果全局位置为1,就会忽略ASID。我们也看到了8位的ASID,操作系统用它来区分进程空间(像上面介绍的一样)。这里有一个问题:如果正在运行的进程数超过 256(2^8)个怎么办?最后,我们看到 3 个一致性位(Coherence,C),决定硬件如何缓存该页(其中一位超出了本书的范围);脏位(dirty),表示该页是否被写入新数据(后面会介绍用法);有效位(valid),告诉硬件该项的地址映射是否有效。还有没在图 19.4 中展示的页掩码(page mask)字段,用来支持不同的页大小。后面会介绍,为什么更大的页可能有用。最后,64位中有一些未使用(图19.4中灰色部分)。

        MIPS 的 TLB 通常有32项或64项,大多数提供给用户进程使用,也有一小部分留给操作系统使用。操作系统可以设置一个被监听的寄存器,告诉硬件需要为自己预留多少 TLB 槽。这些保留的转换映射,被操作系统用于关键时候它要使用的代码和数据,在这些时候,TLB未命中可能会导致问题(例如,在TLB未命中处理程序中)。

         由于MIPS的 TLB 是软件管理的,所以系统需要提供一些更新TLB的指令。MIPS提供了4个这样的指令:TLBP,用来查找指定的转换映射是否在TLB中TLBR,用来将 TLB 中的内容读取到指定寄存器中TLBWI,用来替换指定的 TLB 项TLBWR,用来随机替换一个TLB项。操作系统可以用这些指令管理 TLB 的内容。当然这些指令是特权指令。

八、小结

         通过增加一个小的、芯片内的TLB作为地址转换的缓存,大多数内存引用就不用访问内存中的页表了。

        但是,TLB 也不能满足所有的程序需求。具体来说,如果一个程序短时间内访问的页数超过了 TLB 中的页数,就会产生大量的 TLB 未命中,运行速度就会变慢。这种现象被称为超出 TLB 覆盖范围(TLB coverage),这对某些程序可能是相当严重的问题。解决这个问题的一种方案是支持更大的页,把关键数据结构放在程序地址空间的某些区域,这些区域被映射到更大的页,使 TLB 的有效覆盖率增加。对更大页的支持通常被数据库管理系统 (Database Management System,DBMS)这样的程序利用,它们的数据结构比较大,而且是随机访问

         另一个TLB问题值得一提:访问TLB很容易成为CPU流水线的瓶颈,尤其是有所谓的物理地址索引缓存(physically-indexed cache)。有了这种缓存,地址转换必须发生在访问该缓存之前,这会让操作变慢。为了解决这个潜在的问题,人们研究了各种巧妙的方法, 用虚拟地址直接访问缓存,从而在缓存命中时避免昂贵的地址转换步骤

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2335294.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机网络:流量控制与可靠传输机制

目录 基本概念 流量控制&#xff1a;别噎着啦&#xff01; 可靠传输&#xff1a;快递必达服务 传输差错&#xff1a;现实中的意外 滑动窗口 基本概念 换句话说&#xff1a;批量发货排队验收 停止-等待协议 SW&#xff08;发1份等1份&#xff09; 超时重传&#xff1a;…

架构生命周期(高软57)

系列文章目录 架构生命周期 文章目录 系列文章目录前言一、软件架构是什么&#xff1f;二、软件架构的内容三、软件设计阶段四、构件总结 前言 本节讲明架构设计的架构生命周期概念。 一、软件架构是什么&#xff1f; 二、软件架构的内容 三、软件设计阶段 四、构件 总结 就…

JMeter使用

1.简介 1.1 打开方式 ①点击bat,打开 ②添加JMeter系统环境变量,输⼊命令jmeter即可启动JMeter⼯具 1.2 配置 简体中文 放大字体 1.3 使用 ①添加线程组 ②创建http请求 2. 组件 2.1 线程组 控制JMeter将⽤于执⾏测试的线程数&#xff0c;也可以把⼀个线程理解为⼀个测…

Ant Design Vue 表格复杂数据合并单元格

Ant Design Vue 表格复杂数据合并单元格 官方合并效果 官方示例 表头只支持列合并&#xff0c;使用 column 里的 colSpan 进行设置。 表格支持行/列合并&#xff0c;使用 render 里的单元格属性 colSpan 或者 rowSpan 设值为 0 时&#xff0c;设置的表格不会渲染。 <temp…

ECharts 如何实现柱状图悬停时,整个背景区域均可触发点击事件

1. 前言 ECharts 柱状图的点击事件默认仅响应柱子本身的点击&#xff0c;本文旨在实现整个背景区域均可触发点击事件 2. 实现思路 核心&#xff1a;全局监听 坐标判断 数据转换 通过 getZr() 监听整个画布点击&#xff0c;结合像素坐标判断是否在图表区域内‌通过 containPi…

金融简单介绍及金融诈骗防范

在当今社会&#xff0c;金融学如同一股无形却强大的力量&#xff0c;深刻影响着我们生活的方方面面。无论是个人的日常收支、投资理财&#xff0c;还是国家的宏观经济调控&#xff0c;都与金融学紧密相连。​ 一、金融学的概念​ 金融学&#xff0c;简单来说&#xff0c;是研…

cursor+高德MCP:制作一份旅游攻略

高德开放平台 | 高德地图API (amap.com) 1.注册成为开发者 2.进入控制台选择应用管理----->我的应用 3.新建应用 4.点击添加Key 5.在高德开发平台找到MCP的文档 6.按照快速接入的步骤&#xff0c;进行操作 一定要按照最新版的cursor, 如果之前已经安装旧的版本卸载掉重新安…

Kubernetes控制平面组件:API Server Webhook 授权机制 详解

云原生学习路线导航页&#xff08;持续更新中&#xff09; kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计&#xff08;一&#xff09;Kubernetes架构原则和对象设计&#xff08;二&#xff09;Kubernetes架构原则和对象设计&#xff08;三&#xff09;Kubernetes控…

【Python爬虫】简单案例介绍2

本文继续接着我的上一篇博客【Python爬虫】简单案例介绍1-CSDN博客 目录 跨页 3.2 环境准备 跨页 当对单个页面的结构有了清晰的认识并成功提取数据后&#xff0c;接下来就需要考虑页面之间的跨页问题。此时我们便迎来了下一个关键任务&#xff1a;如何实现跨页爬取&#xf…

【神经网络】python实现神经网络(四)——误差反向传播的基础理论

一.反向传播 本章将介绍能够高效计算权重参数的梯度的方法——误差反向传播法,这里简单介绍一下什么是反向传播,加入有个函数y = f(x),那么它的反向传播为图下这个样子: 反向传播的计算顺序是,将输入信号E乘以节点的局部导数,然后将结果传递给下一个节点。这里所…

I/O进程(全)

I/O 一、标准IO 1.概念 在C库中定义的一组用于输入输出的函数 2.特点 (1).通过缓冲机制减少系统调用&#xff0c;提高效率 (2.)围绕流进行操作&#xff0c;流用FILE *来描述(3).标准IO默认打开了三个流&#xff0c;stdin&#xff08;标准输入&#xff09;、stdout&#xff08;标…

vue2使用ezuikit-js播放萤石视频

需求&#xff1a;需要在大屏上播放萤石视频&#xff0c;用到官方的ezuikit-js插件实现&#xff0c;并实现视频播放切换功能。有个问题至今没有解决&#xff0c;就是萤石视频的宽高是固定的&#xff0c;不会根据大屏缩放进行自适应。我这边做了简单的刷新自适应。 1.下载ezuikit…

【笔试强训day19】

目录 第一题&#xff1a;小易的升级之路 描述 输入描述&#xff1a; 输出描述&#xff1a; 输入&#xff1a; 输出&#xff1a; 第二题&#xff1a;礼物的最大价值 描述 输入&#xff1a; 返回值&#xff1a; 备注&#xff1a; 第三题&#xff1a;对称之美 题目描述…

STM32电机库 电机控制特性

ST MC FW库提供FOC和六步法两种电机控制方式。这使得它能够驱动永磁同步电机 (PMSM) 和无刷直流电机 (BLDC)。FOC 更适合 PMSM,而六步法更适合 BLDC 电机。该固件可以驱动内嵌式PMSM 和标贴式PMSM。 ST Motor Control 固件库提供以下功能: FOC SVPWM 生成: 可配置的 PW…

【Linux】42.网络基础(2.4)

文章目录 2.3 TCP协议2.3.10 拥塞控制2.3.11 延迟应答2.3.12 捎带应答2.3.13 面向字节流2.3.14 粘包问题2.3.15 TCP异常情况2.3.16 TCP小结2.3.17 基于TCP应用层协议 2.3 TCP协议 2.3.10 拥塞控制 虽然TCP有了滑动窗口这个大杀器, 能够高效可靠的发送大量的数据. 但是如果在刚…

SPI接口DAC设备驱动与应用程序开发

本文章相关专栏往期内容&#xff0c;SPI子系统专栏&#xff1a; SPI通信协议与Linux设备驱动框架解析SPI传输与驱动框架的实现spidev.c&#xff1a;SPI设备驱动的核心实现逻辑 PCI/PCIe子系统专栏&#xff1a; 专栏地址&#xff1a;PCI/PCIe子系统PCIe设备MSI/MSI-X中断源码分析…

第十六届蓝桥杯大赛软件赛省赛 Python 大学 B 组 满分题解

题面链接Htlang/2025lqb_python_b 个人觉得今年这套题整体比往年要简单许多&#xff0c;但是G题想简单了出大问题&#xff0c;预估50101015120860&#xff0c;道阻且长&#xff0c;再接再厉 代码仅供学习参考&#xff0c;满分为赛后洛谷中的测评&#xff0c;蓝桥杯官方测评待…

旧版 VMware 虚拟机迁移至 KVM 平台-案例2

项目背景 需将一台旧版 VMware 虚拟机&#xff08;VMDK 格式&#xff09;迁移至 KVM 虚拟化平台&#xff0c;具体要求如下&#xff1a; 格式转换&#xff1a;将 VMDK 转换为 QCOW2 格式。磁盘扩容&#xff1a;将原 40GB 磁盘扩展至 60GB。密码重置&#xff1a;修改 aiden 用户…

若依代码生成器原理velocity模板引擎(自用)

1.源码分析 代码生成器:导入表结构(预览、编辑、删除、同步)、生成前后端代码 代码生成器表结构说明&#xff1a; 若依提供了两张核心表来存储导入的业务表信息&#xff1a; gen_table&#xff1a;存储业务表的基本信息 &#xff0c;它对应于配置代码基本信息和生成信息的页…

OpenCV直方图均衡化全面解析:从灰度到彩色图像的增强技术

目录 一、直方图均衡化基础&#xff1a;原理与核心思想 二、彩色图像的直方图均衡化&#xff1a;挑战与解决方案 三、进阶技巧与注意事项 四、应用场景与典型案 一、直方图均衡化基础&#xff1a;原理与核心思想 1. 直方图的本质与作用 直方图是图像像素强度分布的统计图表…