TLB的作用及工作原理
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
TLB的作⽤及⼯作原理
TLB的作⽤及⼯作过程
以下内容摘⾃《步步惊芯——软核处理器内部设计分析》⼀书
页表⼀般都很⼤,并且存放在内存中,所以处理器引⼊MMU后,读取指令、数据需要访问两次内存:⾸先通过查询页表得到物理地址,然后访问该物理地址读取指令、数据。
为了减少因为MMU导致的处理器性能下降,引⼊了TLB,TLB是Translation Lookaside Buffer的简称,可翻译为“地址转换后援缓冲器”,也可简称为“快表”。
简单地说,TLB就是页表的Cache,其中存储了当前最可能被访问到的页表项,其内容是部分页表项的⼀个副本。
只有在TLB⽆法完成地址翻译任务时,才会到内存中查询页表,这样就减少了页表查询导致的处理器性能下降。
TLB中的项由两部分组成:标识和数据。
标识中存放的是虚地址的⼀部分,⽽数据部分中存放物理页号、存储保护信息以及其他⼀些辅助信息。
虚地址与TLB中项的映射⽅式有三种:全关联⽅式、直接映射⽅式、分组关联⽅式。
OR1200处理器中实现的是直接映射⽅式,所以本书只对直接映射⽅式作介绍。
直接映射⽅式是指每⼀个虚拟地址只能映射到TLB中唯⼀的⼀个表项。
假设内存页⼤⼩是8KB,TLB中有64项,采⽤直接映射⽅式时的TLB变换原理如图10.4所⽰。
因为页⼤⼩是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收到⼀个线性地址,那么必须快速做两个判断:
1 所需的也表⽰否已经缓存在TLB内部(TLB miss或者TLB hit)
2 所需的页表在TLB的哪个条⽬内
为了尽量减少CPU做出这些判断所需的时间,那么就必须在TLB页表条⽬和内存页表条⽬之间的对应⽅式做⾜功夫
全相连 - full associative
在这种组织⽅式下,TLB cache中的表项和线性地址之间没有任何关系,也就是说,⼀个TLB表项可以和任意线性地址的页表项关联。
这种关联⽅式使得TLB表项空间的利⽤率最⼤。
但是延迟也可能相当的⼤,因为每次CPU请求,TLB硬件都把线性地址和TLB的表项逐⼀⽐较,直到TLB hit或者所有TLB表项⽐较完成。
特别是随着CPU缓存越来越⼤,需要⽐较⼤量的TLB表项,所以这种组织⽅式只适合⼩容量TLB
直接匹配
每⼀个线性地址块都可通过模运算对应到唯⼀的TLB表项,这样只需进⾏⼀次⽐较,降低了TLB内⽐较的延迟。
但是这个⽅式产⽣冲突的⼏率⾮常⾼,导致TLB miss的发⽣,降低了命中率。
⽐如,我们假定TLB cache共包含16个表项,CPU顺序访问以下线性地址块:1, 17 , 1, 33。
当CPU访问地址块1时,1 mod 16 = 1,TLB查看它的第⼀个页表项是否包含指定的线性地址块1,包含则命中,否则从RAM装⼊;然后CPU⽅位地址块17,17 mod 16 = 1,TLB发现它的第⼀个页表项对应的不是线性地址块17,TLB miss发⽣,TLB访问RAM把地址块17的页表项装⼊TLB;CPU接下来访问地址块1,此时⼜发⽣了miss,TLB只好访问RAM重新装⼊地址块1对应的页表项。
因此在某些特定访问模式下,直接匹配的性能差到了极点
组相连 - set-associative
为了解决全相连内部⽐较效率低和直接匹配的冲突,引⼊了组相连。
这种⽅式把所有的TLB表项分成多个组,每个线性地址块对应的不再是⼀个TLB表项,⽽是⼀个TLB表项组。
CPU做地址转换时,⾸先计算线性地址块对应哪个TLB表项组,然后在这个TLB表项组顺序⽐对。
按照组长度,我们可以称之为2路,4路,8路。
经过长期的⼯程实践,发现8路组相连是⼀个性能分界点。
8路组相连的命中率⼏乎和全相连命中率⼏乎⼀样,超过8路,组内对⽐延迟带来的缺点就超过命中率提⾼带来的好处了。
这三种⽅式各有优缺点,组相连是个折衷的选择,适合⼤部分应⽤环境。
当然针对不同的领域,也可以采⽤其他的cache组织形式。
TLB表项更新
TLB表项更新可以有TLB硬件⾃动发起,也可以有软件主动更新
1. TLB miss发⽣后,CPU从RAM获取页表项,会⾃动更新TLB表项
2. TLB中的表项在某些情况下是⽆效的,⽐如进程切换,更改内核页表等,此时CPU硬件不知道哪些TLB表项是⽆效的,只能由软件在这些场景下,刷新TLB。
在linux kernel软件层,提供了丰富的TLB表项刷新⽅法,但是不同的体系结构提供的硬件接⼝不同。
⽐如x86_32仅提供了两种硬件接⼝来刷新TLB表项:
1. 向cr3寄存器写⼊值时,会导致处理器⾃动刷新⾮全局页的TLB表项
2. 在Pentium Pro以后,invlpg汇编指令⽤来⽆效指定线性地址的单个TLB表项⽆效。
MMU和cache详解(TLB机制)
1. MMU
MMU:memory management unit,称为内存管理单元,或者是存储器管理单元,MMU是硬件设备,它被保存在主存(main memory)的两级也表控制,并且是由协处理器CP15的寄存器1的M位来决定是enabled还是disabled。
MMU的主要作⽤是负责从CPU内核发出的虚拟地址到物理地址的映射,并提供硬件机制的内存访问权限检查。
MMU使得每个⽤户进程拥有⾃⼰的地址空间(对于WINCE5.0,每个进程是32MB;⽽对于WINCE6.0,每个进程的独占的虚拟空间是2GB),并通过内存访问权限的检查保护每个进程所⽤的内存不被其他进程破坏。
下⾯是MMU提供的功能和及其特征
2. 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).页和页框的⼤⼩必须相同。
3. 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去做,前提是操作系统要维护页表项的正确性,每次分配内存时填写相应的页表项,每次释放内存时清除相应的页表项,在必要的时候分配或释放整个页表。
4. CPU访问内存时的硬件操作顺序
CPU访问内存时的硬件操作顺序,各步骤在图中有对应的标号:
1 CPU内核(图中的ARM)发出VA请求读数据,TLB(translation lookaside buffer)接收到该地址,那为什么是TLB先接收到该地址呢?因为TLB是MMU中的⼀块⾼速缓存(也是⼀种cache,是CPU内核和物理内存之间的cache),它缓存最近查找过的VA 对应的页表项,如果TLB⾥缓存了当前VA的页表项就不必做translation table walk了,否则就去物理内存中读出页表项保存在TLB中,TLB缓存可以减少访问物理内存的次数。
2 页表项中不仅保存着物理页⾯的基地址,还保存着权限和是否允许cache的标志。
MMU⾸先检查权限位,如果没有访问权限,就引发⼀个异常给CPU内核。
然后检查是否允许cache,如果允许cache就启动cache和CPU内核互操作。
3 如果不允许cache,那直接发出PA从物理内存中读取数据到CPU内核。
4 如果允许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字节都取上来缓存。
5. 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]就是最终的物理地址了。
Linux内核-内存-硬件⾼速缓存和TLB原理
硬件⾼速缓存和TLB原理
基本概念
1. 硬件⾼速缓存的引⼊是为了缩⼩CPU和RAM之间的速度不匹配,⾼速缓存单元插在分页单元和主内存之间,它包含⼀个硬件⾼速缓存
内存和⼀个⾼速缓存控制器。
⾼速缓存内存存放内存中真正的⾏。
⾼速缓存控制器存放⼀个表项数组,每个表项对应⾼速缓存内存中的⼀个⾏,如下图:
2. 除了通⽤硬件⾼速缓存,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中取出如下⼏个字段:
1. TLBT: 0x03
2. TLBI: 0x03
3. VPN: 0x0F
4. 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。
以上只分析命中的情况。