CSAPP笔记(九) 虚拟存储器

深入理解计算机系统

虚拟寻址

存储器管理单元(Memory Management Unit, MMU)是CPU上的专用硬件,CPU访存时会经过它,由它读取内存中的页表项,完成地址翻译。

缓存

结构

全相映射 写回

页表

回想SRAM缓存(位于CPU与内存间),cache中条目含有有效位,标记,内容。
把有效位和标记单独取出,再加上内容的地址,组成页表,常驻内存。
页表索引为标记。
页表

缺页

中断处理程序返回后,把导致中断的指令重新执行。

分配页面

在磁盘上创建空间,并把更新页表相应条目,使其指向磁盘的新空间。

管理

每个进程都有独立的页表,切换进程时都重写CPU中的页表地址寄存器。
页表

简化链接

每个进程的存储格式相同。

简化加载

加载器在页表中把0x0804800(32位)开始标记为无效,并指向目标(磁盘中的可执行文件)。
等到CPU取指或访存时调入页。

简化共享

对内核代码,C标准库,都映射到同一内存页。

简化分配

对于连续的虚拟存储页,分配的物理页可以不连续。

保护

权限
SUP:需要内核模式(超级用户)下运行
CPU拿到物理地址的同时也能拿到权限说明,进而可以判断指令是否越权。

地址翻译

地址翻译

结合Cache和VM

结合Cache和VM

TLB

Translation Lookaside Buffer
结合Cache和VM

多级页表

结合Cache和VM

i7

i7

优化

对于Cache来说,查找标记只需PPO。故翻译VPN的同时可在Cache中查找标记。
VM: 页大小为4KB(12位),磁盘
Cache: 块大小为64B(6位),内存
虽然结构上VM位于Cache上游,但仅限于翻译过程的TLB,本质上还是处于下游。

linux

linux
linux
缺页中断产生后,调入物理页前会先遍历链表,
若不虚拟地址不在start和end间,产生段错误。
若在start和end间且越权(prot),触发保护异常。

映射

  • 普通文件
    比如a.out,虚拟地址段先映射到磁盘文件,等CPU调用到这段地址时,从磁盘调入内存,然后更新页表,使虚拟地址映射到内存。
  • 匿名文件
    虚拟地址段映射到内存,第一次调用时,初始化某内存页,然后更新页表,使虚拟地址映射到内存。

共享对象

  • 共享对象: 所有进程都有读写权限
  • 私有对象: 某进程写时要单独复制一份

fork

先复制内核信息,再共享进程信息,等任一个进程写时再分开。

mmap

重点在于选一段虚拟地址映射到物理地址,物理地址可以是内存地址,也可以是文件描述,但仅仅是映射而已,不涉及调页。

显式分配

malloc和free

mmap需给定起始地址,malloc和free默认起始地址为堆地址。
页表
块头4字节,块大小包含块头大小。比如双字(8字节)对齐,存储5字节需要16字节(两个最小块)而不是12字节,因为最小块8字节,只是第1个块有4字节拿去当块头。

碎片

  • 内部碎片:为了对齐,不满1个块大小的也要申请1个块
  • 外部碎片:需要个大块,几个小块加起来满足大小但不连续

隐式空闲链

遍历整个堆去寻找空闲块

显示空闲链

在空闲块中加入前后驱指针

分离空闲链

  • 简单分离存储:按块大小分类再单向连接,每个空闲链中的空闲块大小一致,不合不拆,碎片多。
  • 分离适配:简单分离存储基础上,合且拆,合或拆后的结果放到其他链中。