操作系统的灵魂--MMU详解

虚拟内存是现代操作系统中最伟大的发明之一。它为每个进程提供了一个一致的、私有的地址空间,让每个进程产生了一种自己在独享主存的错觉。

为了讲清楚MMU是如何一步一步完成地址翻译,取出数据的,本篇文章在前4节中讲解了虚拟内存中一些重要的概念,比如,虚拟内存的作用,页命中,缺页异常处理,为什么需要TLB等等。最后,通过两个地址翻译的例子,详细解释了MMU地址翻译的过程。

1. 什么是虚拟内存?

  • 虚拟内存能够创建一个连续的更大的空间给进程使用,出现的原因是由于主存的空间是有限。

  • 当运行多个进程或者一个进程需要更大的空间进行存储运行,主存显然是不够的,这个时候就需要更大更便宜的磁盘进行保存一部分数据。

  • 对于进程来说,虚拟内存就是一张连续的内存空间,这个空间有些在主存中,有些在磁盘中。

2. 虚拟内存的作用

  • 虚拟内存将主存看成是一个存储在磁盘上的地址空间的高速缓存,在主存中只保存活动区域,并根据需要在磁盘和主存之间来回传送数据,通过这种方式,可以高效地使用主存。

  • 虚拟内存为每个进程提供了一致的地址空间,简化了内存管理。

  • 虚拟内存保护了每个进程的地址空间不被其他进程破坏。

3. 虚拟内存与物理内存

3.1 CPU存取数据

CPU通过MMU找到虚拟地址对应的物理地址

我们先来看下,CPU是如何根据地址取得数据的。

CPU 在这里生成的物理地址为 4,把地址发送给内存,然后内存从该地址获取其中保存的字,最后将其发送回 CPU。

MMU(Memory Management Unit)叫做内存管理单元,主要用来管理虚拟内存与物理内存的映射,由硬件自动完成。

3.2 物理地址常用术语

物理地址

这里需要比较烧脑地介绍几个名词,后面理解MMU地址翻译的时候会用到。

  • 物理内存(physical memory),主存RAM,实际能使用的物理空间。

  • 物理页(physical page),把物理内存按照页表的大小进行划分。

  • 物理地址(physical address,PA), 物理内存划分了根据物理页划分为很多块,通过物理地址进行定位。

  • 物理页号(physical page number,PPN) ,定位缓存中的数据字。

  • 物理页号偏移 (physical page offset, PPO),定位缓存中的数据块。

  • 缓存标记(cache tag,CT),在高速缓存中作为行匹配。

  • 缓存索引(cache index,CI),在高速缓存中作为组索引。

  • 缓存偏移(cache offset,CO),在高速缓存中用作行内偏移来选择目的数据块。

  • 物理页号偏移PPO = 组索引CI + 行内偏移CO。

  • 物理页号PPN = 行匹配CT。

  • 物理地址 PA = 物理页号 + 物理页号偏移 = PPN * page size + ppo。

3.3 虚拟地址常用术语

虚拟地址

  • 虚拟内存(virtual memory),每个程序独有,存放在磁盘上,由多个虚拟页(VP, virtual page)组成。

  • 虚拟内存的地址编码称虚拟地址空间(virtual address space VAS),跟物理内存一样,但虚拟内存是每个进程独有的,其大小是根据操作系统的指令集位有关,如32位,64位,32位,每个进程就有4G,64位有个百亿的GB。

  • 虚拟页(virtual page,VP ),把虚拟内存按照页表的大小进行划分。

  • 虚拟地址(virtual address),通俗说是计算机进程加载地址的指令,进程给的虚拟地址通过MMU进行获取地址计算物理地址空间,然后获取物理地址对应的数据传送到CPU上。

  • 虚拟页号(virtual page number ,VPN) ,用于定位页表的PTE。

  • 虚拟页号偏移(virtual page offset VPO) ,跟PPO值一样,定位物理内存的地址。

  • TLB索引(TLB index,TLBI),在页表中作为组索引。

  • TLBT标记(TLB tag,TLBT),在页表中作为行匹配。

  • 虚拟页号VPN = TLBT + TLBI。

  • 虚拟地址 VA = 虚拟页号 + 虚拟页号偏移 。

3.4 页表常用术语

页表

  • 页表(page tables),虚拟地址与物理地址的对应表集合。进程虚拟地址转换成物理地址,程序需要用到数据放在物理主存或磁盘某个位置,页表是存储在主存中。

  • 页表条目(page table entry PTE),虚拟地址与物理地址具体对应记录。页表是由多个页表条目PTE组成的数组,PTE 由一个有效位 和 n位地址字段组成,如果设置了有效位,那么地址字段就标识DRAM中相应的物理页的起始位置。

3.5 页命中/缺页

页命中

  1. 处理器产生一个虚拟地址。

  2. MMU生成PTE地址,并从高速缓存/主存请求得到它。

  3. 高速缓存/主存向MMU返回PTE。

  4. MMU构造物理地址,并把它传送给高速缓存/主存。

  5. 高速缓存/主存返回所请求的数据字给处理器。

缺页

  1. 处理器产生一个虚拟地址。

  2. MMU生成PTE地址,并从高速缓存/主存请求得到它。

  3. 高速缓存/主存向MMU返回PTE。

  4. PTE中的有效位是零,所以MMU触发了一次异常,传递CPU中的控制到操作系统内核中的缺页异常处理程序。

  5. 缺页处理程序确定出物理内存中的牺牲页,如果这个页面已经被修改了,则把它换出到磁盘。

  6. 缺页处理程序页面调入新的页面,并更新内存中的PTE。

  7. 缺页处理程序返回到原来的进程,再次执行导致缺页的指令。CPU将引起缺页的虚拟地址重新发送给MMU。因为虚拟页面现在缓存在物理内存中,所以就会命中,主存就会将所请求字返回给处理器。

相关视频推荐

搞懂底层原理-linux内核,高级程序员的必经之路:linux内核源码(进程管理、内存管理、网络协议栈、设备驱动、文件系统)icon-default.png?t=N7T8https://www.bilibili.com/video/BV1Pd4y1H7aL/

Linux C/C++开发(后端/音视频/游戏/嵌入式/高性能网络/存储/基础架构/安全)

需要C/C++ Linux服务器架构师学习资料加qun812855908获取(资料包括C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享

4. 为什么有了高速缓存,还需要TLB呢?

局部性原则保证了在任意时刻, 程序将往往在一个较小的活动页面集合上工作,这个集合叫做工作集或者常驻集。

换句话说, 局部性原则揭示了一个现象:在一段时间内,我们会反复调入或调出同一个或几个虚拟页页面。而且,每次CPU产生一个VA时, MMU就必须查阅PTE,以便将VA翻译为PA, 注意是每次,所以开销很大。

解决方法: 为了消除这样的开销,在MMU中包括了一个关于PTE的小缓存,称为翻译后备缓冲器,TLB(Translation Lookaside Buffer)。

关键点: 所有的地址翻译步骤都是在芯片上的MMU中执行的, 因此执行速度非常快。

说了这么多,下面就是本文的重点,我们看两个例子,虚拟地址是如何转换为物理地址的。

5. MMU是如何完成地址翻译的?

5.1 准备工作

5.1.1 内存系统的基本条件

简单内存系统的地址组成

假设我们有一个简单内存系统,我们做出如下规定:

  • 虚拟地址(VA):14 位

  • 物理地址(PA):12 位

  • 页面大小:64 字节

  • 虚拟页号(VPN):8位

  • 虚拟页面偏移量(VPO):6 位(64 = 2^6)

  • 物理页号(PPN):6位

  • 物理页偏移量(PPO):6位

5.1.2 TLB

TLB

假设TLB 有 16 个条目,并且是 4 路组相连的。TLB 缓存的是页表条目,页表条目是虚拟页号的唯一标识。所以,我们只需要用虚拟页号去访问 TLB。

我们使用 VPN 的低两位(2^2=4)作为组索引。剩下的6位作为标记位。然后用不同的值来初始化 TLB。

左边的红色区域(第一个列)并不是 TLB 的条目,仅仅是为了方便区分是哪一组。

我们只根据索引来查找组,每一个条目都有一个标记位。一个 TLB 条目如果有效,它就含有一个物理地址。

5.1.3 页表

页表的前 16 个条目

现在,我们还需要页表。假设,图中是我们页表的前 16 个条目。每一个页表有一个物理页号和一个有效位。

如果有效位有效,则表示那个虚拟页面对应的物理页面在内存中,并且 PPN 项给出了对应的物理页号。

5.2 产生虚拟地址

CPU产生的虚拟地址

假设 CPU 执行了一条指令,它产生了一个有效地址 0x3d4。它把这个地址传递给了 MMU。

我们需要找出对应的物理地址,然后从缓存或内存中取出数据。

在这个例子中,虚拟页面偏移(VPO)是0x24,虚拟页号(VPN)是 0xf,TLB 索引(TLBI)是虚拟页号的低两位是 0b11,也就是 0x3。TLB 标记位(TLBT)是 3。

TLB

MMU 做的第一件是就是查询 TLB,所以,我们先取出索引位,值为 3。

我们找到第 3 组,我们在第 3 组中找标记位为 3 的表项。

遍历这 4 个条目,有一个标记位为 7 的项,但它不是我们想要的,它的有效位为 0。再往后找,找到一个标记位为 3 并且有效位为 1。

所以,我们在 TLB 中找到了页表条目。页表条目返回这个值。MMU 返回的物理页号是 0x0D。

5.3 构造物理地址

构造物理地址

现在我们可以构造物理地址,PPO的值总是等于VPO的值,可以直接拷贝过来,为0x24。

PPN的值从 TLB 缓存的 PTE 中得到,为0x0d。合在一起构成了物理地址 0x354。

下一步是使用这个物理地址去看高速缓存中有没有这个物理地址的缓存。

5.4 遍历高速缓存

把 0x354送入高速缓存,请求高速缓存返回对应物理地址上的值,在这个例子中,我们只需要返回一个字节。

高速缓存

高速缓存收到请求后,首先去检查高速缓存中是否有块缓存了该字节。

高速缓存先取出物理地址的索引位是 0b00101,也就是 0x5。

接着去第 5 组找。找标记位为 0xd 的项,有一个匹配的标记位且有效位为 1。这就是我们要在高速缓存中找的项。

偏移量是 0,所以我们去请求第五组偏移量为 0 的字节,值为 0x36。

缓存命中,高速缓存把这个字节返回给 MMU, MMU 把它传递给处理器。最后处理器可能把这个字节存储在一个寄存器里。

以上就是一个完整的地址翻译的例子,在这个例子中,并没有出现缺页的情况。

下面我们看一个在缺页异常处理中,是如何完成地址翻译的。

5.5 缺页处理

好了,我们来看下一个例子。这次 CPU 发送给 MMU 的虚拟地址是 0x0020。

虚拟地址0x0020

和之前的例子一样,我们可以得到VPN为0x00,VPO为0x01,TLBI为0,TLBT为0x00。

TLB

第一步是检查 TLB 看是否有页表条目的缓存。

在 TLB 中,如果缓存存在,它应该在第一组,并且它的标记位应该为 0。所以,我们在第 0 组内找标记位为 0 的项。

第一项是 0x03,不匹配,第二项是 0x09,不匹配,第三项是 0x00,匹配,但是有效位为 0。所以,这次 TLB 缓存不命中。

TLB不命中只能去页表中查找

查找缓存失败了,我们只能去内存中去读取页表中对应的页表条目。

查看页表,寻找虚拟页号为 0 的项。检查对应的页表条目,看虚拟页是否在内存中。

虚拟页号为 0 的项的有效位为1,我们就可以得到一个物理页号为0x28。根据物理页号和物理页面偏移量就可以构造出物理地址。

构造物理地址

现在 MMU 拥有了物理地址,就可以将其发送到高速缓存。并请求高速缓存返回对应的物理地址上的一个字节。

构造出的物理地址

高速缓存得到了这个物理地址。它取出对应的索引位,在这个例子中是 0x8。

所以我们去高速缓存的第八组,然后寻找对应的标记位,在这个例子中是0x28。

第八组有一个条目,它的标记位是 24,这里是一次缓存不命中。

所以,缓存就要向内存传递物理地址去得到所需要的字节。相关内容本篇就不再做具体讲解。

6. 总结

虚拟存储器的工作原理是有一些复杂,本文描述的也并不全是最真实的计算机中的工作方式,比如,PTE由一个有效位和一个地址字段组成其实是为了便于理解而假设出来的。

但是这种方式成功的解决了直接使用物理内存会出现的问题。比如,虚拟内存中连续存储解决了物理内存碎片化,资源利用率过低的问题;每个进程只能访问自己独立的用户空间而内核空间是共用的解决了进程间的安全问题;缺页异常和选择牺牲页的算法提高了内存读写的效率等等。

我们应该对虚拟存储器的工作原理有深层次的理解,可以更好的帮助我们理解系统是如何工作的,也可以帮助我们避免在使用malloc这类的管理虚拟存储器的分配程序时遇到的一些错误。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【代码随想录】刷题笔记Day54

前言 差单调栈就结束代码随想录一刷啦,回家二刷打算改用python补充进博客,小涛加油!!! 647. 回文子串 - 力扣(LeetCode) 双指针法 中心点外扩,注意中心点可能有一个元素可能有两个…

Java-SPI机制

SPI基本概念 SPI(Service Provider Interface)是一种服务发现机制,为某个接口寻找服务实现的机制。这有点类似 IoC 的思想,将装配的控制权移交到了程序之外。SPI 将服务接口和具体的服务实现分离开来,将服务调用方和服…

理解反向代理

反向代理是一个不可或缺的组件。 它在客户端和服务器之间充当中介,提高了安全性、负载平衡和应用性能。 一、反向代理简介 反向代理是一种服务器,它位于客户端和后端服务器之间。与常见的(正向)代理不同,反向代理代表…

爬取A站视频,涉及m3u8格式的处理

一、抓包分析 1.进入A站进行抓包分析 进入一个页面,右点击鼠标按钮,点击检查 接着点击network,点击Fetxh/XHR,然后刷新网页,得到下面的页面 发现其中有许多d595开头的文件,它们是ts文件,点击其中一个。在…

v38.Switch语句

1.Switch语句可以替代if-else语句 2.具体使用 Switch(expression) { case label:...... } ①将x与case后的label 进行比较; ②注意后面有冒号; ③从上往下开始检查case; ④如果…

Transform模型详解

Transformer模型详解 Encoder与Decoder输入单词Embedding位置 Embedding 自注意力机制Self-Attention 结构Self-Attention 的输出Multi-Head Attention Encoder 结构Add & NormFeed Forward组成 Encoder Decoder结构Decoder第一个 Multi-Head AttentionDecoder第二个 Multi…

响应式Web开发项目教程(HTML5+CSS3+Bootstrap)第2版 例4-9 HTML5 表单验证

代码 <!doctype html> <html> <head> <meta charset"utf-8"> <title>HTML5 表单验证</title> </head><body> <form action"#" method"get">请输入您的邮箱:<input type"email&q…

【AI的未来 - AI Agent系列】【MetaGPT】6. 用ActionNode重写技术文档助手

文章目录 0. 前置推荐阅读1. 重写WriteDirectory Action1.1 实现WriteDirectory的ActionNode&#xff1a;DIRECTORY_WRITE1.2 将 DIRECTORY_WRITE 包进 WriteDirectory中 2. 重写WriteContent Action2.1 思考重写方案2.2 实现WriteContent的ActionNode2.3 改写WriteContent Act…

记录一下对集合排序,处理属性为空且参与排序方法

一、需求 实际项目中经常存在对集合某个或多个属性进行排序&#xff0c;例如根据姓名排序&#xff0c;根据金额排序&#xff1b;或者多个字段排序&#xff0c;例如姓名首字母升序金额降序两个字段排序等等。 但是有时候姓名或金额会为空&#xff0c;之前我们排序的时候需要拿出…

(Bean工厂的后处理器入门)学习Spring的第七天

一 . Bean工厂的后处理器入门 : 直接上图 BeanDefinitionRegistyPostProcessor 为 BeanFactoryProcessor的子接口 , 前者先执行(图里只有Bean工厂的后处理器第一个类型) 如下图 : 这两个接口可改变两个Map(BeanDefinitionMap , singletonObject)里的信息 (黑马只讲了BeanFact…

linux LPT和COM回路测试(基于python+Qt+C++)

软件UI: 回路治具&#xff08;COMLPT&#xff09;&#xff1a; lpt_test.cpp&#xff08;c 源代码&#xff09;&#xff1a; #include <iostream> #include <fstream> #include <sstream> #include <unistd.h> #include <fcntl.h> #include <…

SCDN高防如何保护你的服务器

随着互联网的发展&#xff0c;如今的网络世界&#xff0c;虽说给我们的衣食住行带来了非常大的便利&#xff0c;但同时它存在着各种各样的威胁。比如我们的网站&#xff0c;如果不做任何保护措施的话&#xff0c;就很容易被DDoS、CC等攻击堵塞网络、窃取目标系统的信息&#xf…

惬意上手Python —— 装饰器和内置函数

1. Python装饰器 Python中的装饰器是一种特殊类型的函数&#xff0c;它允许用户在不修改原函数代码的情况下&#xff0c;增加或修改函数的行为。 具体来说,装饰器的工作原理基于Python的函数也是对象这一事实&#xff0c;可以被赋值给变量、作为参数传递给其他函数或者作为其他…

【易经】-- 风水基础

目录 一、基础概念 1、五行 2、十天干 3、十二地支 4、八卦 4.1 伏羲八卦次序图 4.2 八卦对应自然界的基本事物 4.3 八卦及所代表的意像 ​编辑 5、生辰八字 5.1 定义 5.2 换算方法 5.3 举例 5.4 八字排盘示例 5.5 算法实现 二、举例 1、计算某年的生肖和年的属…

【nginx实战】nginx正向代理、反向代理、由反向代理实现的负载均衡、故障转移详解

文章目录 一. 正向代理与反向代理的概念二. Nginx服务器的正向代理服务1. Nginx服务器正向代理服务的配置的3个指令1.1. resolver指令1.2. resolver_timeout指令1.3. proxy_pass指令 2. Nginx服务器正向代理服务的使用 三. Nginx服务器的反向代理服务1. 反向代理的基本指令1.1.…

高数总结(1

目录 1.总结&#xff1a;小结&#xff1a; 1.总结&#xff1a; 小结&#xff1a; 关注我给大家分享更多有趣的知识&#xff0c;以下是个人公众号&#xff0c;提供 ||代码兼职|| ||代码问题求解|| 由于本号流量还不足以发表推广&#xff0c;搜我的公众号即可&#xff1a;

基于51单片机的超声波物位测量系统[proteus仿真]

基于51单片机的超声波物位测量系统[proteus仿真] 超声波检测系统这个题目算是课程设计和毕业设计中常见的题目了&#xff0c;本期是一个103基于51单片机的超声波物位测量系统 需要的源文件和程序的小伙伴可以关注公众号【阿目分享嵌入式】&#xff0c;赞赏任意文章 2&#xf…

Redis 笔记二

概览 1.高并发秒杀问题及可能出现的bug 2.秒杀场景JVM级别锁和分布式锁 3.大厂分布式锁Redisson框架 4.从Redisson源码剖析lua解决锁原子性问题 5.从Redisson源码剖析经典锁续命问题 6.Redis主从架构锁失效如何解决 7.Redlock分布式锁高并发下可能存在的问题 8.双十一大促如何将…

【学习】FPN特征金字塔

论文&#xff1a;Feature Pyramid Networks for Object Detection &#xff08;CVPR 2016) 参考blog&#xff1a;https://blog.csdn.net/weixin_55073640/article/details/122627966 参考视频讲解&#xff1a;添加链接描述 卷积网络中&#xff0c;深层网络容易响应语义特征&am…

【C++】list容器功能模拟实现

介绍 上一次介绍了list队容器的迭代器模拟&#xff0c;这次模拟实现list的简单功能&#xff0c;尤其要注意构造函数、析构函数、以及赋值运算符重载的实现。 list容器需要接纳所有类型的数据&#xff0c;因此&#xff0c;结构设置与迭代器设置同理&#xff0c;需要引入结点&…