模拟页面调度算法——1

14 篇文章 0 订阅
/*******************************************************************/
//请分别用FIFO、OPT算法实现“页面置换”的模拟。模拟程序的要求如下:
//
//输入:页面流文件,其中存储的是一系列页面号,用来模拟待换入的页面。
//
//输出:对于每一个页面流文件,标出所使用的算法,
//并且:每换入一个页面(即:每读入一个页面号),判断是否有页面需要被换出。
//若有,把被换出的页面号输出到屏幕;若没有,则要在输出中用特殊标记说明。
//
//初始条件:采用三个页框,初始时均为空。
//
//测试说明:测试教师将事先准备好一组文件,
//从中为每个程序随机指定一至三个作为输入文件
//(被测试者需从键盘输入指定文件的文件名),并查看程序输出结果。
//测试用例:书上p119页,在本地盘建立一个test.txt文件,内容为例中的页面号
//例如:test文本内容为:
//      4 3 2 1 4 3 5 4 3 2 1 5jjjjjjjjj
//      kkkk
//      jklilkjjj
/******************************************************************/
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "iostream.h"
#include <conio.h> /* getch() */
#include <windows.h>

/* 建议还是用宏函数,这样效率更好点,还写成函数的话,调用会增加额外的栈开销 */
/* WINDEF.H 中也定义了,这里最好用宏判断一下 */
#ifndef max
#define  max(a,b) do\
{\
	return a>b?a:b;\
} while (0);
#endif //max

#define MAX_PAGE 100 //定义最大页数
#define MAX_PAGE_BLOCK 3 //定义最大页面块数

void ShowLog()
{
	cout << "**********************************************" << endl;
	cout << "*  用FIFO、OPT算法实现“页面置换”的模拟     *" << endl; 
	cout << "*  Copyright 2011/11/19, zww0815@qq.com      *" << endl;
	cout << "*       All Rights Reserved                  *" << endl;
	cout << "**********************************************" << endl;
}

/* 先进先出算法(First in first out) */
void FIFO(int page[],int n)
{
	int mem[MAX_PAGE_BLOCK];
	int flag = 0;
	int i,j;
	int d=0;
	int count = 0;//缺页中断计数
	int count_mz = 0;//命中计数
	
	memset(mem,0,MAX_PAGE_BLOCK*sizeof(int));

	cout<<endl<<"# 代表命中"<<"   "<<"!后跟的数字代表被换出的页"<<endl;
	cout<<endl<<"FIFO算法:"<<endl;
	//  mem[2]=page[0];
	//  mem[1]=page[1];
	//  mem[0]=page[2];
	//  cout<<mem[0]<<' '<<mem[1]<<' '<<mem[2]<<endl;

	for(i = 0; i<n; i++)
	{
		flag = 0;
		
		//判断有木有命中,命中标志置1
		for(j = 0; j<MAX_PAGE_BLOCK; j++)
		{
			if(mem[j] == page[i])
			{
				flag = 1;
				count_mz++;
				break;//如果命中第一个,后面就不要去比较了,后面直接唤出就可以了
			}
		}
		
		//flag为1表示命中,输出#
		if(flag)
		{
			//cout<<mem[0]<<' '<<mem[1]<<' '<<mem[2]<<"   #" << " ------->命中" << page[i] <<endl;
			//cout<<mem[0]<<' '<<mem[1]<<' '<<mem[2]<<"   #"<<endl;
			for (int x=0;x<MAX_PAGE_BLOCK;x++)
			{
				cout << mem[x] << " ";
			}
			cout << "   #" <<  "=======>命中" << page[i] <<endl;
		}
		else 
		{
			count++;
			int n=MAX_PAGE_BLOCK-1;
			d = mem[n];
			for (;n>0;n--)
			{
				mem[n] =mem[n-1]; 
			}
			mem[0]=page[i];
			
			for (int x=0;x<MAX_PAGE_BLOCK;x++)
			{
				cout << mem[x] << " ";
			}
			cout << "   !------->缺页中断,唤出" <<d<<endl;			
		}
	}
	cout<<endl<<"共产生缺页中断:"<<count<<"次,"<<"共命中:"<< count_mz <<"次!"<<endl;
};

/* 最优离线算法OPT(OPTimal replacement algorithm) */
void OPT(int page[],int n)
{
	int mem[3]={0,0,0};
	int flag = 0;
	int i,j,s;
	int d=0;
	int count = 0;//缺页中断计数
	int count_mz = 0;//命中计数
	int c0=99;
	int c1=99;
	int c2=99;
	
	cout<<endl<<"# 代表命中"<<"   "<<"!后跟的数字代表被换出的页"<<endl;
	cout<<endl<<"OPT算法:"<<endl;
	mem[2]=page[0];
	mem[1]=page[1];
	mem[0]=page[2];
	cout<<mem[0]<<' '<<mem[1]<<' '<<mem[2]<<endl;
	
	for(i = 3; i<n; i++)
	{
		flag = 0;
		
		//在三个页面中查找
		for(j = 0; j<MAX_PAGE_BLOCK; j++)
		{
			//命中,标志置1,命中计数自加1
			if(mem[j] == page[i])
			{
				flag = 1;
				count_mz++;
				break;//如果命中第一个,后面就不要去比较了,后面直接唤出就可以了
			}
		}

		if(flag)
		{
			int x = 0;
			//cout<<mem[0]<<' '<<mem[1]<<' '<<mem[2]<<"   #"<<endl;
			for (;x<MAX_PAGE_BLOCK;x++)
			{
				cout << mem[x] << " ";
			}
			cout << "   #" <<  "------->" << page[i] <<"进入页面[" << j << "],命中"  <<endl;
		}
		else 
		{
			for(s = i+1; s<n; s++)
			{
				if (mem[0] == page[s]) 
				{
					c0 = s;
				}
				else 
				{
					if(mem[1] == page[s])
					{
						c1 = s;
					}
					else
					{
						if(mem[2] == page[s]) 
						{
							c2 =s;
						}
						else if(c0!=99 && c1!=99 && c2!=99)
						{
							break;
						}
					}
				}
				
			}
			//  cout<<endl<<c0<<c1<<c2<<" ";
			if (c0 >= c1 && c0 >= c2)
			{
				d = mem[0];
				mem[0] = page[i];
				cout<<mem[0]<<' '<<mem[1]<<' '<<mem[2]<<"   !" <<d << "------->" << page[i] << "进入页面[0],唤出" << d <<endl;
			}
			else if (c1 >= c0 && c1 >= c2) 
			{
				d = mem[1];
				mem[1] = page[i];
				cout<<mem[0]<<' '<<mem[1]<<' '<<mem[2]<<"   !" << d << "------->" << page[i] << "进入页面[1],唤出" << d << endl;
			}
			else 
			{
				d = mem[2];
				mem[2] = page[i];
				cout<<mem[0]<<' '<<mem[1]<<' '<<mem[2]<<"   !" << d << "------->" << page[i] << "进入页面[2],唤出" << d << endl;
			}
			count++;
			c0 = c1 = c2 = 99;
			
		}
	}
	cout<<endl<<"共产生缺页中断:"<<count+3<<"次,"<<"共命中:"<< count_mz <<"次!"<<endl;
};

int main()
{
	FILE *fp;
	char pt;
	char strFile[10];
	char str[10];
	int i = 0;
	int j = 0;
	int page[MAX_PAGE];
	int flag = 1;
	
	memset(str,0,sizeof(char)*10);
	memset(page,0,sizeof(int)*50);

	for(i=0; i<50; i++)
	{
		page[i] = -1;
	}

	do 
	{
		ShowLog();
		/* 题目要求读入文件路径,打开时有小错误,改成指定文件名方式 */
		//cout<<"请输入需要读入文件的路径:" << endl;
		
		/* 获取输入的文件名 */
		//gets(strFile);
		strcpy(strFile,"test.txt");
		//cout << "|" << str << sizeof(str) << strlen(str) << "|" << endl;
		
		/* 文件名不能为空 */
		if ( 0 == strlen(strFile))
		{
			cout << "亲,输入不能为空!" << endl;
			Sleep(1000);//暂停1秒
			system("cls");//清屏			
			continue;//下面的就不执行了,继续下一轮循环
		}
		
		/* 可读写方式打开文件,该文件必须存在 */
		fp = fopen(strFile,"r+");

		if(fp==NULL)
		{
			cout << endl<<"找不到该文件" << endl << "<Enter to continue.>" <<endl;
			getch();//暂停,直到接收到任何输入为止
			system("cls");
		}
		else
		{
			cout << "打开文件" << strFile
				<< "成功."  << endl;
			break;//退出本循环
		}
	} while (1);
	

	/* 从文件中读取字符 */
	cout << "读入page[MAX_PAGE]:" << endl;
	/* 这里设置一下最多只读100个数据 */
	while((pt = fgetc(fp)) != EOF && j < MAX_PAGE )
	{
		//i = 0;
		if (pt == '\n') continue;//换行符
		if (pt == ' ') continue;//空格
		if (pt == '	') continue;//Tab
		if(pt>='0' && pt<='9')
		{
			str[0] = pt;
			//i++;
			flag = 1;
			str[1] = '\0';
			page[j] = atoi(str);
			//cout<< " page[" << j << "]=" << page[j++];
			printf(" page[%d]=%d",j,page[j]);
			j++;						
			if ( 0 == j%5) 
			{
				cout << endl;
			}
		}
	}
	
	cout<< endl << "共读入数字数:" << " j= " << j<<endl;
	
	i = 0;
	
	cout <<  "从文件中读出的数字依次为:" << endl;
	while(i < j )
	{
		cout<<" page["<< i << "]= "<<page[i];
		if ( 0 == (++i)%5 )
		{
			cout << endl;
		}		
	}
	
	FIFO(page,j);
	OPT(page,j);

	return 0;
}

一、课程设计目的 通过请求页式管理方式中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请 求页式存储管理中的页面置换算法。 容 二、课程设计内容 模拟实现 OPT(最佳置换)、FIFO 和 LRU 算法,并计算缺页率。 示 三、要求及提示 本题目必须单人完成。 1、首先用随机数生成函数产生一个“指令将要访问的地址序列”,然后将地址序列变换 成相应的页地址流(即页访问序列),再计算不同算法下的命中率。 2、通过随机数产生一个地址序列,共产生 400 条。其中 50%的地址访问是顺序执行的, 另外 50%就是非顺序执行。且地址在前半部地址空间和后半部地址空间均匀分布。具体产 生方法如下: 1) 在前半部地址空间,即[0,199]中随机选一数 m,记录到地址流数组中(这是 非顺序执行); 2) 接着“顺序执行一条指令”,即执行地址为 m+1 的指令,把 m+1 记录下来; 3) 在后半部地址空间,[200,399]中随机选一数 m’,作为新指令地址; 4) 顺序执行一条指令,其地址为 m’+1; 5) 重复步骤 1~4,直到产生 400 个指令地址。 3、将指令地址流变换成页地址(页号)流,简化假设为: 1) 页面大小为 1K(这里 K 只是表示一个单位,不必是 1024B); 2) 用户虚存容量为 40K; 3) 用户内存容量为 4 个页框到 40 个页框; 6 4) 用户虚存中,每 K 存放 10 条指令,所以那 400 条指令访问地址所对应的页地 址(页号)流为:指令访问地址为[0,9]的地址为第 0 页;指令访问地址为[10, 19]的地址为第 1 页;……。按这种方式,把 400 条指令组织进“40 页”,并 将“要访问的页号序列”记录到页地址流数组中。 4、循环运行,使用户内存容量从 4 页框到 40 页框。计算每个内存容量下不同页面置换 算法的命中率。输出结果可以为: 页框数 OPT 缺页率 FIFO 缺页率 LRU 缺页率 [4] OPT:0.5566 FIFO:0.4455 LRU:0.5500 [5] OPT:0.6644 FIFO:0.5544 LRU:0.5588 …… …… …… …… [39] OPT:0.9000 FIFO:0.9000 LRU:0.9000 [40] OPT:1.0000 FIFO:1.0000 LRU:1.0000 注 1:在某一次实验中,可能 FIFO 比 LRU 性能更好,但足够多次的实验表明 LRU 的平均性能比 FIFO 更好。 注 2:计算缺页率时,以页框填满之前和之后的总缺页次数计算。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值