cache mmu
Posted 今天天气眞好
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cache mmu相关的知识,希望对你有一定的参考价值。
文章目录
一、cache
1.为什么要引入cache
引入cache的原因是CPU与主存之间的访问速度差距太大,因为外部主存的低速率读写从而会降低CPU的效率。所以引入高速缓冲存储器cache,cache存储器是一种容量小,速度快的存储器。
2.存储器的结构图
存储器层次结构的主要思想是上一层的存储器作为低一层存储器的高速缓存。因此,寄存器文件就是 L1 的高速缓存,L1 是 L2 的高速缓存,L2 是 L3 的高速缓存,L3 是主存的高速缓存,而主存又是磁盘的高速缓存。
我们又可以看到如下模型:
在多核心的 CPU 里,每个核心都有各自的 L1/L2 Cache,而 L3 Cache 是所有核心共享使用的。
一般的话时分为三级缓存:L1 Cache、L2 Cache、L3 Cache,级别越低的离 CPU 核心越近,访问速度也快,但是存储容量相对就会越小。
3.cache分类
4.I-cache D-cache
cache为什么分为i-cache和d-cache?
1.冯氏结构是指令和数据分离,I和D在一起只有互相干扰
2.从物理上考虑,同时需要数据和指令访问的时候,cache在端口上的设计是很难实现的,所以一般在流水线的主干上,采用分离的i-cache和d-cache
数据缓存:D-cache 可读可写
指令缓存:I-cache 只读
I-Cache和D-cache的结构相似,不同的是D-cache的Tag项包含了一个2比特的脏字段D。
Tag Array
:
PA
:物理地址。用于缓存搜索期间的比较
V
:V位表示表项数据是否有效(能否给cpu用)。
L
:L位表示表项是否被锁定
D
:D位只在D-cache中用到,其作用是在指示当前 D-Cache的数据是否与主缓存一致,一致的话为1,不一致的话为0。
带有数据缓存的方式选择条目的数组还保存行的脏位。一个脏点是必需的
在Cache的架构里面,dirty ram仅仅是D-Cache所拥有,其作用是在指示当前D-Cache的数据是否与主缓存一致
,一致的话dirty为1,不一致的话dirty为0。
Data Array
:条目以行单位在缓存中注册。
LRU
:最近 最少使用,是一种页面置换算法,采用LRU (least-recently-used)算法进行路径选择
5.cache结构
cache是由cache控制器和cache存储器组成:
cache存储器
:它由n个cache行组成
目录存储段
:记录当前行对应主存中的位(tag)
数据项段
:缓存主存内容的。
有效位
(valid bit):标记当前cache行内容是最初从主存中获取到的数据,可以为cpu使用。
脏位
(dirty bit):标记cache行的内容与主存中相应的内容是否一致。
cache控制器
:它根据cpu的读写命令自动完成查找、缓存等工作。
标签域
:用来与目录存储段比较,查找此地址中的内容是否在cache中存在.
组索引域
:当命中时,用来定位命中(hit)在具体的那一cache行上。
数据索引域
:当命中时,用来定位命中在具体中行的哪个字节里。
6.cache与主存映射关系
(1)直接映射
:主存中的多个地址对应于cache的一行。
缺点在于程序同时使用了对应于同一cache行中的两个主存地址,就会产生冲突,这两个数据就会不停的将对方替换出高速缓存,效率较低(快速抖动)。
(2)组相联映射
:
四路组相连:主存中的一个地址可以存放到 4个cache行中的任意一行,一个cache行被替换的概率减少为原来的四分之一。
(3)全相联映射
:提高组相联的程度,使主存中的一个地址能够映射到cache存储器中的任意的cache行(实现复杂)
7.cache读写数据
注意到为局部性原理:
① 时间局部性
:
在某个时间点访问了存储器的特定位置,很可能在一小段时间里,会反复地访问这个位置。
② 空间局部性
:
访问了存储器的特定位置,很可能在不久的将来访问它附近的位置。
这也是引入cache的原因
cache读数据
:
1.cache 中有addr 的数据,直接返回,cache命中。
2.cache 中没有 addr 的数据,从内存里把数据读入cache(读入一行数据cache line)
cache写数据
:
1.写通:CPU最开始写数据时候同时写入cache和内存,cache和内存数据保持一致。但是效率低,因此使用写缓冲器,将数据保存在写缓冲器,后续由写缓冲区去写内存。
写缓冲器
(write buffer):将处理器和cache从较慢的对主存的写操作中脱离出来。
写缓冲器同时还改善了cache的性能,这体现在cache行被替换时。当cache控制器要替换出一个脏的cache行时,它只将该cache行中的数据放入写缓冲器中,而不写入主存。这样就可以快速填充新的cache行数据,处理器就可以继续从cache存储器中读/写数据。
2.写回:新数据只是写入 cache,不会立刻写入内存,cache 和内存中的数据并不一致。新数据写入 cache 时,这一行 cache 被标为“脏”(dirty);当 cache 不够用时,才需要把脏的数据写入内存。
8.cache一致性
如下图,我们知道cpu是多核的,最开始i = 0,当我们的A号核心试图修改i的值时候,执行i++运算,此时运算是发生在A核独自的cache中的,也就是L1/L2cache,共享的L3cache中并没有得到更新(写回的策略),此时当我们的B核去访问i的值时,得到的i值仍然是0。这也就会导致一致性问题的出现。
要想实现缓存一致性,关键是要满足 2 点:
第一点是写传播
,也就是当某个 CPU 核心发生写入操作时,需要把该事件广播通知给其他核心;
第二点是事物的串行化
,这个很重要,只有保证了这个,才能保障我们的数据是真正一致的,我们的程序在各个不同的核心上运行的结果也是一致的;
解决办法就是:基于总线嗅探机制的 MESI
协议
Modified,已修改
Exclusive,独占
Shared,共享
Invalidated,已失效
「已修改」状态就是我们前面提到的脏标记,代表该 Cache Block 上的数据已经被更新过,但是还没有写到内存里。而「已失效」状态,表示的是这个 Cache Block 里的数据已经失效了,不可以读取该状态的数据。
「独占」和「共享」状态都代表 Cache Block 里的数据是干净的,也就是说,这个时候 Cache Block 里的数据和内存里面的数据是一致性的。
「独占」和「共享」的差别在于,独占状态的时候,数据只存储在一个 CPU 核心的 Cache 里,而其他 CPU 核心的 Cache 没有该数据。这个时候,如果要向独占的 Cache 写数据,就可以直接自由地写入,而不需要通知其他 CPU 核心,因为只有你这有这个数据,就不存在缓存一致性的问题了,于是就可以随便操作该数据。
另外,在「独占」状态下的数据,如果有其他核心从内存读取了相同的数据到各自的 Cache ,那么这个时候,独占状态下的数据就会变成共享状态。
「共享」状态代表着相同的数据在多个 CPU 核心的 Cache 里都有,所以当我们要更新 Cache 里面的数据的时候,不能直接修改,而是要先向所有的其他 CPU 核心广播一个请求,要求先把其他核心的 Cache 中对应的 Cache Line 标记为「无效」状态,然后再更新当前 Cache 里面的数据。
我们举个具体的例子来看看这四个状态的转换:
1、当 A 号 CPU 核心从内存读取变量 i 的值,数据被缓存在 A 号 CPU 核心自己的 Cache 里面,此时其他 CPU 核心的 Cache 没有缓存该数据,于是标记 Cache Line 状态为「独占」,此时其 Cache 中的数据与内存是一致的;
2、然后 B 号 CPU 核心也从内存读取了变量 i 的值,此时会发送消息给其他 CPU 核心,由于 A 号 CPU 核心已经缓存了该数据,所以会把数据返回给 B 号 CPU 核心。在这个时候, A 和 B 核心缓存了相同的数据,Cache Line 的状态就会变成「共享」,并且其 Cache 中的数据与内存也是一致的;
3、当 A 号 CPU 核心要修改 Cache 中 i 变量的值,发现数据对应的 Cache Line 的状态是共享状态,则要向所有的其他 CPU 核心广播一个请求,要求先把其他核心的 Cache 中对应的 Cache Line 标记为「无效」状态,然后 A 号 CPU 核心才更新 Cache 里面的数据,同时标记 Cache Line 为「已修改」状态,此时 Cache 中的数据就与内存不一致了。
4、如果 A 号 CPU 核心「继续」修改 Cache 中 i 变量的值,由于此时的 Cache Line 是「已修改」状态,因此不需要给其他 CPU 核心发送消息,直接更新数据即可。
5、如果 A 号 CPU 核心的 Cache 里的 i 变量对应的 Cache Line 要被「替换」,发现 Cache Line 状态是「已修改」状态,就会在替换前先把数据同步到内存。
所以,可以发现当 Cache Line 状态是「已修改」或者「独占」状态时,修改更新其数据不需要发送广播给其他 CPU 核心,这在一定程度上减少了总线带宽压力。
二、mmu
1.mmu的引入
虚拟地址到物理地址的映射(虚存系统通过将大的虚拟地址空间中的地址转换成物理内存空间,而扩充程序可使用的地址空间)
CPU 发出的地址是虚拟地址,它经过 MMU(Memory Manage Unit,内存管理单元)映射到物理地址上。
对于不同进程的同一个虚拟地址,MMU 会把它们映射到不同的物理地址
mmu可以完成地址转换,通过建立页表,把虚拟地址通过页表查找,得到最终的物理地址
。
当需要访问内存中的一个数据,通过这个数据的虚拟地址查找页表,一旦在页表中找到(hit),就通过找到的物理地址寻址到内存中的数据。
如果页表中没有找到(miss),表示页表中没有建立这个数据虚拟地址到物理地址的映射,通过缺页异常,建立这个页表映射项。
但是存在一些经常那个不变的数据,如果每次重复查找,非常浪费时间,因此引入TLB(快表)
,TLB是MMU的一部分,实质上是cache。它所缓存的是最近使用的数据的页表项
(虚拟地址到物理地址的映射)。
他的出现是为了加快访问数据(内存)的速度,减少重复的页表查找。当然它不是必须要有的,但有它,速度就更快。
如果一个需要访问内存中的一个数据,给定这个数据的虚拟地址,查询TLB,发现有(hit),直接得到物理地址,在内存根据物理地址取数据。
如果TLB没有这个虚拟地址(miss),那么就只能费力的通过页表来查找了
页表
(page tables):虚拟地址和物理地址对应表的集合,页表存储在主存中
页表项
(页表条目)(page table entry PTE):虚拟地址和物理地址具体对应记录。页表是由多个页表项PTE组成的数组
TLB
是MMU的一部分,实质上是cache。它所缓存的是最近使用的数据的页表项(虚拟地址到物理地址的映射)。他的出现是为了加快访问数据(内存)的速度,减少重复的页表查找。
2.TLB(快表)
使用TLB内存管理方案:
JTLB
:联合快表:因为这个结构用于转换指令和数据虚拟地址,所以它被称为“联合”TLB。
ITLB
:是一个小的4个条目的、完全关联的TLB,专门用于对指令流执行翻译。如果一个获取地址不能被ITLB转换,就会访问JTLB,在接下来的时钟周期中尝试转换它。如果成功,则将翻译信息复制到ITLB中。然后重新访问ITLB,地址将被成功转换。
DTLB
:与ITLB一样,DTLB由硬件管理,对软件透明。与ITLB不同,在转换Load/Store地址时,JTLB是与DTLB并行访问的。如果有DTLB未命中而JTLB命中,则DTLB可以在该循环中重新加载。然后重新访问DTLB,翻译就成功了
3.TLB结构
1、Tag
:
pagemask
:掩码值的页面。Page Mask通过屏蔽适当的VPN2位来定义页面大小。
VPN2[31:13]
:代表一对TLB页面。Tag比较时,位31:25总是包含在TLB查找比较中。位24:13取决于页面大小,由PageMask定义
G
:全局位,当设置该值时,表示该条目对所有进程和/或线程都是全局的,因此禁止在比较中包含该ASID。
ASID
:地址空间标识符。标识此TLB条目与哪个进程或线程相关联。
作用:可减少上下文切换时TLB刷新的频率,ASID的存在允许多个进程同时存在于TLB和指令缓存中
2、Data
:
PFN0
:物理帧数。定义物理地址的上位。
C0/C1
:缓存能力。并确定是否应页放置在缓存中。
D
:“Dirty”或“Write-enable”位(写允许位)。置1为允许写入,即允许存储到页面。如果该位被清除(0),存储到页面会导致TLB修改异常
V
:有效位。表示TLB表项有效,从而表示虚拟页映射有效。
4.虚拟地址到物理地址的转换
转换步骤:
1、虚拟地址:最低有效位部分(offset)、较高有效位VPN(虚拟页面号)与当前线程的ASID拼接在一起形成一个唯一的页地址与TLB中的标签进行比较(即将来自处理器的虚拟地址VPN与TLB中的虚拟地址VPN进行比较)。
匹配项:
(1)设置TLB条目的偶数和奇数页的全局(G)位是否打开
(2)虚地址的ASID字段与TLB表项的ASID字段是否相同
2、如果有匹配(这个匹配称为TLB命中),就给出高位的物理地址,则TLB输出物理帧号PFN (Physical Frame Number),并与Offset连接,形成物理地址
3、如果tlb没有匹配的项,则处理器将接收一个TLB miss异常,并允许软件从内存中的虚拟/物理地址页表重新填充TLB或者创建适当的页表项,加载进tlb然后再次运行转换过程。
4、找到物理地址之后,再使用这个物理地址去看高速缓存中有没有这个物理地址的缓存,缓存命中的话,高速缓存把这个字节返回给 MMU, MMU 把它传递给处理器。
注意最终转换是否成功取决于V, D域。如果V无效,该entry无效,产生TLB无效异常;如果D指示不可写,而有写操作会产生TLB修改异常
5.管理物理地址和虚拟地址之间的关系
1、内存分段
优点:
1.解决了程序本身不需要关心具体的物理内存
地址的问题
2.可以产生连续的内存空间
缺点:
1.产生内存碎片
2.内存交换空间太大的问题(每一次内存交换,
我们都需要把一大段连续的内存数据写到硬盘
上)
2、内存分页
分页是把整个虚拟和物理内存空间切成一段段固定尺寸的大小
页表实际上存储在 CPU 的内存管理单元 (MMU) 中,于是 CPU 就可以直接通过 MMU,找出要实际要访问的物理内存地址
3、段页式内存
内存分段和内存分页并不是对立的,它们是可以组合起来在同一个系统中使用的,那么组合起来后,通常称为段页式内存管理
段页式内存管理实现的方式:
1.先将程序划分为多个有逻辑意义的段,也就是前面提到的分段机制;
2.接着再把每个段划分为多个页,也就是对分段划分出来的连续空间,再划分固定大小的页;
段页式地址变换中要得到物理地址须经过三次内存访问:
1、第一次访问段表,得到页表起始地址;
2、第二次访问页表,得到物理页号;
3、第三次将物理页号与页内位移组合,得到物理地址。
以上是关于cache mmu的主要内容,如果未能解决你的问题,请参考以下文章
计算机组成原理 王道考研2021 第三章:存储系统 -- 高速缓冲存储器Cache基本概念和原理(程序访问的局部性原理)Cache和主存的映射方式替换算法写策略