南京邮电大学操作系统——实验三:页面置换算法

实验内容

理解请求分页式虚拟存储管理方案中的页面置换算法,理解缺页中断率的概念并可以进行正确地统计。具体要求如下:

  1. 使用数组存储一组页面请求,页面请求的数量要50个以上,访问的页面号可以用随机数生成(0~20):
  2. 设置为分配给进程的页框数(假定是5),使用LRU算法,模拟完成全部的页面请求,最后输出总共发生了多少次缺页;重新设置页框为10,模拟过程,完成输出,观察页框数量对缺页中断率的影响;
  3. 在相同页框的情况下,使用FIFO算法模拟全部的页面请求,以此来比对FIFO和LRU之间的差别。

实验源码

#include<iostream>
constexpr int PageTableLength = 20;//页表长度
constexpr int TotalFream = 5;//页框长度

//关于随机数生成频率的设置
constexpr int Frame_Locality_Frequence = 90;
constexpr int Frame_Locality_Begin = 5;
constexpr int Frame_Locality_End = 8;
//关于随机数生成频率的设置


struct PageItem
{
	int PageFrame;
	bool IsValid;
	bool IsWritten;
};

//使用Rdrand指令提供的真随机数,该指令是Inter的IA32和AMD64架构特有的,并且需要在Ivy Bridge微架构之后该条指令才加入Inter标准,
//标准的使用用法应当判断架构类型和微架构类型,此处省略
unsigned int GetRand() {
	__asm {
		RdRand eax
	}
}

//提供具有局部性的随机数,特点是返回的随机数中以MostFrequence的频率分布在BeginMostFrame至EndMostFrame中间
//参数需要满足:BeginFrame<BeginMostFrame<EndMostFrame<EndFrame
int Get_RequestFrame(int MostFrequence, int BeginMostFrame, int EndMostFrame, int BeginFrame, int EndFrame) {
	if (GetRand() % 100 < MostFrequence) {
		return GetRand() % (EndMostFrame - BeginMostFrame) + BeginMostFrame;
	}
	else {
		if (GetRand() % 100 < 50) {
			return GetRand() % (BeginMostFrame - BeginFrame) + BeginFrame;
		}
		else {
			return GetRand() % (EndFrame - EndMostFrame) + EndMostFrame;
		}
	}
}


//本次实验采用了空间换时间策略,使用了反向页表

//MMU类模拟地址转换的一部分内容,提供基础的数据结构
class MMU
{
public:
	void Run(int LoopNum,int FrameLocality=0) {
		for (int loop_1 = 0; loop_1 < LoopNum; loop_1++)
		{
			unsigned int ThisLoop_RequestFrame;
			if (FrameLocality) {
				ThisLoop_RequestFrame = Get_RequestFrame(Frame_Locality_Frequence, Frame_Locality_Begin, Frame_Locality_End, 0, PageTableLength);
			}
			else {
				ThisLoop_RequestFrame = GetRand() % PageTableLength;
			}
			if (PageTable[ThisLoop_RequestFrame].IsValid == 0) {
				if (Used_Frame_Num < TotalFream) {
					CallIn_Algorithm(ThisLoop_RequestFrame);
					Used_Frame_Num++;
				}
				else {
					Swap_Algorithm(ThisLoop_RequestFrame);
				}
				Page_Fault++;
			}
			Statistics_Algorithm(ThisLoop_RequestFrame);
		}
	}
	void virtual Swap_Algorithm(int RequestFrame) { ; }
	void virtual Statistics_Algorithm(int RequestFrame) { ; }
	void virtual CallIn_Algorithm(int RequestFrame) {
		Reversed_PageTable[Used_Frame_Num] = RequestFrame;
		PageTable[RequestFrame].IsValid = 1;
		PageTable[RequestFrame].PageFrame = Used_Frame_Num;
	}
	int Page_Fault=0;
	int  Used_Frame_Num=0;
	int Reversed_PageTable[TotalFream];


	PageItem PageTable[PageTableLength];

	MMU() {
		for (int i = 0; i < PageTableLength; i++)
		{
			PageTable[i].IsValid = 0;
			PageTable[i].IsWritten = 0;
			PageTable[i].PageFrame = 0;
		}
	}
};

//MMU类模拟地址转换的一部分内容,提供基础的数据结构

class FIFO:public MMU
{
public:
	int Longest_PageFrame = 0;
	void Swap_Algorithm(int RequestFrame) {
		PageTable[Reversed_PageTable[Longest_PageFrame]].IsValid = 0;
		PageTable[RequestFrame].IsValid = 1;
		PageTable[RequestFrame].PageFrame = Longest_PageFrame;
		Reversed_PageTable[Longest_PageFrame] = RequestFrame;
		Longest_PageFrame = (Longest_PageFrame + 1) % TotalFream;
	}
	
};

class LRU:public MMU
{
public:
	LRU() {
		for (int i = 0; i < PageTableLength; i++)
		{
			Counter_PageNum[i] = 0;
		}
	}
	int Counter_PageNum[PageTableLength];
	void Swap_Algorithm(int RequestFrame) {
		int Min = -1;
		int Min_Index = 0;

		for (int loop_1 = 0; loop_1 < TotalFream; loop_1++)
		{
			if (Counter_PageNum[Reversed_PageTable[loop_1]] > Min)
				Min_Index = loop_1;
		}

		PageTable[RequestFrame].IsValid = 1;
		PageTable[RequestFrame].PageFrame = Min_Index;
		PageTable[Reversed_PageTable[Min_Index]].IsValid = 0;
		Counter_PageNum[RequestFrame] = 0;
		Reversed_PageTable[Min_Index] = RequestFrame;

	}
	void Statistics_Algorithm(int RequestFrame) {
		Counter_PageNum[RequestFrame]++;
	}
};



int main() {
	FIFO _FIFO;
	LRU  _LRU;
	int RequestNum = 10000;
	_FIFO.Run(RequestNum,1);
	printf("FIFO算法运行%d次发生缺页的次数为%d,缺页发生率为:%.2f\n", RequestNum, _FIFO.Page_Fault,_FIFO.Page_Fault/(RequestNum*1.0));
	_LRU.Run(RequestNum,1);
	printf("LRU算法运行%d次发生缺页的次数为%d,缺页发生率为:%.2f\n", RequestNum, _LRU.Page_Fault, _LRU.Page_Fault / (RequestNum*1.0));
}

需要注意的是在LRU算法中并没有使用效率最高的老化算法,原因是在模拟中并不需要考虑LRU算法的实现效率问题。
另外还需要解释一下Get_RequestFrame这个函数,该函数能够生成符合程序局部性原理的随机数集合,实现思路也并不复杂:生成一个(0,100)范围内的随机数来决定当前生成数的范围。其生成的频率分布图大致如下所示(画工太渣,不要介意):
在这里插入图片描述

实验结果

在10000次请求中,实验结果如下所示:

页框数缺页次数缺页率请求次数
327450.2710000
317690.1810000
516400.1610000
58510.0910000
107250.0710000
104580.0510000

对应的结果图片如下所示:

在这里插入图片描述

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

结果分析

从表格可以看到,在程序集中访问率为90%的情况下,能够较好的还原出课堂上的统计结果:

  • 页框数越少,缺页率越严重,两种算法的差距越明显;
  • 当页框数增加到一定程度后,两种算法的差距将可以忽略;

在这里插入图片描述

  • 4
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值