存储管理-CA

一个访存例子

一个程序片段:
	• array = (int*)malloc(0x1000);
	• for (i=0;i<1024;i++) array[i] = 0;
软件功能:
	• 分配一个1024项的一维整数数组array,并初始化为0; 
硬件过程?
	• 数组地址分配在什么地址?
	• 数组存在什么地方(内存/硬盘)?
	• 什么时候分配?什么时候存?
	• 虚地址和物理地址如何转换?

虚拟存储的基本原理

虚拟存储的作用

  1. 隔离进程编程地址空间;
  2. 虚拟地址空间可大于实际物理地址空间;(swap交换区:内存和硬件交换)
  3. 支持多进程环境下的内存的共享和保护;

虚拟存储原理

  • 由操作系统和CPU紧密配合才能完成
  • 虚拟存储是计算机系统发展过程中有里程碑作用的事件:
    • 多进程环境下统一的编程空间
    • 多进程环境下的共享与保护
    • 支持大于实际物理内存的编程空间
  • 虚实地址分开,建立一种从虚地址空间映射到物理内存的机制:
    • 把两个层次的存储转换为一个层次的存储
    • 物理内存实际上是磁盘的一个Cache

虚实地址转换与页表

在这里插入图片描述

  • 在页的范围内,虚实地址相等;
  • TLB是页表的cache;

多级页表

在这里插入图片描述

TLB

(1)TLB实际上是操作系统中页表的Cache:

  • TLB主要负责完成用户空间到物理空间的转化
  • 一般与Cache访问同时进行
  • TLB内容:虚地址(Cache的Tag),物理地址(Cache的Data),保护位(Cache的状态)//判断访问是否合法

(2)TLB失效处理:

  • TLB失效时需要把相应页表内容从内存取到TLB
  • TLB失效时硬件(如X86的page walker)和软件(如MIPS的特殊例外)来填充TLB

Cache和虚拟存储

在这里插入图片描述

分清两种映射关系

  • TLB是页表的Cache:
    • 负责地址转换,一页管4KB以上数据
    • 页表由操作系统管理,存在系统空间
  • 内存是硬盘的Cache:
    • 负责数据缓存,一字节就是一字节
    • 用户程序的数据在用户空间

MIPS处理器对虚存系统的支持

总技术支持

  • 分段(控制访问权限),段内分页
  • TLB
  • 特殊的控制寄存器
  • 特殊指令
  • 专用的例外入口

MIPS的访问权限

  • User mode用户态:
    • EXL=0 and ERL=0 and KSU=10
  • Supervisor mode管理态:
    • EXL=0 and ERL=0 and KSU=01
  • Kernel mode核心态:
    • EXL=1 or ERL=1 or KSU=00

MIPS存储空间分段情况

32位模式:
在这里插入图片描述

  • 问题一:为什么在内核地址空间中要有一段空间不能用TLB转换以及不能进cache,而且两个虚地址不同的段(kseg0和kseg1)要映射到相同的物理地址呢?
    ①是系统初始化的需要;
    ②因为在MIPS中各自I/O设备都被映射到0~512MB的空间中。在启动计算机的时候,CPU刚开始上电运行,硬件复位信号只对非常必要的一些寄存器进行了初始化,而CPU中的cache、TLB以及各自寄存器都需要由软件进行初始化。(即:CPU刚启动时用于初始化的指令不能存在cache中,其地址也不能用TLB进行转换,否则就会出现先有鸡还是先有蛋的问题:
  • CPU加电、初始化和启动操作系统的整个过程,其中最关键的约定是CPU第一条指令必须有一个固定的入口,并且这个入口的地址不能使用TLB转换,也不能用cache:
    • 在MIPS系统中,CPU初始化时,复位信号reset把程序计数器PC置为0xbfc00000,这个地址属于kseg1段,地址映射方式是直接减去0xa0000000,所以物理地址就是0x1fc00000;
    • 上述地址是一个非缓存地址,一旦CPU发生reset,访存总线第一次送出来一个地址肯定是0x1fc00000,这个地址对应主板的BIOS,CPU从BIOS取指令对cache和控制寄存器等进行初始化后,由于没有使用cache,每条指令的取址和执行都需要上百拍。对cache等初始化后,BIOS程序跳转到另一段地址空间kseg0。
    • 这一段是可以使用cache的,指令和数据都可以进入cache,比非缓存的kseg1快很多。在对内存以及I/O接口进行必要的初始化后,把操作系统代码从硬盘复制到内存中,开始引导操作系统(跳转到操作系统在内存的地址),操作系统就把所有的资源都管理起来了。

MIPS的TLB及相关控制寄存器

32位模式、全相联、32-64项

  • MIPS的TLB格式:
    在这里插入图片描述

    • MASK:12位,用于TLB查找时,控制VPN2的低12位是否参与地址比较(其某位为1:在查找TLB时该为不参与比较),则MIPS的页在4KB-16MB之间可变;
    • VPN2:虚拟页号:每项把两个连续的虚拟页映射为两个物理页;
    • G:全局域:当G等于1时,关闭ASID匹配使得该TLB项适用于所有的地址空间;
    • ASID:地址空间标识符,标记该项地址属于哪个地址空间(只有CPU当前ASID号和该域匹配时,地址查找才命中),ASID域可以理解为:用于区分不同进程表项的编号;
    • PFN:物理页帧号,有效宽度依赖于该CPU支持的物理内存空间的大小;
    • C:表示相应物理页的cache算法;
    • D:dirty脏位,D=1:该页允许写入;OS可利用该位了解该页上是否有写操作发生过;
    • V:有效位,表示相应物理页是否在内存中;
  • MIPS,TLB相关控制寄存器:
    在这里插入图片描述

    • PageMask:Mask⾥⾯值为1的位,书上说的在执⾏ TLB 表项匹配时被忽略(也就相当于 PageMask 寄存器值为 1 的位被看作了⻚内偏移位),⻚内偏移多⼀位,就相当于⻚⼤⼩*2。初始⻚内偏移(12位=4K)⼤⼩,当MASK12位全位1的时候,⻚内偏移成了24位也就是16MB(这也就是FPN为啥要是24位的原因)(页大小四倍递增)
    • PageMask、EntryHi、EntryLo0、EntryLo1,这四个寄存器内容与TLB一样,主要用于读写TLB:
      • 写TLB时,把寄存器的内容写到其中某一项去(其中G位处理方法:把EntyrLo0和EntyrLo1的G位相与后写到TLB);
      • 读TLB时,把TLB某一项的内容读到这些寄存器中(其中G位处理方法:把TLB的G位同时写入到EntyrLo0和EntyrLo1的G位);
    • Index、Random(值随机更新)、Wired,这三个寄存器决定读写TLB的哪个表项;
      • wired:锁定某些TLB项的作用,即指定Random寄存器的值只能在Wired和(TLB最大表项值-1)之间变换;
      • 当软件用Rondom作索引写TLB进行随机替换的时候,0到wired之间的TLB项就不可能被替换(则OS常把一些常用的页表项放到0到wired之间);
    • EPC:例外时的当前PC,便于例外处理完后返回该位置重新执行;(MIPS中存在分支延迟槽,如果发生例外的指令在分支延迟槽中,EPC保存的是发生例外的前一条指令,这样可以返回到分支指令);
    • BadVAddr:引起例外的虚地址;
    • Context:环境上下文,其内容与BadVAddr的内容有些重复,主要是为了加速快TLB异常回填过程中的页表查找速度,其中页表的基地址存储在PTEBase域中,而BadVPN2指向页表内的表项;
  • 虚拟地址转换为物理地址过程为:
    虚拟地址的⾼位(VPN)和当前程序的ASID送给TLB,与TLB中的所有entry表项同时进⾏匹配,匹配过程中如果有如下都满⾜的TLB表项,从中读取PFN,V,D域:
    1.当前程序(进程)的ASID等于TLB表项中的ASID(EntryHi的Gbit置位的话,不⽐较ASID);
    2.虚拟地址的bit63~62与TLB表项的R字段相同;
    3.虚拟地址的相应位域和TLB的VPN2相同,相应位域取决于PageMask寄存器设置的⻚表⼤⼩;
    注意最终转换是否成功取决于V,D域。如果V⽆效,该entry⽆效,产⽣TLB⽆效异常;如果D指示不可写,⽽有写操作会产⽣TLB修改异常。如果没有上述异常,即是TLB命中,命中entry的PFN和虚拟地址低位(1KBpage的话是低10bit,4KBpage的话低12bit)构成最终的物理地址。

与TLB管理有关的指令(核心态下才能执行)

  • MFC0, MTC0:在通用寄存器和控制寄存器之间搬运数据
  • TLBR:以Index寄存器为索引把TLB内容读到PageMask、EntryHi和EntryLo0/1等寄存器
  • TLBP:检查EntryHi中指定的虚页是否在TLB中
  • TLBWR, TLBWI:分别以Random和Index寄存器为索引把Pagemask、EntryHi和EntryLo0/1寄存器的内容写入TLB

处理器访问TLB

处理器访问TLB时,将访存地址和EntryHi中的ASID与TLB的每一项进行匹配:

  • 如果命中,则读出相应的PFN、C、D、V等内容;
  • 如果不命中则发TLB重填(TLB Refill)例外;
  • 如果TLB命中但读出的V位为0,则发出TLB无效(TLB Invalid)例外;
  • 如果是存数操作且TLB命中、有效但读出的D位为0,则发出TLB修改(TLB Modify)例外;

发生TLB例外时,硬件除了把当前PC保存在EPC中用于例外返回,把PC置为例外入口地址,在Cause控制寄存器中记录例外原因,把系统转态置为核心态(置status控制寄存器的EXL位为1)以外,还需要在BadVAddr和Context控制寄存器中保存于TLB例外相关的信息;

TLB例外

(1)发生TLB例外时硬件处理过程:

  • 置BadVaddr, Context, EntryHi:
    //把发生例外的虚地址放到BadVaddr,和Context的PTEBase和BadVPN2域,以及 EntryHi的VPN2域中
  • PC=例外入口地址,当前PC保存在EPC中用于例外返回
    • TLB Refill入口=0x80000000
    • 其它入口=0x80000180
  • 置Status(置EXL位进入核心态), Cause(向其ExCode域中记录例外原因);
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述

(2)TLB例外类型:
1)Refill:TLB中没有对应的项
• 如果查找TLB没有找到一个虚地址匹配(VPN2+ASID/G)
• 例外入口:80000000 (除非exl=1)
在这里插入图片描述
2)TLB invalid:相应物理页不再内存
  • 如果找到一个虚地址匹配项,但其v=0
 • 例外入口:80000180
 • 细分为两种:TLBL for loads, TLBS for stores
3)TLB modify:非法写只读页
 • 如果找到一个虚地址匹配项,其v=1,但D=0且访问为store
 • 例外入口80000180

(3)例外返回:
1)例外处理器在核心态下进行:(用户只能通过(系统调用)进入核心态)
 • 不允许在核心态下执行一条用户指令
 • 不允许在用户态下执行指令核心指令
2)例外返回的两种方式:

  • jr+mtc0: mtc0必须在jr的延迟槽中:
    ①用MTC0指令清除status中的EXL位(权限切换:内核->用户)
    ②用跳转指令(如:jr)转移到EPC指定的地方
  • eret: eret没有延迟槽:
    自动将status寄存器中的转态位改为用户态;

一种虚拟存储实现方式

(1)使得发生例外时,context寄存器指向页表中相应项:
 • 一维线性页表
 • 内存页表每项8个字节,每对页面占用16字节页表(VPN2)
 • 进程切换时操作系统更改context寄存器中pte_base域,使其指向该进程的页表基地址
 (pte_base是进程上下文的一部分)

(2)一维线性页表需要很大的空间,不能全部分配物理内存:
 • 放在kernel mapped的kseg2/kseg3段
 • 需要解决TLB refill重入问题

(3)TLB refill过程:
在这里插入图片描述

  • Pagemask在操作系统初始化时由OS设置(固定页操作系统)
  • Pte_base在进程切换时由OS设置
  • Vpn2和EntryHi在缺页时由CPU设置

(4)TLB refill代码:
在这里插入图片描述在这里插入图片描述

LINUX操作系统的存储管理

Linux/MIPS虚拟地址空间安排

在这里插入图片描述

内存中的页表组织(32位情况)

(1)两级页表,每项4个字节:
 • PFN:物理帧号
 • Flags:V、C、D
 • Exts:软件扩展位,用于维护一些硬件没有实现的功能,例如ref位,modified位

(2)页表存放在kseg0:
 • 页表访问不引起TLB例外(该段不用通过TLB映射的地址空间查询)
 • 页表存储空间在使用到的时候分配

(3)每个进程的页表基地址(PGD表基地址)存放在进程上下文中
 • 进程切换时,把PGD表的基地址写到context的PTEBase中

Linux/MIPS的两层页表

在这里插入图片描述

Linux的tlb重填代码(共18条指令)

在这里插入图片描述

  • 例子:
    在这里插入图片描述在这里插入图片描述

  • 问题:为什么要分两次例外?
    在这里插入图片描述

Linux/MIPS中TLB例外的处理

在这里插入图片描述

  • 例题:
    在这里插入图片描述

展望-不忘初心

(1)为什么访存指令的执行这么复杂?

  • 虚拟化:结构设计复杂一些,用户用起来简单一些;
  • 结构设计:虚实地址转换,支持比实际内存容量更大的访问空间;
  • 用户程序:每个进程都感到整个CPU和内存都是“我的”;

(2)进一步虚拟化:

  • 运行多个OS,让每个OS都感到整个CPU和内存都是”我的“;
  • 两次地址转换:guest VA=>guest PA(host VA)=>host PA,两个不同的TLB以及一个“影子TLB”(guest VA =>host PA);
  • 地址例外时guest OS 和host OS切换;

(3)OS的摩尔定律终结:2020年OS的复杂度也到头了

  • 把CPU最后一点“家当”(核心态功能)也虚拟化掉了

TLB的优化

• 防缓冲区溢出攻击优化
• 硬件性能优化
• 软件性能优化

利用TLB的保护机制防范攻击

  • 利用缓冲区溢出进行攻击的例子
  • 龙芯处理器通过可执行保护防止缓冲区溢出攻击:TLB增加可执行位
    在这里插入图片描述

TLB相关性能数据

  • TLB miss处理的时间可以占到高达40%的运行时间,占40~90%的内核运行时间;
  • SPEC CPU2000大约1/4的程序有比较显著的TLB miss;
     • 早期多数CPU的TLB是全相连的32-128项,如果每项4KB,能映射的空间只有几百KB,越来越难满足现代程序的需求
  • 性能优化方法:
     • 增加TLB覆盖空间大小,降低TLB失效概率
     • 降低TLB失效开销

增加页大小后性能显著提高

  • 增加页大小后,TLB失效明显减少
  • 16KB页时128页有2MB
  • 通过软件配置pagemask可以增加/减少页大小

MIPS-Linux多级页表

(1)查找过程示意图:
在这里插入图片描述

MIPS原Context寄存器设计不再适合多级页表的快速查找(原设计针对一级页表);

(2)加速MIPS-Linux多级页表查找:
1)首先通过软件可配置寄存器来描述具体的页表结构:

  • PGBase:页表基址寄存器(进程上下文一部分,其余寄存器操作系统启动时配置
  • PGSize:描述各级页表的大小
  • PGIndex:描述各级页表索引值在待查询地址中的起始位置
  • PGEntry:描述奇偶页表项之间位置关系,以及页表中软件用的位的宽度
    在这里插入图片描述

2)定义专门的页表访存指令:

  • LDDIR dest, src, #N:将src寄存器中的值作为第N级目录页表的基址,同时根据CP0.BadVaddr中存放的待查询地址以及新增的PGSize、PGINdex配置寄存器信息,访存得到第N+1级页表的基址,写入到dest寄存器中。
  • LDPTE src, #0/#1:将src寄存器中的值作为页表项页表的基址,同时根据CP0.BadVaddr中存放的待查询地址以及新增的PGSize、PGINdex、PGEntry配置寄存器信息,访存得到偶数号/奇数号页表项的内容,将页表中纯粹软件用的位移除后,写入到CP0.EntryLo0/CP0.EntryLo1中。

(3)MIPS-Linux TLB重填代码优化:
在这里插入图片描述

软TLB方案

(1)目的:
主要减少TLB重载入异常处理的时间,提高TLB重载入异常处理的效率。

(2)原理:
通过减少TLB重载入异常处理过程Cache Miss的次数来减少TLB重载入异常处理的时间。

(3)具体流程图:
在这里插入图片描述

(4)软TLB的命中率:
在这里插入图片描述

(5)缓冲区大小对软TLB命中率的影响:
在这里插入图片描述

(6)软TLB对SPEC性能的提高:
在这里插入图片描述

常见处理器的结构参数

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值