【操作系统 - 5】虚拟内存页面置换算法

操作系统系列

  学习至此,发现很多学了但很久没用的知识,久而久之,慢慢遗忘。等哪天还需要的话,却发现已经忘得差不多了,即使整理了文档(word等),还是得从头再学一遍。读研第一学期,发现很多东西都可以从博客上学习到,也有不少博主呕心沥血整理了挺多有用的博文。于是,本人借此契机,也慢慢开始整理一些博文,不断改进完善中。整理博文(IT)有如下目的:

  • 首要目的:记录“求学生涯”的所学所悟,不断修改,不断更新!(有读者的互动)
  • 其次目的:在这“开源”的时代,整理并分享所学所悟是一种互利的行为!

博文系列:操作系统课程所学相关算法

  • 1.先来先服务FCFS和短作业优先SJF进程调度算法
  • 2.时间片轮转RR进程调度算法
  • 3.预防进程死锁的银行家算法
  • 4.动态分区分配算法
  • 5.虚拟内存页面置换算法
  • 6.磁盘调度算法

6个实验相关代码的下载地址:http://download.csdn.net/detail/houchaoqun_xmu/9865648

-------------------------------

虚拟内存页面置换算法

一、概念介绍和案例解析 - 页面置换算法

  • 最佳(Optimal)置换算法:
  最佳置换算法是由Belady于1966年提出的一种理论上的算法。其所选择的被淘汰页面,将是以后永不使用的,或是在最长(未来)时间内不再被访问的页面。采用最佳置换算法,通常可保证获得最低的缺页率。
  但由于人们目前还无法预知一个进程在内存的若干个页面中,哪一个页面是未来最长时间内不再被访问的,因而该算法是无法实现的,但可以利用该算法去评价其它算法。现举例说明如下。 

  假定系统为某进程分配了三个物理块,并考虑有以下的页面号引用串:

7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1
  进程运行时,先将7,0,1三个页面装入内存。以后,当进程要访问页面2时,将会产生缺页中断。此时OS根据最佳置换算法,将选择页面7予以淘汰。这是因为页面0将作为第5个被访问的页面,页面1是第14个被访问的页面,而页面7则要在第18次页面访问时才需调入。下次访问页面0时,因它已在内存而不必产生缺页中断。当进程访问页面3时,又将引起页面1被淘汰;因为,它在现有的1,2,0三个页面中,将是以后最晚才被访问的。图4-26示出了采用最佳置换算法时的置换图。由图可看出,采用最佳置换算法发生了6次页面置换。
【操作系统 - 5】虚拟内存页面置换算法_第1张图片

  • 先进先出(FIFO)页面置换算法:
  这是最早出现的置换算法。该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。
  该算法实现简单,只需把一个进程已调入内存的页面,按先后次序链接成一个队列,并设置一个指针,称为替换指针,使它总是指向最老的页面。
  但该算法与进程实际运行的规律不相适应,因为在进程中,有些页面经常被访问,比如,含有全局变量、常用函数、例程等的页面,FIFO算法并不能保证这些页面不被淘汰。
  这里,我们仍用上面的例子,但采用FIFO算法进行页面置换(图4-27)。当进程第一次访问页面2时,将把第7页换出,因为它是最先被调入内存的;在第一次访问页面3时,又将把第0页换出,因为它在现有的2,0,1 三个页面中是最老的页。由图4-27 可以看出,利用FIFO算法时进行了12次页面置换,比最佳置换算法正好多一倍。 
【操作系统 - 5】虚拟内存页面置换算法_第2张图片
Belady(抖动)现象:采用FIFO算法时,如果对一个进程未分配它所要求的全部页面,有时就会出现分配的页面数增多,缺页率反而提高的异常现象。
Belady现象的描述:一个进程P要访问M个页,OS分配N个内存页面给进程P;对一个访问序列S,发生缺页次数为PE(S,N)。当N增大时,PE(S, N)时而增大,时而减小。
Belady现象的原因:FIFO算法的置换特征与进程访问内存的动态特征是矛盾的,即被置换的页面并不是进程不会访问的。

  • 最近最久未使用(LRU)置换算法:
LRU(Least Recently Used)置换算法的描述:
  FIFO置换算法性能之所以较差,是因为它所依据的条件是各个页面调入内存的时间,而页面调入的先后并不能反映页面的使用情况。最近最久未使用(LRU)的页面置换算法,是根据页面调入内存后的使用情况进行决策的。由于无法预测各页面将来的使用情况,只能利用“最近的过去”作为“最近的将来”的近似,因此,LRU置换算法是选择最近最久未使用的页面予以淘汰。该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间t,当须淘汰一个页面时,选择现有页面中其t值最大的,即最近最久未使用的页面予以淘汰。 
【操作系统 - 5】虚拟内存页面置换算法_第3张图片
利用LRU算法对上例进行页面置换的结果如上图所示
当进程第一次对页面2进行访问时,由于页面7是最近最久未被访问的,故将它置换出去。
当进程第一次对页面3进行访问时,第1页成为最近最久未使用的页,将它换出。
由图可以看出,前5个时间的图像与最佳置换算法时的相同,但这并非是必然的结果。
因为,最佳置换算法是从“向后看”的观点出发的,即它是依据以后各页的使用情况;
而LRU算法则是“向前看”的,即根据各页以前的使用情况来判断,而页面过去和未来的走向之间并无必然的联系。 

LRU置换算法的硬件支持
  LRU置换算法虽然是一种比较好的算法,但要求系统有较多的支持硬件。
  为了了解一个进程在内存中的各个页面各有多少时间未被进程访问,以及如何快速地知道哪一页是最近最久未使用的页面,须有两类硬件之一的支持:寄存器或栈。

  【寄存器】为了记录某进程在内存中各页的使用情况,须为每个在内存中的页面配置一个移位寄存器,可表示为

R = Rn-1Rn-2Rn-3 … R2R1R0

  当进程访问某物理块时,要将相应寄存器的Rn-1位置成1。此时,定时信号将每隔一定时间(例如100 ms)将寄存器右移一位。如果我们把n位寄存器的数看做是一个整数,那么,具有最小数值的寄存器所对应的页面,就是最近最久未使用的页面

  下图示出了某进程在内存中具有8个页面,为每个内存页面配置一个8位寄存器时的LRU访问情况。这里,把8个内存页面的序号分别定为1~8。由图可以看出,第3个内存页面的R值最小,当发生缺页时,首先将它置换出去。

【操作系统 - 5】虚拟内存页面置换算法_第4张图片

  【栈】可利用一个特殊的栈来保存当前使用的各个页面的页面号。每当进程访问某页面时,便将该页面的页面号从栈中移出,将它压入栈顶。因此,栈顶始终是最新被访问页面的编号,而栈底则是最近最久未使用页面的页面号。假定现有一进程所访问的页面的页面号序列为:
4,7,0,7,1,0,1,2,1,2,6
  随着进程的访问,栈中页面号的变化情况如下图所示。在访问页面6时发生了缺页,此时页面4是最近最久未被访问的页,应将它置换出去。 
【操作系统 - 5】虚拟内存页面置换算法_第5张图片

Linux LRU算法

  最初分配某个页时, 页的寿命为3, 每次页被访问, 其寿命增加3, 直到20为止。当内核的交换进程运行时(kswapd周期运行), 在内存的所有页面寿命减1。如果某个页的寿命为0,则该页作为交换候选页。

二、实验介绍

  • 问题描述:

  设计程序模拟先进先出FIFO、最佳置换OPI和最近最久未使用LRU页面置换算法的工作过程。假设内存中分配给每个进程的最小物理块数为m,在进程运行过程中要访问的页面个数为n,页面访问序列为P1, … ,Pn,分别利用不同的页面置换算法调度进程的页面访问序列,给出页面访问序列的置换过程,计算每种算法缺页次数和缺页率。

  • 程序要求:

1)利用先进先出FIFO、最佳置换OPI和最近最久未使用LRU三种页面置换算法模拟页面访问过程。

2)模拟三种算法的页面置换过程,给出每个页面访问时的内存分配情况。

3)输入:最小物理块数m,页面个数n,页面访问序列P1, …,Pn,算法选择1-FIFO,2-OPI,3-LRU。

4)输出:每种算法的缺页次数和缺页率。


三、程序设计和程序开发

const int MaxNumber=100;
int PageOrder[MaxNumber];  //页面序列
int PageNum,LackNum,MinBlockNum; //页面个数,缺页次数,最小物理块数
int PageDisCount[MaxNumber]; //当前内存距离下一次出现的距离
int LRUtime[MaxNumber];   //存储队列中各个页面最近使用情况
double  LackPageRate;   //缺页率
int LackPageNum;   //缺页数
int VirtualQueue[MaxNumber];   //虚拟队列
页面置换的实现过程如下:
  • 1.变量初始化;
  • 2.接收用户输入最小物理块数m,页面个数n,页面序列P1, … ,Pn,选择算法1-FIFO,2-OPI,3-LRU;
  • 3.根据用户选择的算法进行页面的分配和置换,输出页面置换算法的模拟过程;
  • 4.计算选择算法的缺页次数和缺页率;
  • 5.输出选择算法的缺页次数和缺页率。
FIFO过程:
void FIFO()
{
	cout<<"********* 你选择了FIFO算法:********* "<OPI过程:

void OPI()
{
	cout<<"********* 你选择了OPI算法:********* "<LRU过程:

void LRU()
{
	cout<<"********* 你选择了LRU算法:********* "<四、实验结果分析 
  
  • 实验数据:
3
20
7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1
  • 实验结果:
【操作系统 - 5】虚拟内存页面置换算法_第6张图片【操作系统 - 5】虚拟内存页面置换算法_第7张图片

五、实验源码

// 操作系统_实验五(虚拟内存页面置换算法).cpp : 定义控制台应用程序的入口点。
//

#include 
#include 
#include 
using namespace std;

const int MaxNumber=100;
int PageOrder[MaxNumber];  //页面序列
int PageNum,LackNum,MinBlockNum;  //页面个数,缺页次数,最小物理块数
int PageDisCount[MaxNumber]; //当前内存距离下一次出现的距离
int LRUtime[MaxNumber];   //存储队列中各个页面最近使用情况

double  LackPageRate;   //缺页率
int LackPageNum;   //缺页数
int VirtualQueue[MaxNumber];   //虚拟队列

void input();
void initial();
void FIFO();    //先进先出
void OPI();     //最佳置换
void LRU();    //最近最久未使用LRU页面置换算法
void display();

void input()
{
	ifstream readData;
	readData.open("data.txt");
	readData>>MinBlockNum;
	readData>>PageNum;
	for (int i=0;i>PageOrder[i];
	}

	cout<<"读取数据结果如下:"<>chooseAlgorithm;
		switch(chooseAlgorithm)
		{
		case 1:
			FIFO();
			break;
		case 2:
			OPI();
			break;
		case 3:
			LRU();
			break;
		default:
			cout<<"请输入正确的序号进行选择:"<>isContinue;
	}

	cout<<"***************************结束***************************"<


你可能感兴趣的:(【C++】,【操作系统】,C++,数据结构)