从 01 开始 从 01 开始
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档

晓林

程序猿,自由职业者,博主,英语爱好者,健身达人
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档
  • 计算机简史

  • 数字电路

  • 计算机组成原理

  • 操作系统

    • 我的操作系统学习笔记

    • 我的操作系统实验笔记

    • 操作系统网课-王道考研

      • 0_课程白嫖指南
      • 1_1_操作系统的概念(定义)、功能和目标
      • 1_2_操作系统的特征
      • 1_3_操作系统的发展与分类
      • 1_4_操作系统的运行机制与体系结构
      • 1_5_中断和异常
      • 2_1_6_系统调用
      • 2_1_1_进程的定义、组成、组织方式、特征
      • 2_1_2_进程的状态与转换
      • 2_1_3_进程控制
      • 2_1_4_进程通信
      • 2_1_5_线程概念和多线程模型
      • 2_2_1_处理机调度的概念、层次
      • 2_2_2_进程调度的时机、切换与过程、方式
      • 2_2_3_调度算法的评价指标
      • 2_2_4_FCFS、SJF、HRRN调度算法
      • 2_2_5_调度算法:时间片轮转、优先级、多级反馈队列
      • 2_3_1_进程同步、进程互斥
      • 2_3_2_进程互斥的软件实现方法
      • 2_3_3_进程互斥的硬件实现方法
      • 2_3_4_信号量机制
      • 2_3_5_用信号量实现进程互斥、同步、前驱关系
      • 2_3_6_生产者-消费者问题
      • 2_3_7_多生产者-多消费者问题
      • 2_3_8_吸烟者问题
      • 2_3_9_读者-写者问题
      • 2_3_10_哲学家进餐问题
      • 2_3_11_管程
      • 2_4_1_死锁的概念
      • 2_4_2_死锁的处理策略—预防死锁
      • 2_4_3_死锁的处理策略—避免死锁
      • 2_4_4_死锁的处理策略—检测和解除
      • 3_1_1_内存的基础知识
      • 3_1_2_内存管理的概念
      • 3_1_3_覆盖与交换
      • 3_1_4_连续分配管理方式
      • 3_1_5_动态分区分配算法
      • 3_1_6_基本分页存储管理的基本概念
      • 3_1_7_基本地址变换机构
      • 3_1_8_具有快表的地址变换机构
        • 局部性原理
        • 快表机制
        • 引入块表后,地址的变换过程
        • 小结
      • 3_1_9_两级页表
      • 43_3_1_10_基本分段存储管理方式
      • 3_1_11_段页式管理方式
      • 3_2_1_虚拟内存的基本概念
      • 3_2_2_请求分页管理方式
      • 3_2_3_页面置换算法
      • 3_2_4_页面分配策略
      • 4_1_1_初识文件管理
      • 4_1_2_文件的逻辑结构
      • 4_1_3_文件目录
      • 4_1_4_文件的物理结构(上)
      • 4_1_4_文件的物理结构(下)
      • 54_4_1_5_文件存储空间管理
      • 4_1_6_文件的基本操作
      • 4_1_7_文件共享
      • 4_1_8_文件保护
      • 4_1_9_文件系统的层次结构
      • 4_2_1_磁盘的结构
      • 4_2_2_磁盘调度算法
      • 4_2_3_减少磁盘延迟时间的方法
      • 4_2_4_磁盘的管理
      • 5_1.2_I-O 控制器
      • 5_1.3_I-O 控制方式
      • 65_5_1_1_I-O 设备的概念和分类
      • 5_1_4_I-O 软件层次结构
      • 5_1_5_I-O 核心子系统
      • 5_1_6_假脱机技术
      • 5_1_7_设备的分配与回收
      • 5_1_8_缓冲区管理
  • Linux

  • 计算机网络

  • 数据库

  • 编程工具

  • 装机

  • 计算机基础
  • 操作系统
  • 操作系统网课-王道考研
2023-05-15
目录

318_具有快表的地址变换机构

# 3.1_8_具有快表的地址变换机构

‍各位同学大家好。‍‍在这个小节中我们会学习具有快表的地址变换机构,那么这种地址变换机构其实是在上个小节学习的基本地址变换机构‍‍的基础上进行改进的一个版本,在这个基础上引进了快表机制。‍‍

‍

这个小节中我们会首先介绍什么是局部性原理,在理解了什么是局部性原理之后,大家才可以更好的理解‍‍为什么快表能够起作用。另外我们还会介绍在引入快表之后地址变换的一个过程,‍‍我们会按照从上至下的顺序依次讲解。‍‍

​ ‍

# 局部性原理

我们来看一个简单的小程序,‍‍在这个程序当中我们定义了一个 int 型的变量 i 还有一个 int 型的数组 a,这个数组总共有 100 个元素,‍‍之后会执行 100 次循环,每一次循环都会给 a 这个数组对应的元素进行一个赋值的操作。‍‍

那么这个程序在经过编译之后,可能会形成一系列与它对等的‍‍机器指令,然后这些指令有可能是放在某一个内存块当中的,比如说是放在 10 号内存块当中。‍‍除此之外,在这个程序当中定义的这些变量 i,还有像数组型的变量 a‍‍有可能是放在另外一个内存块当中的,比如说是 23 号内存块,‍‍

由于这个程序会一直循环的执行这一段代码,所以很显然这段程序‍‍在执行的过程当中,肯定会很频繁的访问到 10 号内存块‍‍和 23 号内存块,因为这些代码对应的指令是存放在 10 号内存块里的,而这个代码当中‍‍需要访问的这些变量又是存放在 23 号内存块当中的。‍‍由此我们引出了时间局部性和空间局部性两个概念。‍‍

所谓的时间局部性是指如果我们在程序当中执行了某一条指令,‍‍不久之后这条指令很有可能会被再次执行。‍‍如果某个数据被访问过,那不久之后这个数据很有可能会被再次访问。什么意思呢?‍‍用循环当中 i++ 这条代码来看,‍‍i++ 代码在经过编译之后,可能会形成与它对等的某一条机器指令,‍‍那么这条机器指令需要使用到 i 这个变量,并且由于我们的循环会执行 100 次,‍‍所以 i++ 对应的那条指令很有可能会很频繁的不断的执行 100 次,‍‍相应的在指令执行的过程中,也需要对 i 变量数据进行不断的访问。‍‍所以由于我们的程序当中存在着大量的循环操作,‍‍因此某一条指令被执行之后,在不久的将来很有可能会被再次执行。‍‍另外在循环当中的某一个变量,此次被访问之后,在不久的将来有可能会被再次访问,‍‍这就是时间局部性原理。‍‍

空间局部性又是指一个程序,在访问了某一个存储单元的不久之后,‍‍存储单元附近的那些存储单元也有可能被访问,还是以这个程序作为例子,‍‍我们的数组 a 总共有 100 个元素,那么这 100 个元素在内存当中其实是连续的存放在‍‍内存块当中的某一个区域当中的,在这个循环当中,我们如果访问了 a 这个数组的第一个元素,‍‍在之后不久的将来,a 这个数组的第二个元素,也就是与第一个元素相邻的存储单元,‍‍很有可能就会被再次访问,以此类推,第三个第四个第五个也是会在不久之后也会被连续的访问,‍‍所以我们定义的类似于数组这些的数据在内存当中都是连续存放的,‍‍因此我们在访问了某一个存储单元之后,很有可能会紧接着访问与它相邻的存储单元,‍‍这就是空间局部性

时间局部性和空间局部性可以统称为局部性原理。‍‍

在上个小节当中,我们介绍了基本地址变换机构,‍‍每次要访问一个逻辑地址,肯定都是需要查询内存当中的页表的。‍‍但是由于刚才我们介绍的这些局部性原理,我们会发现其实在程序运行的过程当中,‍‍很有可能会连续不断的对某一个内存块进行或者说某一个页面进行访问。‍‍既然会连续不断的访问同一个页面,那就意味着我们很有可能会连续很多次查到的都是同一个页表项。‍‍

既然如此,我们能不能利用特性来减少对列表的访问次数?‍‍‍‍基于这个原理,人们引入了快表机制

​

# 快表机制

快表又称为联想存储器,英文缩写是 TLB 这三个名称在题目当中都有可能会出现。

快表是一种访问速度要比内存快很多的‍‍高速缓冲存储器,快表可以用来存放当前访问的若干个页表项,‍‍用以加速地址变换的过程,那与快表相对应,内存当中的页表的查询速度,访问速度会更慢,‍‍所以内存当中的页表常称为慢表,

我们来看一个具体的例子加深理解。‍‍假设一个进程需要依次执行三条指令,‍‍这三条指令的存放位置分别是页号为 0 页内偏移量为 0 的逻辑地址,‍‍还有页号位 0,页内偏移量为 4 的逻辑地址,还有 08 这个逻辑地址,CPU 会依次执行这三条指令

在执行第一条指令的时候,‍‍程序计数器 PC 当中存放的应该是此时想要访问的那一条‍‍指令对应的逻辑地址,也就是页号为 0,页内偏移量为 0 的逻辑地址,‍‍这个逻辑地址会被拆分成页号和页内偏移量这样两个部分,‍‍之后会对页号进行合法性的检查,用页号和页表的长度进行对比,‍‍看看有没有发生越界对比的过程,咱们在上个小节介绍过,这就不展开了。‍‍

确认了页号的合法性之后,会用页号来查询快表,看一看快表当中有没有和页号对应的页表项。‍‍由于刚开始这个快表是空的,所以并没有找到与这个页号对应的页表项,‍‍也就是说查询快表是未命中的,‍‍

由于快表没有命中,所以接下来需要用页表始址和页号‍‍来计算出液号对应的页表项在内存当中存放的位置。‍‍

​ ‍

另外在查询到页号对应的页表项之后,‍‍系统会把页表项自动的复制到快表当中,‍‍这样的话快表当中就出现了一个与页表项相对应的一个副本,‍‍找到这个页号对应的页表项之后,我们当然就可以知道这个页面存放的‍‍内存块号到底是多少,根据内存快号和页内偏移量,我们就可以得到最终的物理地址,最后根据这个物理地址,‍‍CPU 就可以找到逻辑地址为 00 的那条指令存放的实际物理地址了。‍‍

​

在执行完第一条指令之后,会紧接着执行第二条指令。‍‍第二条指令在内存当中存放的位置应该是页号为 0,页内偏移量为 4‍‍的内存单元当中,那么和刚才一样,首先需要对页号进行合法性的检查,看一下它是否越界。‍‍如果这个页号没有越界的话,接下来会查询页表。‍‍但是由于我们想要查询的是 0 号页面,此时页表当中其实已经有了 0 号页面对应的页表项,‍‍所以我们在查询页表的时候就已经命中了,所以‍‍我们通过快表就可以直接知道 0 号页面对应的物理内存块号到底是多少。‍‍既然已经知道了 0 号页存放的内存块,‍‍接下来就不需要再查询内存当中的页表了,我们可以直接根据内存快号,还有页内偏移量就得到最终想要访问的物理地址。‍‍接下来 CPU 就会根据物理地址,从内存当中取出它要执行的第二条指令。‍‍所以从刚才的分析过程当中,我们也会发现,如果查询快表命中了,‍‍那么就不需要再查询内存了,因为查询快表的速度要比查询‍‍内存中页表的速度要快得多,所以如果查询快表命中的话,‍‍那么地址转换的过程就可以快很多。‍‍

​ ‍

继续回到刚才的过程,‍‍CPU 在执行完第二条指令之后,还会紧接着执行第三条指令的存放位置是 08 这个位置。‍‍那和刚才一样,首先需要检查页号的合法性,在确认页号合法之后再查询快表,‍‍结果发现快表当中已经有与页号对应的页表项了,于是我们可以直接得到页面存放的内存快号,‍‍然后再结合页内偏移量,最终就可以得到第三条指令存放的实际物理地址到底是多少。‍‍

从刚才的分析当中也可以看到,其实快表当中存放的是页表的一部分副本内容

# 引入块表后,地址的变换过程

接下来我们根据之前分析的这些过程来总结一下,引入了快表之后地址变换的过程是怎么样的。‍‍第一步 CPU 会给出一个逻辑地址,‍‍然后由某个硬件根据这个逻辑地址算得页号和页内偏移量这两个信息,‍‍并且会把页号和快表当中的所有页号进行比较。‍‍如果说在快表当中找到了相匹配的页号,‍‍那就说明我们要访问的页表项在快表当中是有一个副本的,我们就可以直接从快表当中取出页表项,‍‍对应的内存块号到底是多少,那之后再把内存块号和页内偏移量拼接成最终的物理地址,‍‍最后再访问物理地址对应的内存单元就可以了。‍‍所以从这个过程中我们可以看到,如果说快表命中的话,那么访问某一个逻辑地址‍‍仅需要一次访存的操作。

如果说我们在页表当中没有找到与页号相匹配的项的话,‍‍那么就需要在访问内存当中的页表。注意页表指的是慢表,‍‍找到了对应的页表项之后,就可以得到这个页面存放的实际的内存括号,‍‍之后再把内存括号和页内偏移量拼接成一个物理地址。‍‍最后根据物理地址在访问我们最终想要访问的内存单元。‍‍

所以从这个过程中我们可以看到,如果快表没有命中的话,那么我们想要访问某一个逻辑地址需要两次访存,‍‍第一次是查询内存当中的页表,第二次才是访问我们最终想要访问的内存单元,‍‍

这个地方大家需要注意的是,在找到了慢表当中的页表项之后,‍‍需要同时把页表项把它复制到快表当中,‍‍这是基于局部性原理的考虑,因为这个页表相对应的页面很有可能在后面会被再次访问到。‍‍不过如果快表当中已经存不下了,那么我们需要按照一定的算法对旧的页面项‍‍进行替换,我们到底可以用什么算法?这个问题我们会在之后学习页面置换相关的那些小节当中进行介绍,‍‍这儿就先不展开。

由于查询快表的速度要比查询慢表,也就是内存当中的页表的速度要快很多,‍‍所以只要快表命中的话,我们就可以节省很多地址转换的时间,‍‍而因为局部性原理一般来说跨表的命中率可以很高,可以达到 90% 以上。‍‍

我们来看一个例题,‍‍假设某一个系统当中使用基本分页存储管理,并且采用了具有快表的地址变换机构,‍‍访问一次快表耗时一微秒,访问一次内存耗时 100 微秒,‍‍如果快表的命中率是 90% 的话,访问一个逻辑地址的平均耗时应该是多少?‍‍通过刚才的分析可以知道,‍‍在访问一个逻辑地址的时候,首先会根据页号去优先的查询快表,查询快表的耗时是一微秒,‍‍如果说快表命中的话,‍‍就可以得到这个逻辑地址对应的最终的物理地址,接下来就再进行一次访问内存的操作,‍‍也就是访问我们最终想要访问的物理内存单元就可以了,所以如果快表命中的话,‍‍耗时应该是 1+100,也就是 101 微秒,那快表命中的概率是 90%,所以我们给它乘上一个 0.9 的权值。‍‍

另一方面如果我们查询快表没有命中的话,那么我们就需要访问内存当中的慢表,‍‍所以这会产生更多一次的访问内存的操作。‍‍最后再根据内存块号和页内片一量得到物理地址,然后对物理地址‍‍进行访问,所以这儿又是一次访问内存的操作。‍‍‍‍由于快表未命中的概率是 10%,所以这儿乘上一个 0.1 的权值,因此‍‍平均下来访问一个逻辑地址的平均耗时应该是 111 微妙。‍‍

在这个计算过程当中,我们默认是先查询快表,当快表查询失败之后才会去查询页表,‍‍但是在有的系统当中,它会支持快表和慢表同时查询,‍‍如果快表查询成功了,那么就会停止慢表的查询操作。‍‍所以在这种系统当中,慢表和快表的查询是同时开始的。‍‍因此在这种系统当中,如果说我们的快表没有命中的话,‍‍那么总共的查询耗时应该就是慢表的查询时间 100,再加上最终访问内存的时间 100 也就是 200。‍‍

所以如果题目当中告诉我们这个系统是支持快表和慢表同时查询的话,‍‍那么访问一个逻辑地址的平均耗时应该是 110.9 微秒。不过如果题目当中没有明确的告诉我们的话,‍‍我们是默认首先需要查询快表,当快表查询失败之后才会继续查询慢表,‍‍这是有可能在题目当中出现的一个小细节。‍‍

最后我们再来看一下,如果说没有采用快表机制的话,那么访问一个逻辑地址‍‍肯定是需要先查询一次慢表,然后才能找到最终要访问的内存单元。‍‍所以在这种情况下访问一个逻辑地址需要的平均耗时就应该是 200 微秒。‍‍在这个例题当中引入了快表机制之后,地址转换的耗时几乎是减了一半,‍‍所以这就可以大幅度的提高我们计算机的性能。‍‍

​

# 小结

这个小节中我们学习了具有快表的地址变换机构,‍‍这个小节当中大家需要着重掌握,引入了快表机制之后,地址变换的过程是什么样的,‍‍相比于上个小节学习的基本地址变换机构来说,引入了快表机制之后,‍‍地址变换的过程当中会优先的检查快表,‍‍如果快表命中了,那么就可以直接从快表当中就知道我们想要找的页面存放的内存快号到底是多少,那就可以直接通过内存块号得到物理地址。‍‍

如果说快表没有命中的话,才需要再去查询内存当中的页表或者说慢表,‍‍并且我们还需要将慢表当中的页表项复制到快表当中,‍‍这是基于局部性原理得到的一种处理的策略

另外大家也需要能够自己分析,‍‍在采用这两种地址变换机构的情况下,访问一个逻辑地址到底需要几次访存,‍‍基本地址变换机构当中肯定是需要查询内存当中的页表的,所以一定需要两次访存。‍‍而如果说引入了快表机制之后,‍‍如果快表命中就不需要在查询内存当中的页表,所以只需要一次保存,如果快表没有命中,那么还需要查询一次‍‍内存当中的页表,所以需要两次访存。

​

上次更新: 2025/5/9 14:55:39
3_1_7_基本地址变换机构
3_1_9_两级页表

← 3_1_7_基本地址变换机构 3_1_9_两级页表→

最近更新
01
学点统计学:轻松识破一本正经的胡说八道
06-05
02
2025 年 5 月记
05-31
03
《贫穷的本质》很棒,但可能不适合你
05-27
更多文章>
Theme by Vdoing | Copyright © 2022-2025 | 粤 ICP 备 2022067627 号 -1 | 粤公网安备 44011302003646 号 | 点击查看十年之约
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式