5虚拟内存,页面置换算法

96
龟龟51
2017.10.18 21:43* 字数 5803

8.1虚拟存储的需求

虚拟内存是非连续内存分配的一个延续,非连续内存分配在存储空间内可以连续也可以不连续。虚拟内存是在非连续内存分配基础上,可以把一部分内容放到外存中去,让应用程序有更大的空间使用。

需求背景:增长迅速的存储需求,程序规模的增长速度远远大于存储器容量的增长速度。

理想中的存储器:容量更大、速度更快、价格更便宜的非易失性存储器。

实际中的存储器:


操作系统的存储抽象:


虚拟存储需求:

原因:计算机系统时常出现内存空间不够用

解决办法:

覆盖(overlay):应用程序手动把需要的指令和数据保存在内存中

交换(swapping):操作系统自动把暂时不能执行的程序保存到外存中

虚拟存储:在有限容量的内存中,以页为单位自动装入更多更大的程序

8.2覆盖和交换技术

8.2.1覆盖技术

■ 目标:在较小的可用内存中运行较大的程序

■ 方法:依据程序逻辑结构,将程序划分为若干功能相对独立

的模块;将不会同时执行的模块共享同一块内存区域

  (1)必要部分(常用功能)的代码和数据常驻内存

  (2)可选部分(不常用功能)放在其他程序模块中,只在需要用到时装入内存

  (3)不存在调用关系的模块可相互覆盖,共用同一块内存区域

注:不存在相互调用关系可以分成一个覆盖区


不足:

(1)增加编程困难

            1)需程序员划分功能模块,并确定模块间的覆盖关系

          2)增加了编程的复杂度;

(2)增加执行时间

          1)从外存装入覆盖模块

          2)时间换空间

8.2.2交换技术

目标:增加正在运行或需要运行的程序的内存

实现方法:

可将暂时不能运行的程序放到外存;

换入换出的基本单位(整个进程的地址空间);

换出(swap out):把一个进程的整个地址空间保存到外存;

换入(swap in):将外存中某进程的地址空间读入到内存;


交换技术面临的问题

■ 交换时机:何时需要发生交换?

          只当内存空间不够或有不够的可能时换出

■ 交换区大小

         存放所有用户进程的所有内存映像的拷贝

■ 程序换入时的重定位:换出后再换入时要放 在原处吗?

         采用动态地址映射的方法

覆盖与交换的比较

■ 覆盖

只能发生在没有调用关系的模块间

程序员须给出模块间的逻辑覆盖结构

发生在运行程序的内部模块间

■ 交换

以进程为单位

不需要模块间的逻辑覆盖结构

发生在内存进程间

8.3局部性原理

8.3.1虚拟存储技术的目标:


■ 只把部分程序放到内存中,从而运行比物理内存大的程序

由操作系统自动完成,无需程序员的干涉

■ 实现进程在内存与外存之间的交换,从而获得更多的空闲内存空间

在内存和外存之间只交换进程的部分内容

8.3.2局部性原理(principle of locality)

■ 程序在执行过程中的一个较短时期,所执行的指令地址和指令的操作数地址,分别局限于一定区域

·时间局部性

一条指令的一次执行和下次执行,一个数据的一次访问和下次访问都集中在一个较短时期内

·空间局部性

当前指令和邻近的几条指令,当前访问的数据和邻近的几个数据都集中在一个较小区域内

·分支局部性

一条跳转指令的两次执行,很可能跳到相同的内存位置

■ 局部性原理的意义

从理论上来说,虚拟存储技术是能够实现的,而且可取得满意的效果

8.4虚拟存储概念

基本概念:

■思路

将不常用的部分内存块暂存到外存

原理:

装载程序时

只将当前指令执行需要的部分页面或段装入内存

指令执行中需要的指令或数据不在内存(称为缺页或缺段)时

处理器通知操作系统将相应的页面或段调入内存

操作系统将内存中暂时不用的页面或段保存到外存

■ 实现方式

虚拟页式存储

虚拟段式存储

基本特征


■ 不连续性:

物理内存分配非连续

虚拟地址空间使用非连续

■ 大用户空间

提供给用户的虚拟内存可大于实际的物理内存

■ 部分交换

虚拟存储只对部分虚拟地址空间进行调入和调出

支持技术

■ 硬件: 页式或短时存储中的地址转换机制

■ 操作系统: 管理内存和外存间页面或段的换入和换出

8.5虚拟页存储

■ 在页式存储管理的基础上,增加请求调页和页面置换

■ 思路

1当用户程序要装载到内存运行时,只装入部分页面,就启动程序运行;

2进程在运行中发现有需要的代码或数据不在内存时,则向系统发出缺页异常请求;

3操作系统在处理缺页异常时,将外存中相应的页面调入内存,使得进程能继续运行;

8.5.1虚拟页式存储中的地址转换

执行到相应页表,标志位表示缺页异常,操作系统来接管异常,操作系统要做的事情呢是找页把它写好,然后把这个位变成有效


8.5.2虚拟页式存储中的页表项结构


驻留位:表示该页是否在内存

1表示该页位于内存中,该页表项是有效的,可以使用

0表示该页当前在外存中,访问该页表项将导致缺页异常

修改位:表示在内存中的该页是否被修改过

回收该物理页面时,据此判断是否要把它的内容写回外存

访问位:表示该页面是否被访问过(读或写)

用于页面置换算法

保护位:表示该页的允许访问方式

只读、可读写、可执行等



8.6缺页异常

8.6.1缺页异常(缺页中断)的处理流程


(1)在内存中有空闲物理页面时,分配一物理页帧f,转第E步;

(2)依据页面置换算法选择将被替换的物理页帧f,对应逻辑页q;

(3)如q被修改过,则把它写回外存;

(4)修改q的页表项中驻留位置为0;

(5)将需要访问的页p装入到物理页面f;

(6)修改p的页表项驻留位为1,物理页帧号为f;

(7)重新执行产生缺页的指令

8.6.2虚拟页式存储中的外存管理

在何处保存未被映射的页?

1应能方便地找到在外存中的页面内容

2交换空间(磁盘或者文件)

采用特殊格式存储未被映射的页面

注:可以用一个文件来存这些未被映射的页

虚拟页式存储中的外存选择

1代码段:可执行二进制文件(代码指向相应的可执行文件)

2动态加载的共享库程序段:动态调用的库文件(共享库也有相应的目标文件,所以上两项不改)

3其它段:交换空间(数据段,堆栈)

虚拟页式存储管理的性能

有效存储访问时间(effective memory access time EAT)

EAT =访存时间* (1-p) +缺页异常处理时间*缺页率p


9.1页面置换算法的概念

9.1.1置换算法的功能和目标

功能:当出现缺页异常,需调入新页面而内存已满时,置换算法选择被置换的物理页面;

设计目标:1尽可能减少页面的调入调出次数;2把未来不再访问或短期内不访问的页面调出

页面锁定(frame locking)(有些页面必须在内存里面)

1描述必须常驻内存的逻辑页面

2操作系统的关键部分

3要求响应速度的代码和数据

4页表中的锁定标志位(lock bit)

9.1.2置换算法的评价方法


9.1.3页面置换算法分类

■ 局部页面置换算法

置换页面的选择范围仅限于当前进程占用的物理页面内

最优算法、先进先出算法、最近最久未使用算法

时钟算法、最不常用算法

■ 全局页面置换算法

置换页面的选择范围是所有可换出的物理页面

工作集算法、缺页率算法

9.2页面置换算法总结

9.2.1最优页面置换算法(OPT, optimal)

基本思路:置换在未来最长时间不访问的页面

算法实现:

1缺页时,计算内存中每个逻辑页面的下一次访问时间

2选择未来最长时间不访问的页面

算法特征

1缺页最少,是理想情况

2实际系统中无法实现

3无法预知每个页面在下次访问前的等待时间

4这个算法可以作为置换算法的性能评价依据

(实际使用:在模拟器上运行某个程序,并记录每一次的页面访问情况,第二遍运行时使用最优算法)


9.2.2先进先出算法(First-In First-Out, FIFO)

基本思路:选择在内存驻留时间最长的页面进行置换

算法实现:

1维护一个记录所有位于内存中的逻辑页面链表

2链表元素按驻留内存的时间排序,链首最长,链尾最短

3出现缺页时,选择链首页面进行置换,新页面加到链尾

算法特征

1实现简单

2性能较差,调出的页面可能是经常访问的

3进程分配物理页面数增加时,缺页并不一定减少(Belady现象)

4很少单独使用


9.2.3最近最久未使用算法(Least Recently Used, LRU)

基本思路:

1选择最长时间没有被引用的页面进行置换

2如某些页面长时间未被访问,则它们在将来还可能会长时间不会访问

算法实现:

1缺页时,计算内存中每个逻辑页面的上一次访问时间

2选择上一次使用到当前时间最长的页面

算法特征

最优置换算法的一种近似


LRU算法的可能实现方法

页面链表

·系统维护一个按最近一次访问时间排序的页面链表

链表首节点是最近刚刚使用过的页面

链表尾节点是最久未使用的页面

·访问内存时,找到相应页面,并把它移到链表之首

·缺页时,置换链表尾节点的页面

活动页面栈

·访问页面时,将此页号压入栈顶,并栈内相同的页号抽出

·缺页时,置换栈底的页面

特征

·开销比较大


9.2.4时钟置换算法(Clock)

基本思路:

仅对页面的访问情况进行大致统计

数据结构:

1在页表项中增加访问位,描述页面在过去一段时间的内访问情况

2各页面组织成环形链表

3指针指向最先调入的页面

算法实现:

1访问页面时,在页表项记录页面访问情况

2缺页时,从指针处开始顺序查找未被访问的页面进行置换

算法特征:

时钟算法是LRU和FIFO的折中

时钟置换算法的实现:

■ 页面装入内存时,访问位初始化为0

■ 访问页面(读/写)时,访问位置1

■ 缺页时,从指针当前位置顺序检查环形链表

·访问位为0,则置换该页

·访问位为1,则访问位置0,并指针移动到下一个页面,直到找到可置换的页面


9.2.5改进的Clock算法

基本思路:

减少修改页的缺页处理开销

算法实现:

1在页面中增加修改位,并在访问时进行相应修改

2缺页时,修改页面标志位,以跳过有修改的页面



9.2.6最不常用算法(Least Frequently Used, LFU)

基本思路:

缺页时,置换访问次数最少的页面

算法实现:

1每个页面设置一个访问计数(多位计数)

2访问页面时,访问计数加1

3缺页时,置换计数最小的页面

算法特征:

1算法开销大

2开始时频繁使用,但以后不使用的页面很难置换

解决方法:计数定期右移、衰减

LRU和LFU的区别

·LRU关注多久未访问,时间越短越好

·LFU关注访问次数,次数越多越好


9.2.7Belady现象

现象:采用FIFO等算法时,可能出现分配的物理页面数增加,缺页次数反而升高的异常现象

原因:

1FIFO算法的置换特征与进程访问内存的动态特征矛盾

2被它置换出去的页面并不一定是进程近期不会访问的

哪些置换算法没有Belady现象?

时钟(CLOCK)置换算法,最近最久未使用(LRU)算法,最佳置换算法(OPT)

时钟/改进的时钟页面置换是否有Belady现象?

没有

为什么LRU页面置换算法没有Belady现象?

对于每一时刻,下一步访问的页面我们也是已知的。当N=n+1时,如果下一步会产生缺页,说明下一步会访问的页面不在这n+1个页面中。假设这n+1个页面的集合为W,则当N=n时,内存中的页面是W的一个子集。如果一个元素都不在W中,那么也肯定不存在于W的子集中。反之如果一个元素不存在于W的子集合中,不一定不存在W中。

所以N=n+1时会出现缺页的情况,在N=n时一定缺页。N=n缺页时,N=n+1不一定缺页。所以S一定时,f关于N单调递减。

LRU一般都有栈的特性,一个N+1大小的cache很自然的就包含了大小为N的cache的内容。所以随着cache大小增加,hit rate要么不变,要么提高。

9.2.8LRU、FIFO和Clock的比较

■LRU算法和FIFO本质上都是先进先出的思路

LRU依据页面的最近访问时间排序

LRU需要动态地调整顺序

FIFO依据页面进入内存的时间排序

FIFO依据页面进入内存的时间排序

■LRU可退化成FIFO

如页面进入内存后没有被访问,最近访问时间与进入内存的时间相同

例如:给进程分配3个物理页面,逻辑页面的访问顺序为1、2、3、4、5、6、1、2、3…

■LRU算法性能较好,但系统开销较大

■FIFO算法系统开销较小,会发生Belady现象

■Clock算法是它们的折衷

页面访问时,不动态调整页面在链表中的顺序,仅做标记

缺页时,再把它移动到链表末尾

■对于未被访问的页面,Clock和LRU算法的表现一样好

(注:和fifo也一样了,没有之前参考的信息)

■对于被访问过的页面,Clock算法不能记录准确访问顺序,而LRU算法可以

9.3全局页面置换算法

■ 思路:全局置换算法为进程分配可变数目的物理页面

■ 全局置换算法要解决的问题

1进程在不同阶段的内存需求是变化的

2分配给进程的内存也需要在不同阶段有所变化

3全局置换算法需要确定分配给进程的物理页面数

CPU利用率与并发进程数的关系


■CPU利用率与并发进程数存在相互促进和制约的关系

进程数少时,提高并发进程数,可提高CPU利用率

并发进程导致内存访问增加

并发进程的内存访问会降低了访存的局部性特征

局部性特征的下降会导致缺页率上升和CPU利用率下降

9.3.1工作集

一个进程当前正在使用的逻辑页面集合,可表示为二元函数W(t,D)

·t是当前的执行时刻

D 称为工作集窗口(working-set window),即一个定长的页面访问时间窗口


W(t,D)是指在当前时刻t前的 D时间窗口中的所有访问页面所组成的集合

| W(t,D) |指工作集的大小,即页面数目

W(t,D)={时间窗内所以页面的集合}

工作集的变化


进程开始执行后,随着访问新页面逐步建立较稳定的工作集

当内存访问的局部性区域的位置大致稳定时,工作集大小也大致稳定

局部性区域的位置改变时,工作集快速扩张和收缩过渡到下一个稳定值

常驻集

在当前时刻,进程实际驻留在内存当中的页面集合

工作集与常驻集的关系

工作集是进程在运行过程中固有的性质

常驻集取决于系统分配给进程的物理页面数目和页面置换算法

缺页率与常驻集的关系

常驻集包含工作集时,缺页较少

工作集发生剧烈变动(过渡)时,缺页较多

进程常驻集大小达到一定数目后,缺页率也不会明显下降


9.3.2工作集置换算法

■思路:换出不在工作集中的页面

■窗口大小τ:当前时刻前τ个内存访问的页引用是工作集,τ被称为窗口大小

■实现方法(开销也大)

·访存链表:维护窗口内的访存页面链表

·访存时,换出不在工作集的页面;更新访存链表

·缺页时,换入页面;更新访存链表


超过工作集窗口大小的页面及调出,例如a,时间4的时候已经过了窗口大小所以换出。

9.3.3缺页率置换算法(PFF, Page-Fault-Frequency)

缺页率(两种表示方式)

1缺页次数/内存访问次数

1缺页平均时间间隔的倒数(一般使用这个)

影响缺页率的因素

页面置换算法(可控)

分配给进程的物理页面数目

页面大小

程序的编写方法(可控)

缺页率置换算法(PFF, Page-Fault-Frequency)


通过调节常驻集大小,使每个进程的缺页率保持在一个合理的范围内

·若进程缺页率过高,则增加常驻集以分配更多的物理页面

·若进程缺页率过低,则减少常驻集以减少它的物理页面数

缺页率置换算法的实现

■访存时,设置引用位标志

■缺页时,计算从上次缺页时间tlast到现在tcurrent的时间间隔

如果t_current–t_last>T,则置换所有在[tlast ,  tcurrent ]时间内没有被引用的页(缺页率比较低,把不用的置换出去)

如果t_current–t_last≤T,则增加缺失页到工作集中


9.4抖动和负载控制

9.4.1抖动问题(thrashing)

■抖动

进程物理页面太少,不能包含工作集

造成大量缺页,频繁置换

进程运行速度变慢

■产生抖动的原因

随着驻留内存的进程数目增加,分配给每个进程的物理页面数不断减小,缺页率不断上升

■操作系统需在并发水平和缺页率之间达到一个平衡

选择一个适当的进程数目和进程需要的物理页面数

9.4.2负载控制

通过调节并发进程数(MPL)来进行系统负载控制

平均缺页间隔时间(MTBF) =缺页异常处理时间(PFST):

实际上我们利用第二条竖线,缺页之后,有一个缺页出现的平均间隔和缺页处理的时间,这两个构成一个比例,如果间隔大于处理时间,cpu是能够处理的,就在Ni/o点之前,如果间隔小于处理时间,cpu基本上就满负荷的去做处理还忙不过来了, 对于这种情况就已经到了这条线的底下了


操作系统