实验四:页面置换算法

1 实验简介

本实验要求实现多种页面替换算法,然后利用随机产生的引用串测试其性能。

2 实验原理

2.1 页面替换算法

我们做如下假设:
• 虚拟内存页面总数为P,标号从謰到P−1
• 引用串RS(reference string)是一个整数序列,整数的取值范围为0到P−1。RS中的每个元素p表示对页面p的一次引用
• 物理内存由F帧组成,标号从0到F−1。我们引入一个数组M|F|,数组元素M[f]中包含数字p,它表示帧f中包含页面p
页面替换算法顺次读取RS中的每个元素。对于RS中的元素值p,算法搜索数组M[F],判断是否存在某个f,使得M[f]==p。如果未发现,则表示页面缺失。这时,算法必须根据其特定的替换规则,选择一帧M[i],用页面p替换其中的内容,即令M[i]=p。
下面讨论各种替换算法所需要的不同数据结构:
• 最佳替换算法和随机替换算法不需要其它的数据结构。对于最佳替换算法,通过搜索RS即足以确定应被替换的页面;对于随机替换算法,产生一个取值范围在0和F-1之间的随机数,该随机数即可表示应被替换的页面。
• FIFO需要一个指向最老页面的指针(数组索引)。每当该页面被替换的时候,把该指针加1(模F)即可。
• LRU算法则需要一个尺寸为F的数组,该数组用来实现排队功能:每次处理一个新的页面引用时,则把该页放置在队列的末尾。这样,每当需要淘汰一个页面时,从队首取到的即最长时间未被用到的页面。
• Clock算法(也叫second−chance算法)和FIFO算法一样,需要一个指针。此外,它还需要一个数组,用来记录每一帧的使用情况。

2.2引用串的生成算法

引用串可用如下算法产生:

  1. 确定虚拟内存的尺寸P,工作面的起始位置p,工作面中包含的页数e,工作面移动率m,以及一个范围在0和1之间的值t
  2. 生成m个取值范围在p和p+e间的随机数,并记录到引用串中
  3. 生成一个随机数r,0≤ r ≤1
  4. 如果r < t,则为p生成一个新值,否则p=(p+1)mod P
  5. 如果想继续加大引用串的长度,请返回第2步,否则结束

3 实验结果

  1. 物理内存F=5,页面总数P=20,起始位置p=1,e=16,m=4,t=0.64
    在这里插入图片描述
  2. 物理内存F=5,页面总数P=50,起始位置p=1,e=16,m=4,t=0.64
    在这里插入图片描述

4 性能评测

  • 使用同一物理内存和引用串,缺页中断次数可以代表缺页率来表明各个算法的效率。

4.1 测试结果

a. F=3

测试一:F=3,RS[12] = { 10,5,2,8,5,8,9,9,7,9,4,3 };
在这里插入图片描述
测试二:F=3,RS[12] = { 8,4,2,7,8,9,9,9,7,9,4,3 };
在这里插入图片描述
测试三:F=3,RS[12] = { 8,10,6,7,8,3,8,9,7,9,4,9 };
在这里插入图片描述
测试四:F=3, RS[12] = { 3,10,4,7,6,3,8,9,7,8,4,9 };
在这里插入图片描述
测试五:F=3,RS[12] = { 3,10,4,5,5,3,6,9,7,8,9,9 };
在这里插入图片描述

F=3最优随机FIFOLRUClock
158557
238558
349668
458788
559668
平均数4.48.45.867.8

b. F=5

测试一:F=5,RS[12] = { 10,5,2,8,5,8,9,9,7,9,4,3 };
在这里插入图片描述
测试二:F=5,RS[12] = { 8,4,2,7,8,9,9,9,7,9,4,3 };
在这里插入图片描述
测试三:F=5,RS[12] = { 8,10,6,7,8,3,8,9,7,9,4,9 };
在这里插入图片描述
测试四:F=5,RS[12] = { 3,10,4,7,6,3,8,9,7,8,4,9 };
在这里插入图片描述
测试五:F=5,RS[12] = { 3,10,4,5,5,3,6,9,7,8,9,9 };
在这里插入图片描述

F=3最优随机FIFOLRUClock
137443
215211
327324
428234
538435
平均数2.27.03.02.43.4

F=5 最优 随机 FIFO LRU Clock

4.2 问题

  1. FIFO算法是否比随机替换算法优越?LRU算法比FIFO 算法优越多少?
    FIFO算法比随机替换算法优越一些;LRU算法比FIFO算法的效率高5%~10%,由理论知识可知,页面访问序列具有局部性,而FIFO算法并不符合实际情况。
  2. LRU算法和最优算法有何差距?
    LRU算法是所有算法中效率最接近最优算法的算法,由理论知识可知,最优算法是理想的算法,现实中几乎不可能实现,只能作为一种测评标准,LRU算法是效率较高的可实现置换算法,但其硬件要求较高,如果规模较小,则略显麻烦。
    3.Clock算法和LRU算法有何差距?
    Clock算法和LRU算法从结果来看有些差距,Clock算法是使用软件的方式实现LRU算法中硬件的功能,从而在执行效率上会稍弱一些。

5 总结和感想

这次实验的题目是页面置换算法,属于存储器管理的内容。通过这次实验,我对页面置换算法的了解更为深刻。此次实验涉及到了常见的五种算法,包括OPT、随机置换、FIFO、LRU、Clock算法,每种算法都有各自的优缺点。实验中比较容易的是编写实现引用串的函数,比较困难是如何实现各种算法,需要我们掌握每个算法的流程和原理,通过查阅资料和向同学请教最终完成了这个实验,让我觉得受益匪浅。

附录 源代码

源代码连接:https://github.com/zymmoa/OS-Labs/tree/master/Lab4

// 页面替换算法.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <time.h> 
#include <windows.h> 
double get_random_r()
{
	int x;
	x = rand();
	//printf("x:%d\n", x);
	double r = x / (RAND_MAX + 1.0);
	return r;
}
//确定虚拟内存的尺寸P,工作面的起始位置p,工作面中包含的页数e,工作面移动率m,以及一个范围在0和1之间的值t
void Get_RS(int *RS, int P, int p, int e, int m, float t)
{
	int i = 0, j = 0;
	int real_num = 0;
	while (real_num < P)
	{
		for (i = 0; i < m && real_num < P; i++, real_num++)
		{
			RS[real_num] = rand() % (p + e + 1) + p;
		}
		if (real_num >= P)
		{
			break;
		}
		double r = get_random_r();
		//printf("r:%f\n", r);
		if (r<t)
		{
			p = rand() % P;
		}
		else
		{
			p = (p + 1) % P;
		}
		for (j = 0; j<10; j++)
		{
			Sleep(60);
		}
	}
}
int OPT(int *RS, int R, int *M, int F)
{
	int P = 0;	//缺页中断的次数
	int m, m1;
	int r, r1;
	int flag, flag2;
	int fm, rmax;
	int num = 0;
	for (r = 0; r<R; r++)
	{
		flag = 0;
		for (m = 0; m<num; m++)
		{
			if (M[m] == RS[r])
			{
				flag = 1;
				break;
			}
		}
		if (num <F && flag == 0)
		{
			M[num] = RS[r];
			num++;
			continue;
		}
		if (flag == 0 && num == F)
		{
			P++;
			rmax = 0;
			fm = 0;
			for (m1 = 0; m1 < F; m1++)
			{
				flag2 = 0;
				for (r1 = r; r1 < R; r1++)
				{
					if (RS[r1] == M[m1])
					{
						break;
					}
				}
				if (r1 > rmax)
				{
					rmax = r1;
					fm = m1;
				}
			}
			//printf("fm:%d\n",fm);
			M[fm] = RS[r];
		}
	}
	return P;

}

int Random(int *RS, int R, int *M, int F)
{
	int P = 0;
	int m, r;
	int flag;
	for (r = 0; r<R; r++)
	{
		flag = 0;
		for (m = 0; m<F; m++)
		{
			if (M[m] == RS[r])
			{
				flag = 1;
				break;
			}
		}
		if (!flag)
		{
			P++;
			int Page = rand() % F;
			M[Page] = RS[r];
		}
	}
	return P;

}

int FIFO(int *RS, int R, int *M, int F)
{
	int P = 0;
	int m, r, flag, pos;
	for (m = 0; m<F; m++)
	{
		M[m] = RS[m];
	}
	pos = 0;
	for (r = 0; r<R; r++)
	{
		flag = 0;
		for (m = 0; m<F; m++)
		{
			if (M[m] == RS[r])
			{
				flag = 1;
				break;
			}
		}
		if (!flag)
		{
			P++;
			M[pos] = RS[r];
			pos++;
			pos = pos%F;
		}
	}
	return P;

}

int LRU(int *RS, int R, int *M, int F)
{
	int P = 0;	//缺页中断的次数
	int m, r, i, flag;
	int num = 0;
	int *temp;
	temp = (int *)malloc(sizeof(int) * F);
	for (r = 0; r < R; r++)
	{
		flag = 0;
		for (m = 0; m < num; m++)
		{
			if (RS[r] == M[m])
			{
				flag = 1;
				break;
			}
		}

		if (flag == 1)
		{

			for (i = 0; i < num; i++)
			{
				temp[i] ++;
			}

			temp[m] = 0;

		}

		if (num == F && flag == 0)
		{

			P++;
			int max = -1, max_i;
			for (i = 0; i < F; i++)
			{
				if (temp[i] > max)
				{
					max_i = i;
					max = temp[i];
				}
				temp[i] ++;
			}

			M[max_i] = RS[r];
			temp[max_i] = 0;

		}

		if (num < F && flag == 0)
		{
			for (i = 0; i < num; i++)
			{
				temp[i] ++;
			}

			M[num] = RS[r];
			temp[num] = 0;
			num++;
		}

	}
	return P;
}


int Clock(int *RS, int R, int *M, int F)
{
	int P = 0;	//缺页中断的次数
	int m, r, flag, pos, num;
	int *temp;
	int i;
	temp = (int*)malloc(sizeof(int)*F);
	num = 0;
	for (r = 0; r<R; r++)
	{
		flag = 0;

		for (m = 0; m<num; m++)
		{
			if (M[m] == RS[r])
			{
				flag = 1;
				break;
			}
		}

		if (flag == 0 && num == F)
		{
			P++;
			pos = 0;

			for (i = 0; i < F; i++)
			{

				if (temp[i] == 1)
				{
					temp[i] = 0;
				}
				else
				{
					pos = i;
					break;
				}

			}

			M[pos] = RS[i];
			temp[pos] = 1;

		}
		if (flag == 0 && num < F)
		{
			M[num] = RS[r];
			temp[num] = 1;
			num++;
		}

	}
	return P;
}

int main()
{
	int *M;
	int F = 5;
	M = (int*)malloc(sizeof(int)*F);
	int *RS;
	int P,p,e,m;
	float t;
	P = 20 ;//虚拟内存页面总数
	p = 1 ;
	e = 10 ;
	m = 4 ;
	t = 0.64 ;
	RS = ( int * ) malloc ( sizeof ( int ) * P ) ;

	Get_RS(RS,P,p,e,m,t);
	printf("生成的引用串RS:");
	for( int i = 0 ; i < P ; i ++ )
	{
	printf("%d ",RS[i]);
	}
	printf("\n");
/*	int RS[10] = { 5,2,10,8,5,8,9,9,7,9 };
	int P = 10;*/
	printf("--------------------------\n");
	printf("页面替换次数如下\n");
	printf("最优:%d\n", OPT(RS, P, M, F));
	printf("随机:%d\n", Random(RS, P, M, F));
	printf("FIFO:%d\n", FIFO(RS, P, M, F));
	printf("LRU:%d\n", LRU(RS, P, M, F));
	printf("Clock:%d\n", Clock(RS, P, M, F));
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 JavaScript 编写的记忆游戏(附源代码)   项目:JavaScript 记忆游戏(附源代码) 记忆检查游戏是一个使用 HTML5、CSS 和 JavaScript 开发的简单项目。这个游戏是关于测试你的短期 记忆技能。玩这个游戏 时,一系列图像会出现在一个盒子形状的区域中 。玩家必须找到两个相同的图像并单击它们以使它们消失。 如何运行游戏? 记忆游戏项目仅包含 HTML、CSS 和 JavaScript。谈到此游戏的功能,用户必须单击两个相同的图像才能使它们消失。 点击卡片或按下键盘键,通过 2 乘 2 旋转来重建鸟儿对,并发现隐藏在下面的图像! 如果翻开的牌面相同(一对),您就赢了,并且该对牌将从游戏中消失! 否则,卡片会自动翻面朝下,您需要重新尝试! 该游戏包含大量的 javascript 以确保游戏正常运行。 如何运行该项目? 要运行此游戏,您不需要任何类型的本地服务器,但需要浏览器。我们建议您使用现代浏览器,如 Google Chrome 和 Mozilla Firefox, 以获得更好、更优化的游戏体验。要玩游戏,首先,通过单击 memorygame-index.html 文件在浏览器中打开游戏。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值