
大家好,我是小林。加速器的最新消息可以到我们平台网站了解一下,也可以咨询客服人员进行详细的解答!https://www.tiandiapp.com/ ![]() 今天上午在群里有位读者面试时,被问到这么一个问题: 表其是 TLB,是 CPU 封装在芯片里的一个东西: 为什么要有 TLB 现在的内存分页都是多级页表的,这样虚拟地址到物理地址的转换就多了几道转换的工序,这显然就降低了这俩地址转换的速度,也就是带来了时间上的开销。 所以,TLB 是专门存放程序比较常访问的页表项的 C,有了 TLB 后,那么 CPU 在寻址时,会先查 TLB,如果没找到,才会继续查常规的页表。 每个进程的虚拟地址范围都是一样的,那不同进程对应相同的虚拟地址,在 TLB 是如何区分的呢? 正文TLB是 的简称。首先,我们知道MMU的作用是把虚拟地址转换成物理地址。虚拟地址和物理地址的映关系存储在页表中,而现在页表又是分级的。64位系统一般都是3~5级。 常见的配置是4级页表,就以4级页表为例说明。分别是PGD、PUD、PMD、PTE四级页表。在硬件上会有一个叫做页表基地址寄存器,它存储PGD页表的首地址。MMU就是根据页表基地址寄存器从PGD页表一路查到PTE,比较终找到物理地址(PTE页表中存储物理地址)。 这就像在地图上显示你的家在哪一样,我为了找到你家的地址,先确定你是,再确定你是某个省,继续往下某个市,比较后找到你家是一样的原理。一级一级找下去。这个过程你也看到了,非常繁琐。 如果首次查到你家的具体位置,我如果记下来你的姓和你家的地址。下次查找时,是不是只需要跟我说你的姓是什么,我就直接能够告诉你地址,而不需要一级一级查找。四级页表查找过程需要四次内存访问。延时可想而知,非常影响性能。 页表查找过程的示例如下图所示。以后有机会详细展开,这里了解下即可。 TLB的本质是什么TLB其就是一块高速缓存。数据缓存地址(虚拟地址或者物理地址)和数据。TLB缓存虚拟地址和其映的物理地址。 TLB根据虚拟地址查找,它没得选,只能根据虚拟地址查找。所以TLB是一个虚拟高速缓存。硬件存在TLB后,虚拟地址到物理地址的转换过程发生了变化。 虚拟地址首先发往TLB确认是否命中,如果 直接可以得到物理地址。否则,一级一级查找页表获取物理地址。 并将虚拟地址和物理地址的映关系缓存到TLB中。既然TLB是虚拟高速缓存(VIVT),是否存在别和歧义问题呢?如果存在,软件和硬件是如何配合解决这些问题呢? TLB的特殊虚拟地址映物理地址的比较小单位是4KB。所以TLB其不需要存储虚拟地址和物理地址的低12位(因为低12位是一样的,根本没必要存储)。 另外,我们如果命中,肯定是一次性从中拿出整个数据。所以虚拟地址不需要域。域是否需要呢?这取决于的组织形式。 如果是全相连高速缓存。那么就不需要。如果使用多路组相连高速缓存,依然需要。下图就是一个四路组相连TLB的例子。 现如今64位CPU寻址范围并没有扩大到64位。64位地址空间很大,现如今还用不到那么大。因此硬件为了设计简单或者解决成本,际虚拟地址位数只使用了一部分。这里以48位地址总线为了例说明。 TLB的别问题我先来思考首个问题,别是否存在。我们知道PIPT的数据不存在别问题。物理地址是仅有的,一个物理地址一定对应一个数据。 但是不同的物理地址可能存储相同的数据。也就是说,物理地址对应数据是一对一关系,反过来是多对一关系。由于TLB的特殊性,存储的是虚拟地址和物理地址的对应关系。 因此,对于单个进程来说,同一时间一个虚拟地址对应一个物理地址,一个物理地址可以被多个虚拟地址映。将PIPT数据类比TLB,我们可以知道TLB不存在别问题。 而VIVT C存在别问题,原因是VA需要转换成PA,PA里面才存储着数据。中间多经传一手,所以引入了些问题。 TLB的歧义问题我们知道不同的进程之间看到的虚拟地址范围是一样的,所以多个进程下,不同进程的相同的虚拟地址可以映不同的物理地址。这就会造成歧义问题。 例如,进程A将地址02000映物理地址04000。进程B将地址02000映物理地址05000。当进程A执行的时候将02000对应04000的映关系缓存到TLB中。当切换B进程的时候,B进程访问02000的数据,会由于命中TLB从物理地址04000取数据。这就造成了歧义。 如何消除这种歧义我们可以借鉴VIVT数据的处理方式,在进程切换时将整个TLB效。切换后的进程都不会命中TLB,但是会导致性能损失。 如何尽可能的避免 TLB首先需要说明的是,这里的理解成使效的意思。我们知道进程切换的时候,为了避免歧义,我们需要主动整个TLB。如果我们能够区分不同的进程的TLB表项就可以避免 TLB。 我们知道L如何区分不同的进程每个进程拥有一个独一二的进程ID。如果TLB在判断是否命中的时候,除了比较以外,再额外比较进程ID该多好呢!这样就可以区分不同进程的TLB表项。进程A和B虽然虚拟地址一样,但是进程ID不一样,自然就不会发生进程B命中进程A的TLB表项。 所以,TLB添加一项ASID(A S ID)的匹配。ASID就类似进程ID一样,用来区分不同进程的TLB表项。这样在进程切换的时候就不需要 TLB。但是仍然需要软件管理和分配ASID。 如何管理ASIDASID和进程ID肯定是不一样的,别混淆二者。进程ID取值范围很大。但是ASID一般是8或16 。所以只能区分256或65536个进程。 我们的例子就以8位ASID说明。所以我们不可能将进程ID和ASID一一对应,我们必须为每个进程分配一个ASID,进程ID和每个进程的ASID一般是不相等的。每创建一个新进程,就为之分配一个新的ASID。当ASID分配完后,所有TLB,重新分配ASID。所以,如果想完全避免 TLB的话,理想情况下,运行的进程数目必须小于等于256。 管理ASID上需要软硬结合。L 为了管理每个进程会有个_结构体,我们可以把分配给当前进程的ASID存储在这里。页表基地址寄存器有空闲位也可以用来存储ASID。 当进程切换时,可以将页表基地址和ASID(可以从_获得)共同存储在页表基地址寄存器中。当查找TLB时,硬件可以对比以及ASID是否相等(对比页表基地址寄存器存储的ASID和TLB表项存储的ASID)。如果都相等,代表TLB 。否则TLB 。当TLB 时,需要多级遍历页表,查找物理地址。然后缓存到TLB中,同时缓存当前的ASID。 更上一层楼我们知道内核空间和用户空间是分开的,并且内核空间是所有进程共享。 既然内核空间是共享的,进程A切换进程B的时候,如果进程B访问的地址位于内核空间,完全可以使用进程A缓存的TLB。但是现在由于ASID不一样,导致TLB 。 我们针对内核空间这种全局共享的映关系称之为映。针对每个进程的映称之为-映。所以,我们在比较后一级页表中引入一个(- (G) )代表是不是映。 当虚拟地址映物理地址关系缓存到TLB时,将G 也存储下来。当判断是否命中TLB时,当比较相等时,再判断是不是映,如果是的话,直接判断TLB ,需比较ASID。当不是映时,比较后比较ASID判断是否TLB 。 什么时候应该 TLB我们再来比较后的总结,什么时候应该 TLB。 当ASID分配完的时候,需要全部TLB。ASID的管理可以使用管理, TLB后整个。当我们建立页表映的时候,就需要虚拟地址对应的TLB表项。首印象可能是修改页表映的时候才需要 TLB,但是际情况是只要建立映就需要 TLB。原因是,建立映时你并不知道之前是否存在映。例如,建立虚拟地址A到物理地址B的映,我们并不知道之前是否存在虚拟地址A到物理地址C的映情况。所以就统一在建立映关系的时候 TLB。 |
狂铁是王者荣耀中一位前期极度强势的边路战士,以高额的爆发伤害
曹操是王者荣耀中一位经典的战士/打野英雄,以其强大的续航能力
想在《英雄联盟手游》中看到自己在本地玩家中的真实战力排名吗?
蒜蓉鱼片是一道非常受欢迎的家常菜,鱼肉滑嫩鲜美,蒜香浓郁扑鼻
佛跳墙土鸡煲是传统佛跳墙的简化版和改良版,以土鸡作为主角和汤