地址转换过程
地址翻译的过程,即从快表TLB-->页表-->Cache和主存-->外存。
从虚拟地址到物理地址:先找TLB,TLB中没有再找页表。
通过物理地址访问数据:先找Cache,Cache中没有记录,则到主存中找。
首先Cache和TLB都属于硬件部分(都是相联存储器)
Cache引入的目的是作为主存和CPU之间的缓冲区
TLB引入的目的是解决虚拟存储系统中页表机制引入的多次访存问题
Cache中每一行存放的是内存物理地址中数据段和指令的拷贝
TLB每一行存放放的是页表项,页表项又存放了虚拟页号对应的实际内存物理页号
Cache和TLB的地址转换过程在数学上本质上是一样的,都是找到物理块号+块内偏移,若给出一个虚拟地址,先将其划分为低位的页内偏移(偏移位数跟页面大小有关),高位则是虚拟页号,因为相联存储器的分组问题
高位的虚拟页号可能又被划分 标记tag+组号(组号位数跟每组行数有关)。综上,我们将虚拟地址(逻辑地址)进行拆分后得到:虚拟地址 = tag + 组号 + 页内偏移
拿着这个分解的地址去TLB找对应行,比对tag,得到物理块号;拿着物理块号和原本的页内偏移找到对应的真实物理地址,得到物理地址之后,再次进行物理地址划分,方法同划分虚拟地址一样
物理地址 = tag + 组号 + 块内偏移;拿着这个物理地址 去TLB比对,若找到,就不用访存了,直接使用Cache中的指令和数据,若没找到,需要访存该物理地址,更新Cache。
页表 TLB 和 Cache 协同工作
页表、转换后备缓冲区 (TLB) 和缓存是计算机系统内内存管理和缓存的三个重要组件。
1.页表:页表是操作系统维护的数据结构,用于将进程使用的虚拟地址映射到内存中的物理地址。 每个进程都有自己的页表。 当进程访问虚拟地址时,会查阅页表以查找相应的物理地址。 页表确保适当的内存隔离并允许虚拟内存大于物理内存。
2.TLB(Translation Lookaside Buffer):TLB是一个硬件缓存,存储最近访问的虚拟到物理地址的转换。 它位于处理器和主存储器之间。 当进程访问虚拟地址时,首先检查TLB。 如果在TLB中找到翻译(TLB命中),则检索相应的物理地址,从而避免查阅页表。 这加快了内存访问速度。 如果未找到转换(TLB 未命中),则访问页表以获取转换并更新 TLB 以供将来使用。
3.缓存:缓存是一个硬件或软件组件,用于存储经常访问的数据以减少内存访问延迟。 它在不同级别(L1、L2、L3)运行,并且比主存储器更靠近处理器。 缓存利用局部性原理,将最近访问的数据存储在缓存中,并期待将来的访问。 高速缓存可以存储指令和数据,通过减少从较慢的内存访问数据或指令所需的时间来提高整体系统性能。
从它们的关系来看,TLB和Cache共同提高内存访问性能。 当进程访问虚拟地址时,首先检查 TLB 进行转换,如果在 TLB 中找到翻译,则检索相应的物理地址。 然后检查高速缓存中是否有与该物理地址关联的数据, 如果在缓存中找到数据,则可以快速检索。 如果发生 TLB 或高速缓存未命中,则需要分别从页表或主存储器获取必要的转换或数据。
总而言之,页表提供虚拟地址和物理地址之间的映射,TLB 缓存最近访问的虚拟到物理地址转换以加速内存访问,缓存存储频繁访问的数据以减少内存延迟。 它们共同有助于高效的内存管理和提高系统性能。
TLB与Cache的区别
TLB,全称Translation Lookaside Buffer,即旁路转换缓冲或地址转换后备缓冲,是计算机系统中用于加速虚拟地址到物理地址转换过程的一个硬件组件。以下是关于TLB的详细解释:
1. 基本概念
TLB是一个高速缓存,其访问速度远快于主存。
TLB中存放的是页表文件的副本,即虚拟地址到物理地址的转换表。
TLB的主要目标是减少地址转换的开销,提高程序的执行效率。
2. 工作原理
当CPU访问虚拟地址时,TLB首先检查是否存在对应的物理地址。
如果TLB中存在该虚拟地址对应的物理地址(即“命中”),则TLB直接返回该物理地址。
如果TLB中不存在该虚拟地址对应的物理地址(即“不命中”),则TLB发出一个内存访问请求,从主存中获取对应的物理地址。
当主存返回物理地址后,将该虚拟地址和物理地址的映射关系添加到TLB中,以便下次访问时能够直接命中。
3. TLB的内部组成
在X86体系的CPU中,TLB通常包括多组缓存,如缓存一般页表的指令页表缓存(Instruction-TLB)和数据页表缓存(Data-TLB),以及缓存大尺寸页表的对应缓存。
TLB的条目数(即页表条目数)是有限的,因此操作系统需要管理TLB的使用,以确保高效的地址转换。
4. TLB的刷新
当进程进行上下文切换时,通常需要重新设置CR3寄存器并刷新TLB。
但在某些情况下,如使用相同页表的进程切换或普通进程切换到内核线程时,可以避免刷新TLB。
5. TLB与Cache的区别
TLB和Cache都是高速缓存,但TLB缓存的是页表数据,而Cache缓存的是实际数据。
TLB的访问速度对于虚拟地址到物理地址的转换至关重要,而Cache的访问速度则对于提高指令和数据的读取速度至关重要。
TLB和Cache共同提高内存访问性能。 当进程访问虚拟地址时,首先检查 TLB 进行转换。 如果在 TLB 中找到翻译,则检索相应的物理地址。 然后,检查高速缓存中是否有与该物理地址关联的数据。 如果在缓存中找到数据,则可以快速检索。 如果发生 TLB 或高速缓存未命中,则需要分别从页表或主存储器获取必要的转换或数据。
TLB加速了从虚拟地址到物理地址的转换,可以很快的得到所需要数据的物理地址,但是如果直接从物理内存中取数也是很慢的。因此可以采用cache来缓存物理内存中的数据。
TLB的作用及工作原理
TLB的作用及工作过程
页表一般都很大,并且存放在内存中,所以处理器引入MMU后,读取指令、数据需要访问两次内存:首先通过查询页表得到物理地址,然后访问该物理地址读取指令、数据。为了减少因为MMU导致的处理器性能下降,引入了TLB,TLB是Translation Lookaside Buffer的简称,可翻译为“地址转换后援缓冲器”,也可简称为“快表”。简单地说,TLB就是页表的Cache,其中存储了当前最可能被访问到的页表项,其内容是部分页表项的一个副本。只有在TLB无法完成地址翻译任务时,才会到内存中查询页表,这样就减少了页表查询导致的处理器性能下降。
TLB中的项由两部分组成:标识和数据。标识中存放的是虚地址的一部分,而数据部分中存放物理页号、存储保护信息以及其他一些辅助信息。虚地址与TLB中项的映射方式有三种:全关联方式、直接映射方式、分组关联方式。OR1200处理器中实现的是直接映射方式,所以本书只对直接映射方式作介绍。直接映射方式是指每一个虚拟地址只能映射到TLB中唯一的一个表项。假设内存页大小是8KB,TLB中有64项,采用直接映射方式时的TLB变换原理如图所示。
因为页大小是8KB,所以虚拟地址的0-12bit作为页内地址偏移。TLB表有64项,所以虚拟地址的13-18bit作为TLB表项的索引。假如虚拟地址的13-18bit是1,那么就会查询TLB的第1项,从中取出标识,与虚拟地址的19-31位作比较,如果相等,表示TLB命中,反之,表示TLB失靶。TLB失靶时,可以由硬件将需要的页表项加载入TLB,也可由软件加载,具体取决于处理器设计,OR1200没有提供硬件加载页表项的功能,只能由软件实现。TLB命中时,此时翻译得到的物理地址就是TLB第1项中的标识(即物理地址13-31位)与虚拟地址0-12bit的结合。在地址翻译的过程中还会结合TLB项中的辅助信息判断是否发生违反安全策略的情况,比如:要修改某一页,但该页是禁止修改的,此时就违反了安全策略,会触发异常。
OR1200中的MMU分为指令MMU、数据MMU,分别简称为IMMU、DMMU。采用的是页式内存管理机制,每一页大小是8KB,没有实现页表管理、页表查询、更新、锁定等功能,都需要软件实现。实际上OR1200的MMU模块主要实现的就是TLB,OR1200中TLB的大小可以配置,默认是64项,采用的是直接映射方式。IMMU中有ITLB,DMMU中有DTLB,但是ITLB、DTLB的加载、更新、失效、替换等功能也都需要软件实现。本章从下一节开始将分别对IMMU、DMMU进行分析。
TLB工作原理
TLB(translation lookaside buffer)快表,旁路快表缓冲,页表缓冲,地址变换高速缓存。
由于页表存放在主存中,因此程序每次访存至少需要两次:一次访存获取物理地址,第二次访存才获得数据。提高访存性能的关键在于依靠页表的访问局部性。当一个转换的虚拟页号被使用时,它可能在不久的将来再次被使用到。
TLB是一种高速缓存,内存管理硬件使用它来改善虚拟地址到物理地址的转换速度。当前所有的个人桌面,笔记本和服务器处理器都使用TLB来进行虚拟地址到物理地址的映射。使用TLB内核可以快速的找到虚拟地址指向物理地址,而不需要请求RAM内存获取虚拟地址到物理地址的映射关系。这与data cache和instruction caches有很大的相似之处。
TLB原理
当cpu要访问一个虚拟地址/线性地址时,CPU会首先根据虚拟地址的高20位(20是x86特定的,不同架构有不同的值)在TLB中查找。如果是表中没有相应的表项,称为TLB miss,需要通过访问慢速RAM中的页表计算出相应的物理地址。同时,物理地址被存放在一个TLB表项中,以后对同一线性地址的访问,直接从TLB表项中获取物理地址即可,称为TLB hit。
想像一下x86_32架构下没有TLB的存在时的情况,对线性地址的访问,首先从PGD中获取PTE(第一次内存访问),在PTE中获取页框地址(第二次内存访问),最后访问物理地址,总共需要3次RAM的访问。如果有TLB存在,并且TLB hit,那么只需要一次RAM访问即可。
TLB表项
TLB内部存放的基本单位是页表条目,对应着RAM中存放的页表条目。页表条目的大小固定不变的,所以TLB容量越大,所能存放的页表条目越多,TLB hit的几率也越大。但是TLB容量毕竟是有限的,因此RAM页表和TLB页表条目无法做到一一对应。因此CPU收到一个线性地址,那么必须快速做两个判断:
- 所需的也表示否已经缓存在TLB内部(TLB miss或者TLB hit)
- 所需的页表在TLB的哪个条目内
为了尽量减少CPU做出这些判断所需的时间,那么就必须在TLB页表条目和内存页表条目之间的对应方式做足功夫。
TLB表项更新
TLB表项更新可以有TLB硬件自动发起,也可以有软件主动更新
- TLB miss发生后,CPU从RAM获取页表项,会自动更新TLB表项
- TLB中的表项在某些情况下是无效的,比如进程切换,更改内核页表等,此时CPU硬件不知道哪些TLB表项是无效的,只能由软件在这些场景下,刷新TLB。
在linux kernel软件层,提供了丰富的TLB表项刷新方法,但是不同的体系结构提供的硬件接口不同。比如x86_32仅提供了两种硬件接口来刷新TLB表项:
- 向cr3寄存器写入值时,会导致处理器自动刷新非全局页的TLB表项
- 在Pentium Pro以后,invlpg汇编指令用来无效指定线性地址的单个TLB表项无效。
MMU和cache详解(TLB机制)
MMU:memory management unit,称为内存管理单元,或者是存储器管理单元,MMU是硬件设备,它被保存在主存(main memory)的两级也表控制,并且是由协处理器CP15的寄存器1的M位来决定是enabled还是disabled。MMU的主要作用是负责从CPU内核发出的虚拟地址到物理地址的映射,并提供硬件机制的内存访问权限检查。MMU使得每个用户进程拥有自己的地址空间(对于WINCE5.0,每个进程是32MB;而对于WINCE6.0,每个进程的独占的虚拟空间是2GB),并通过内存访问权限的检查保护每个进程所用的内存不被其他进程破坏。
VA和PA
VA:virtual address称为虚拟地址,PA:physical address称为物理地址。CPU通过地址来访问内存中的单元,如果CPU没有MMU,或者有MMU但没有启动,那么CPU内核在取指令或者访问内存时发出的地址(此时必须是物理地址,假如是虚拟地址,那么当前的动作无效)将直接传到CPU芯片的外部地址引脚上,直接被内存芯片(物理内存)接收,这时候的地址就是物理地址。如果CPU启用了MMU(一般是在bootloader中的eboot阶段的进入main()函数的时候启用),CPU内核发出的地址将被MMU截获,这时候从CPU到MMU的地址称为虚拟地址,而MMU将这个VA翻译成为PA发到CPU芯片的外部地址引脚上,也就是将VA映射到PA中。MMU将VA映射到PA是以页(page)为单位的,对于32位的CPU,通常一页为4k,物理内存中的一个物理页面称页为一个页框(page frame)。虚拟地址空间划分成称为页(page)的单位,而相应的物理地址空间也被进行划分,单位是页框(frame),页和页框的大小必须相同。
VA到PA的映射过程
首先将CPU内核发送过来的32位VA[31:0]分成三段,前两段VA[31:20]和VA[19:12]作为两次查表的索引,第三段VA[11:0]作为页内的偏移,查表的步骤如下:
- 从协处理器CP15的寄存器2(TTB寄存器,translation table base register)中取出保存在其中的第一级页表(translation table)的基地址,这个基地址指的是PA,也就是说页表是直接按照这个地址保存在物理内存中的。
- 以TTB中的内容为基地址,以VA[31:20]为索引值在一级页表中查找出一项(2^12=4096项),这个页表项(也称为一个描述符,descriptor)保存着第二级页表(coarse page table)的基地址,这同样是物理地址,也就是说第二级页表也是直接按这个地址存储在物理内存中的。
- 以VA[19:12]为索引值在第二级页表中查出一项(2^8=256),这个表项中就保存着物理页面的基地址,我们知道虚拟内存管理是以页为单位的,一个虚拟内存的页映射到一个物理内存的页框,从这里就可以得到印证,因为查表是以页为单位来查的。
- 有了物理页面的基地址之后,加上VA[11:0]这个偏移量(2^12=4KB)就可以取出相应地址上的数据了。
这个过程称为Translation Table Walk,Walk这个词用得非常形象。从TTB走到一级页表,又走到二级页表,又走到物理页面,一次寻址其实是三次访问物理内存。注意这个“走”的过程完全是硬件做的,每次CPU寻址时MMU就自动完成以上四步,不需要编写指令指示MMU去做,前提是操作系统要维护页表项的正确性,每次分配内存时填写相应的页表项,每次释放内存时清除相应的页表项,在必要的时候分配或释放整个页表。
CPU访问内存时的硬件操作顺序
CPU访问内存时的硬件操作顺序,各步骤在图中有对应的标号:
- CPU内核(图中的ARM)发出VA请求读数据,TLB(translation lookaside buffer)接收到该地址,那为什么是TLB先接收到该地址呢?因为TLB是MMU中的一块高速缓存(也是一种cache,是CPU内核和物理内存之间的cache),它缓存最近查找过的VA对应的页表项,如果TLB里缓存了当前VA的页表项就不必做translation table walk了,否则就去物理内存中读出页表项保存在TLB中,TLB缓存可以减少访问物理内存的次数。
- 页表项中不仅保存着物理页面的基地址,还保存着权限和是否允许cache的标志。MMU首先检查权限位,如果没有访问权限,就引发一个异常给CPU内核。然后检查是否允许cache,如果允许cache就启动cache和CPU内核互操作。
- 如果不允许cache,那直接发出PA从物理内存中读取数据到CPU内核。
- 如果允许cache,则以VA为索引到cache中查找是否缓存了要读取的数据,如果cache中已经缓存了该数据(称为cache hit)则直接返回给CPU内核,如果cache中没有缓存该数据(称为cache miss),则发出PA从物理内存中读取数据并缓存到cache中,同时返回给CPU内核。但是cache并不是只去CPU内核所需要的数据,而是把相邻的数据都去上来缓存,这称为一个cache line。ARM920T的cache line是32个字节,例如CPU内核要读取地址0x30000134~0x3000137的4个字节数据,cache会把地址0x30000120~0x3000137(对齐到32字节地址边界)的32字节都取上来缓存。
- ARM920T支持多种尺寸规格的页表。
ARM体系结构最多使用两级页表来进行转换,页表由一个个条目组成,每个条目存储一段虚拟地址对应的物理地址及访问权限,或者下一级页表的地址。S3C2443最多会用到两级页表,已段(section,大小为1M)的方式进行转换时只用到一级页表,以页(page)的方式进行转换时用到两级页表。而页的大小有3种:大页(large pages,64KB),小页(small pages,4KB)和极小页(tiny pages,1KB)。条目也成为描述符,有段描述符、大页描述符、小页描述符和极小页描述符,分别保存段、大页、小页和极小页的起始物理地址,见下图。
MMU的查表过程,首先从CP15的寄存器TTB找到一级页表的基地址,再把VA[31:20]作为索引值从表中找出一项,这个表项称为一级页描述符(level one descriptor),一个这样的表项占4个字节,那么一级页表需要保存的物理内存的大小是4*4096=16KB,表项可以是一下四种格式之一:
如果描述符的最低位是00,属于fault格式,表示该范围的VA没有映射到PA。
如果描述符的最低位是10,属于section格式,这种格式没有二级页表而是直接映射到物理页面,一个色彩体哦你是1M的大页面,描述符中的VA[31:20]就是这个页面的基地址,基地址的VA[19:0]低位全为0,对齐到1M地址边界,描述符中的domain和AP位控制访问权限,C、B两位控制缓存。
如果描述符的最低两位是01或11,则分别对应两种不同规格的二级页表。根据地址对齐的规律想一下,这两种页表分别是多大?从一级描述符中取出二级页表的基地址,再把VA的一部分作为索引去查二级描述符(level two descriptor),如果是coarse page,则VA[19:12](2^8=256)作为查找二级页表表项的索引;如果是fine page,则VA[19:10](2^10=024)。二级描述符可以是下面四种格式之一:
二级描述符最低两位是00是属于fault格式,其它三种情况分别对应三种不同规格的物理页面,分别是large page(64KB)、small page(4KB)和tiny page(1KB),其中large page和small page有4组AP权限位,每组两个bit,这样可以为每1/4个物理页面分别设置不同的权限,也就是说large page可以为每16KB设置不同的权限,small page可以为每1KB设置不同的权限。
ARM920T提供了多种页表和页面规格,但操作系统只采用其中一种,WINCE采用的就是一级描述符是coarse page table格式(也即由VA[19:12]来作为查找二级页表项的索引),二级描述符是small page格式(也即是VA[11:0]来作为查找物理页面偏移量的索引),每个物理页面大小是4KB。
根据上图我们来分析translation table walk的过程
- VA被划分为三段用于地址映射过程,各段的长度取决于页描述符的格式。
- TTB寄存器中只有[31:14]位有效,低14位全为0,因此一级页表的基地址对齐到16K地址边界,而一级页表的大小也是16K。
- 一级页表的基地址加上VA[31:20]左移两位组成一个物理地址。想一想为什么VA[31:20]要左移两位占据[13:2]的位置,而空出[1:0]两位呢?应该是需要空出最低两位用于表示当前要寻找的一级描述符是coarse page格式,目前不清楚,有待了解。
- 用这个组装的物理地址从物理内存中读取一级页表描述符,这是一个coarse page table格式的描述符。
- 通过domain权限检查后,coarse page table的基地址再加上VA[19:12]左移两位组装成一个物理地址。
- 用这个组装的物理地址从物理内存中读取二级页表描述符,这是一个small page格式的描述符。
- 通过AP权限检查后,small page的基地址再加上VA[11:0]就是最终的物理地址了。
硬件高速缓存和TLB原理
硬件高速缓存的引入是为了缩小CPU和RAM之间的速度不匹配,高速缓存单元插在分页单元和主内存之间,它包含一个硬件高速缓存内存和一个高速缓存控制器。高速缓存内存存放内存中真正的行。高速缓存控制器存放一个表项数组,每个表项对应高速缓存内存中的一个行,如下图:
除了通用硬件高速缓存,80x86处理器还包含了另一个称为转换后援缓冲器或TLB(Translation Lookaside Buffer)的高速缓存用于加快线性地址的转换。TLB是一个小的、虚拟寻址的缓存,其中的每一行都保存着一个由单个页表条目组成的块。
原理
下面通过一个具体的地址翻译示例来说明缓存和TLB的原理(注意:这是简化版的示例,实际过程可能复杂些,不过原理相同),地址翻译基于以下设定:
- 存储器是按字节寻址的
- 存储器访问是针对1字节的字的
- 虚拟地址(线性地址)是14位长的
- 物理地址是12位长的
- 页面大小是64字节
- TLB是四路组相连的,总共有16个条目
- L1 Cache是物理寻址、直接映射的,行大小为4字节,总共有16个组
下面给出小存储系统的一个快照,包括TLB、页表的一部分和L1高速缓存
虚拟地址(TLBI为索引):
TLB:四组,16个条目,四路组相连(PPN为物理页号):
页表:只展示前16个页表条目(PTE)
物理地址(CO为块偏移):
高速缓存:16个组,4字节的块,直接映射
基于以上的设定,来看下当CPU执行一条读地址0x3d4(虚拟地址)处字节的加载指令时发生了什么:
从0x3d4中取出如下几个字段:
- TLBT: 0x03
- TLBI: 0x03
- VPN: 0x0F
- VPO: 0x14
首先,MMU从虚拟地址中取出以上字段,然后检查TLB,看它是否因为前面的某个存储器的引用而缓存了PTE0x0F的一个拷贝。TLB从VPN中抽取出TLB索引(TLBI:0x03)和TLB标记(TLBT:0x03),由上面的TLB表格可知,组0x3的第二个条目中有效匹配,所以命中,将缓存的PPN(0x0D)返回给MMU。
将上述的PPN(0x0D)和来自虚拟地址的VPO(0x14)连接起来,得到物理地址(0x354)。
接下来,MMU发送物理地址给缓存,缓存从物理地址中取出缓存偏移CO(0x0)、缓存组索引CI(0x5)以及缓存标记CT(0x0D)。
从上面高速缓存表格中可得,组0x5中的标记与CT相匹配,所以缓存检测到一个命中,读出在偏移量CO处的数据字节(0x36),并将它返回给MMU,随后MMU将它传递回CPU。
————————————————
原文链接:
1、页表 TLB Cache 的协同工作_cache 和tlb都在哪-CSDN博客