不同进程对应相同的虚拟地址,在 TLB(快表) 是如何区分的?

2023-10-24 09:20

本文主要是介绍不同进程对应相同的虚拟地址,在 TLB(快表) 是如何区分的?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

大家好,我叫徐锦桐,个人博客地址为www.xujintong.com。平时记录一下学习计算机过程中获取的知识,还有日常折腾的经验,欢迎大家访问。

一、前言

从虚拟地址到物理地址需要进行多级的页表转换,64位操作系统一般是3~5级,如果每次都要进行这个页表转换那会带来性能上的消耗。
如果我们将已知的虚拟地址和物理地址映射关系存到一个缓存表中,那么如果再次用到这个映射关系就能直接查表来找到虚拟地址对应的物理地址了,这就是TLB表,也叫快表。

但是会发生一个歧义,就是两个进程有相同的虚拟地址,但是映射到了不同的物理地址,到时候查表的时候就会发生歧义

二、页表查找简述

我们知道MMU是将虚拟地址转换为物理地址,然后其中的映射关系存储到页表中,而页表又是分级的。


64位操作系统一般有3~5级页表,这里我们以4级页表为例,分别是PGD、PUD、PMD、PTE四级页表。在硬件上有一个页表基地址寄存器,它存储PGD页表的首地址,MMU根据这个寄存器从PGB表开始查,最后查到PTE,然后生成最后的物理地址。


这个就是相当于找你家的具体位置一样,先找你的省份,然后是市级…。当下次再找你家的具体位置时,还要这么来一次,这非常的麻烦。但是如果第一次查完之后,把你的信息记录下来,比如说一个名字对应你家的具体位置,下次找的时候直接查表就行了。但是如果遇到同名的咋办,这就遇到了歧义,解决办法下面我再说。

三、TLB本质

TLB本质就是一个告诉缓存。TLB缓存虚拟地址和其映射的物理地址。


TLB根据虚拟地址查找cache,也只能根据虚拟地址查找。硬件存在TLB后,虚拟地址转到到物理地址的过程发生了变化。


虚拟地址首先传给TLB确认是否命中cache,如果cache hit就直接可以得到其对应的物理地址。否则,就是一级一级的查页表。
TLB1.webp
(操作系统虽然是64位,64位是非常大的一个数,我们目前一般用不多这么多,所以硬件厂商为了设计简单或节约成本,所以64位CPU寻址范围并不是64位,这里以48位的进行举例)

四、解决TLB中的歧义

在进程切换的时候我们可以将整个TLB失效,切换的进程肯定不会命中TLB,但是会导致性能损失,如果我们进程切换的非常频繁,可能TLB表就没咋用。


怎么尽可能避免flush TLB(这里的flush理解成使无效的意思)呢。如果我们能区分不同的进程TLB表就好了。


Linux操作系统为了区分不同的进程,会给每个进程一个独一无二的进程ID,我们也可以除了通过虚拟地址查表外,通过对比一个ID来区分不同进程的TLB表项。


所以,TLB添加一项ASID(Address Space ID)的匹配。ASID就类似进程ID一样,用来区分不同进程的TLB表项。这样在进程切换的时候就不需要flush TLB。但是仍然需要软件管理和分配ASID。
TLB2.webp

五、管理ASID

ASID和进程ID是不一样的。ASID一般是8或16 bit,所以只能区分256或65536个进程,但是进程ID的取值范围非常的大。我们不能将ASID和进程ID一一对应,我们必须给每个进程分配一个ASID。


Linux管理进程,每个进程会有个tast_struct结构,这里存储的进程的基本信息,我们可以把分配给这个进程的ASID存储到这里。页表基地址寄存器如果有空闲位也可以用来存储ASID。


当进程切换时候,可以将页表基地址和ASID(可以从task_struct获得)共同存储在页表基地址寄存器中。当查找TLB的时候,可以对比虚拟地址和ASID和TLB表中的是否一样来区分不同进程TLB表。 如果TLB miss就需要查页表了,然后再缓存到TLB中,同时缓存当前的ASID。

六、up

内核空间和用户空间是分开的,并且内核空间是所有进程共享的。


内核空间是共享的,那么进程A切换进程B的时候,如果进程B访问的地址位于内核空间,我们完全可以用进程A缓存的TLB表。但是现在因为ASID不一样,所以导致TLB miss。


我们针对内核空间这种全局共享的映射关系称为global映射。针对每个进程的映射成为non-global映射。 所以,我们在最后一级页表引入一个bit(non-global(nG)bit)代表是不是global映射。


当映射关系缓存到TLB的时候,将nG bit也缓存下来。这时候,我们的TLB表中有虚拟地址和物理地址的映射关系、ASID、nG bit。当判断是否命中TLB时,先比较虚拟地址,当找到表中的虚拟地址后,然后再看是不是global映射,如果是,就直接TLB hit,这时候就不用比较ASID了。如果不是global映射,最后还需要比较ASID。
TLB3.webp

参考文章:小林coding–面试官:不同进程对应相同的虚拟地址,在 TLB 是如何区分的?

这篇关于不同进程对应相同的虚拟地址,在 TLB(快表) 是如何区分的?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/274212

相关文章

Python中多线程和多进程的基本用法详解

《Python中多线程和多进程的基本用法详解》这篇文章介绍了Python中多线程和多进程的相关知识,包括并发编程的优势,多线程和多进程的概念、适用场景、示例代码,线程池和进程池的使用,以及如何选择合适... 目录引言一、并发编程的主要优势二、python的多线程(Threading)1. 什么是多线程?2.

Python重命名文件并移动到对应文件夹

《Python重命名文件并移动到对应文件夹》在日常的文件管理和处理过程中,我们可能会遇到需要将文件整理到不同文件夹中的需求,下面我们就来看看如何使用Python实现重命名文件并移动到对应文件夹吧... 目录检查并删除空文件夹1. 基本需求2. 实现代码解析3. 代码解释4. 代码执行结果5. 总结方法补充在

Python如何计算两个不同类型列表的相似度

《Python如何计算两个不同类型列表的相似度》在编程中,经常需要比较两个列表的相似度,尤其是当这两个列表包含不同类型的元素时,下面小编就来讲讲如何使用Python计算两个不同类型列表的相似度吧... 目录摘要引言数字类型相似度欧几里得距离曼哈顿距离字符串类型相似度Levenshtein距离Jaccard相

在不同系统间迁移Python程序的方法与教程

《在不同系统间迁移Python程序的方法与教程》本文介绍了几种将Windows上编写的Python程序迁移到Linux服务器上的方法,包括使用虚拟环境和依赖冻结、容器化技术(如Docker)、使用An... 目录使用虚拟环境和依赖冻结1. 创建虚拟环境2. 冻结依赖使用容器化技术(如 docker)1. 创

关于Spring @Bean 相同加载顺序不同结果不同的问题记录

《关于Spring@Bean相同加载顺序不同结果不同的问题记录》本文主要探讨了在Spring5.1.3.RELEASE版本下,当有两个全注解类定义相同类型的Bean时,由于加载顺序不同,最终生成的... 目录问题说明测试输出1测试输出2@Bean注解的BeanDefiChina编程nition加入时机总结问题说明

linux进程D状态的解决思路分享

《linux进程D状态的解决思路分享》在Linux系统中,进程在内核模式下等待I/O完成时会进入不间断睡眠状态(D状态),这种状态下,进程无法通过普通方式被杀死,本文通过实验模拟了这种状态,并分析了如... 目录1. 问题描述2. 问题分析3. 实验模拟3.1 使用losetup创建一个卷作为pv的磁盘3.

C#比较两个List集合内容是否相同的几种方法

《C#比较两个List集合内容是否相同的几种方法》本文详细介绍了在C#中比较两个List集合内容是否相同的方法,包括非自定义类和自定义类的元素比较,对于非自定义类,可以使用SequenceEqual、... 目录 一、非自定义类的元素比较1. 使用 SequenceEqual 方法(顺序和内容都相等)2.

java中不同版本JSONObject区别小结

《java中不同版本JSONObject区别小结》本文主要介绍了java中不同版本JSONObject区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录1. FastjsON2. Jackson3. Gson4. org.json6. 总结在Jav

Python中连接不同数据库的方法总结

《Python中连接不同数据库的方法总结》在数据驱动的现代应用开发中,Python凭借其丰富的库和强大的生态系统,成为连接各种数据库的理想编程语言,下面我们就来看看如何使用Python实现连接常用的几... 目录一、连接mysql数据库二、连接PostgreSQL数据库三、连接SQLite数据库四、连接Mo

Linux环境变量&&进程地址空间详解

《Linux环境变量&&进程地址空间详解》本文介绍了Linux环境变量、命令行参数、进程地址空间以及Linux内核进程调度队列的相关知识,环境变量是系统运行环境的参数,命令行参数用于传递给程序的参数,... 目录一、初步认识环境变量1.1常见的环境变量1.2环境变量的基本概念二、命令行参数2.1通过命令编程