读懂操作系统之快表(TLB)原理(七)
前言
前不久、我们详细分析了TLB基本原理,本节我们通过一个简单的示例再次叙述TLB的算法和原理,希望借此示例能加深我们对TLB(又称之为快表,深入理解计算机系统(第三版)又称之为翻译后备缓冲区)的理解。
使用分页作为支持虚拟内存的核心机制可能会导致高性能开销,通过将地址空间划分成固定大小的小单元(即页面),分页需要映射大量信息,由于该映射信息通常存储在物理内存中,因此在逻辑上分页需要针对程序生成的每个虚拟地址进行额外的内存查找,在每条指令获取或显式加载或存储之前进入内存获取翻译信息的速度会非常慢。因此,我们的问题演变为:如何对逻辑地址进行高速翻译?我们如何加快地址转换的速度从而避免在分页时需要额外的内存引用?硬件支持是必要的吗?哪些操作需要操作系统参与?
TLB(快表,翻译后备缓冲区)原理和练习
当我们想加快查找速度时,通常需要借助于操作系统通常来完成,那就是来自操作系统的老朋友:硬件。为了加快地址翻译速度,我们将添加一个称为翻译后备缓冲区(TLB),TLB是芯片的内存管理单元(MMU)的一部分,因此,TLB是虚拟地址到物理地址翻译的硬件缓存。在每次引用虚拟内存时,硬件首先检查TLB,以查看是否已保留了所需的翻译(PTE),否则,硬件将检查TLB。如此这样将执行快速翻译而不必每次都去查阅页表(包含所有翻译),因每次进行内存引用必将对对性能的巨大影响,所以从另外一个角度讲,实际上TLB使虚拟内存成为可能。逻辑地址并计算出VPN、如何查找TLB、TLB缺失后如何处理等等通过图解方式来进行详细叙述,这里我们通过伪代码方式来进一步讲解TLB整个大概原理过程若有错误之处,还请批评指正,存有疑惑之处,还请先看操作系统专辑中对此更容易理解的叙述
VPN = (VirtualAddress & VPN_MASK) >> SHIFT;
(Success, TlbEntry) = TLB_Lookup(VPN);
if (Success == true)
{
if (CanAccess(TlbEntry.ProtectBits) == true)
{
Offset = VirtualAddress & OFFSET_MASK;
PhysAddr = (TlbEntry.PFN << SHIFT) | Offset;
Register = AccessMemory(PhysAddr);
}
else
{
RaiseException(PROTECTION_FAULT);
}
}
else
{
PTEAddr = PTBR + (VPN * sizeof(PTE));
PTE = AccessMemory(PTEAddr);
if (PTE.Valid == False)
RaiseException(SEGMENTATION_FAULT);
else if (CanAccess(PTE.ProtectBits) == false)
RaiseException(PROTECTION_FAULT);
else
TLB_Insert(VPN, PTE.PFN, PTE.ProtectBits);
RetryInstruction();
}
从逻辑地址提取出VPN(第1行),调用TLB_Lookup方法查找TLB中是否存持有VPN的翻译(第2行),获取到TLB是否命中的标识(Success)和TLB条目。若TLB命中(第3行),获取TLB条目中的保护位并调用CanAccess方法判断是否可访问(第5行),若可访问,从逻辑地址中提取出偏移量(第7行)。通过TLB条目中的物理页帧号即PFN、页偏移量以及基于页起始位置偏移计算出物理地址(第8行),传递物理地址并调用访问主存方法AccessMemory,使得寄存器指向主存地址空间(第9行)若TLB缺失(第16行),通过VPN和页表基寄存器计算PTE地址(第18行),传递PTE地址调用访问主存方法AccessMemory,这里是访问主存页表从而获取PTE,很显然,访问主存页表将导致额外的内存引用,操作成本很高(第19行),若PTE有效位为无效(第20行),则引发错误(第21行),同理若不可访问则引发保护位错误,这个时候将交由操作系统来进行缺页处理进行页面置换。否则调用TLB_Insert方法,将VPN和PTE中的PFN和保护位插入到TLB条目(第25行),一旦更新了TLB条目,那么硬件将重试缺页指令,如此将加速翻译,快速处理内存引用(第26行)
为了更清楚说明TLB的作用,我们通过一个简单的示例来跟踪虚拟地址翻译,最后看看TLB如何改善其性能。在此示例中,假设内存中有10个4字节整数的数组,从虚拟地址100开始。进一步假设我们有一个小的8位虚拟地址空间,具有16字节页面;因此,虚拟地址分为4位VPN(有16个虚拟页面)和4位偏移(即每页面有16个字节)。如下求数组元素之和
int sum = ;
var array = new[] { , , , , , , , , , };
for (int i = ; i < ; i++)
{
sum += array[i];
}
上述数组中的10个元素在页表中的存放大概如下图所示,第1个元素位于(VPN = 6,偏移量 = 4),所以在第6页只能容纳3个4个字节整数元素,紧接着其他元素则分别放在第7和第8页。

为了简单起见,我们假设循环生成的唯一内存访问就是对数组的访问,忽略变量i和sum以及指令本身。当访问第一个数组元素(a[0])时,CPU将加载100的虚拟地址,硬件从地址中提取VPN(VPN = 06),并使用该地址检查TLB的有效转换,假设这是程序第一次访问数组,则结果将是引起TLB缺失。下一步开始访问元素a[1],好消息是:TLB命中,因为数组的第二个元素紧挨着第一个元素,所以它位于同一页上,因为在访问数组的第1个元素时已经访问了此页面,所以翻译已经加载到了TLB中。当访问元素a[3]时,此时又会引起页缺失,但接下来的a[4]..a[6]都将命中,因为它们和a[3]都在内存中同一页上。我们总结一下对数组的10次访问期间的TLB活动:未命中,命中,命中,未命中,命中,命中,命中,未命中,命中,命中。因此,我们的TLB命中率(即命中数除以访问总数)为70%
虽然这不是太高(实际上,我们希望命中率接近100%),但它不是零,这可能令人惊讶。即使这是程序第1次访问该数组时,由于空间局部性,TLB还是会提高性能。数组的元素紧密地包装在页面中(即它们在空间上彼此靠近),因此只有第1次访问页面上的元素才会产生TLB未命中。其实这也我们联想到了为何要进行缓存预热,因为第1次访问会导致缓存强制缺失。如果页面大小只是原来的2倍(32字节,而非16字节),则数组访问将遭受更少的丢失。由于典型的页面大小是4KB,因此这些类型的密集,基于数组的访问可凸显出出色的TLB性能,每页访问仅遇到一次未命中。
关于TLB性能的最后一点:如果程序在此循环完成后不久再次访问了数组,则假设我们有足够大的TLB来缓存所需的翻译,那么我们可能会看到更好的结果:命中,命中,命中,命中,命中,命中,命中,命中,命中,命中。在这种情况下,由于时间局部性即时间上的快速重新引用,TLB命中率会很高,像任何高速缓存一样,TLB依赖于时间和空间局部性而获得成功,程序具备这两个属性,往往大多时候,此二者不可同时兼得。
总结
相信之前和通过本节专述TLB原理,同时结合一个简单的示例详细的讲解,能够让大家更加明白TLB的实际作用,下一节我们进入关于操作系统内存管理最后一小节内容作为总结,然后我们开始进入程序执行、线程、进程等内容,感谢您的阅读,我们下节见。
读懂操作系统之快表(TLB)原理(七)的更多相关文章
- 读懂操作系统之缓存原理(cache)(三)
前言 本节内容计划是讲解TLB与高速缓存的关系,但是在涉及高速缓的前提是我们必须要了解操作系统缓存原理,所以提前先详细了解下缓存原理,我们依然是采取循序渐进的方式来解答缓存原理,若有叙述不当之处,还请 ...
- 读懂操作系统之虚拟内存TLB与缓存(cache)关系篇(四)
前言 前面我们讲到通过TLB缓存页表加快地址翻译,通过上一节缓存原理的讲解为本节做铺垫引入TLB和缓存的关系,同时我们来完整梳理下从CPU产生虚拟地址最终映射为物理地址获取数据的整个过程是怎样的,若有 ...
- 【Java基本功】一文读懂String及其包装类的实现原理
String作为Java中最常用的引用类型,相对来说基本上都比较熟悉,无论在平时的编码过程中还是在笔试面试中,String都很受到青睐,然而,在使用String过程中,又有较多需要注意的细节之处. S ...
- 读懂操作系统(x86)之堆栈帧(过程调用)
前言 为进行基础回炉,接下来一段时间我将持续更新汇编和操作系统相关知识,希望通过屏蔽底层细节能让大家明白每节所阐述内容.当我们写下如下C代码时背后究竟发生了什么呢? #include <stdi ...
- 读懂操作系统(x64)之堆栈帧(过程调用)
前言 上一节内容我们对在32位操作系统下堆栈帧进行了详细的分析,本节我们继续来看看在64位操作系统下对于过程调用在处理机制上是否会有所不同呢? 堆栈帧 我们给出如下示例代码方便对照汇编代码看,和上一节 ...
- 一篇文章读懂HTTPS及其背后的加密原理
HTTPS(全称: Hypertext Transfer Protocol Secure,超文本传输安全协议),是以安全为目标的HTTP通道,简单讲是HTTP的安全版.本文,就来深入介绍下其原理. 1 ...
- 一文读懂机器学习大杀器XGBoost原理
http://blog.itpub.net/31542119/viewspace-2199549/ XGBoost是boosting算法的其中一种.Boosting算法的思想是将许多弱分类器集成在一起 ...
- 《一篇文章读懂HTTPS及其背后的加密原理》阅读笔记
HTTPS(Hypertext Transfer Protocol Secure,超文本传输安全协议),是以安全为目标的HTTP通道,简单讲是HTTP的安全版.这篇文章深入介绍了它的原理. 当我们适用 ...
- 一文读懂 SuperEdge 边缘容器架构与原理
前言 superedge是腾讯推出的Kubernetes-native边缘计算管理框架.相比openyurt以及kubeedge,superedge除了具备Kubernetes零侵入以及边缘自治特性, ...
随机推荐
- 3分钟理解NMS非极大值抑制
1. NMS被广泛用到目标检测技术中,正如字面意思,抑制那些分数低的目标,使最终框的位置更准: 2. 假如图片上实际有10张人脸,但目标检测过程中,检测到有30个框的位置,并且模型都认为它们是人脸,造 ...
- webpack的入门实践,看这篇就够了
webpack的入门实践 我会将所有的读者概括为初学者,即使你可能有基础,学习本节之前我希望你具有一定的JavaScript和node基础 文中的 ... ...代表省略掉部分代码,和上面的代码相同 ...
- 只需几行 JavaScript 代码,网页瞬间有气质了!
最近在网上闲逛,发现一个特别好玩的 JavaScript 库,叫 RoughNotation.干嘛用的呢?就是在网页上给文字加标注,比如下划线.方框.高亮文字背景等,不过是手写风格的!截图给大家感受下 ...
- 集合类List底层数据结构总结
数组: 1. 不安全 ArrayList 2. 安全 Vector链表LinkedList不安全 3.2.1 ArrayList 1. 适合随机查找和遍历,不适合删除和增加 2. 大小不足时,需要将已 ...
- Python3笔记003 - 1.3 python开发工具
第1章 认识python 1.3 python开发工具 IDLE(python自带的python shell) Pycharm(python开发的,选择专业版) 1.进入IDLE模式: C:\Prog ...
- VS2017配置PCL1.9.1 for win10
安装链接 https://www.jianshu.com/p/463f54c91ab7 1.9.1 安装包下载 官网路径: https://github.com/PointCloudLibrary/p ...
- Linux服务器定时脚本
crontab -e 进入编辑模式,同vi编辑器操作. 用户所建立的crontab文件中,每一行都代表一项任务,每行的每个字段代表一项设置,它的格式共分为六个字段,前五段是时间设定段,第六段是要执行的 ...
- nodejs 本地压缩jpg,png图片(nodejs)
使用nodejs实现本地压缩jpg,png图片. 使用到的包 1.images 用于压缩jpg npm install images yarn add images 2.imagemin 用于压缩 ...
- 免费馅饼——移动dp
免费馅饼 题目描述 SERKOI最新推出了一种叫做"免费馅饼"的游戏: 游戏在一个舞台上进行.舞台的宽度为 \(W\) 格,天幕的高度为 \(H\) 格,游戏者占一格. 开始时游戏 ...
- [Mybatis]Mybatis常用操作
Mybatis是目前国内比较流行的ORM框架,特点是可以写灵活的SQL语句,非常适合中小企业的面向数据库开发. 本文总结自己开发过程中常用的Mybatis操作. 一.插入操作 主键自增插入单条 < ...