页面置换算法代码实现完整版
(完整word版)页面置换算法OPT+FIFO+LRU+clock

#include<iostream>#include<fstream>using namespace std;#define BlockSize 10#define PageSize 100int page[PageSize]; //页面数组存放页面int block[BlockSize]; //物理块数组int result[PageSize][BlockSize]; //存放页面和物理块二维数组int pSize = 0; //用户使用页面数int bSize = 0; //用户使用物理块数int blockFlag[BlockSize]; //用于LRU与最佳置换算法中,辅助判断该换出的页面int noPageCount = 0; //缺页次数//输入数据void inputData(){cout<<endl<<"请输入物理块数(1<=bSize<="<<BlockSize<<')'<<endl;cin>>bSize;cout<<"请输入页面数(1<=pSize<="<<PageSize<<')'<<endl;cin>>pSize;while(bSize<=0||bSize>BlockSize||pSize<=0||pSize>PageSize){//判断用户输入是否在范围内cout<<"输入范围错误,请重新输入:"<<endl;cout<<"请输入物理块数(1<=F<="<<BlockSize<<')';cin>>bSize;cout<<endl<<"请输入页面数(1<=p<="<<PageSize<<')';cin>>pSize;}cout<<"请输入页面走向"<<endl;for(int i = 0;i <pSize;i++)cin>>page[i];}//初始化page数组void initPage(){for(int i = 0;i<PageSize;i++)page[i] = -1;}//初始化block与result数组void initBlockResult(){int i = 0;for(i = 0;i<BlockSize;i++)block[i] = -1;for(i = 0;i < PageSize;i++)for(int j = 0; j < BlockSize;j++)result[i][j] = -1;}//查找物理块中是否存在要调用的页面int Exist(int i){for(int j = 0;j < bSize;j++)if(block[j] == i)return j;return -1;}//显示结果void display(int noPageCount){for(int i =0 ;i < pSize;i++){cout<<" "<<page[i]<<" ";for(int j = 0;j < bSize;j++){if(result[i][j] == -1) break;else cout<<'['<<result[i][j]<<']'<<' ';}cout<<endl;}cout<<"____________________________________"<<endl;cout<<endl<<"缺页次数:"<<noPageCount<<endl;cout<<"缺页率:"<<((double)noPageCount/pSize)*100<<'%'<<endl;cout<<"===================================="<<endl;}//最佳置换算法OPTvoid OPT(){int i = 0,j = 0;int position = 0,noPageCount = 0;int pageFlag = 0,resultFlag = 0; //页面标记(下标)指向下一个页面,结果标记表示结果的行,即result数组的行标for(i = 0;i < BlockSize;i++)blockFlag[i] = 0;while(pageFlag < pSize){if(Exist(page[pageFlag]) != -1) //判断页面是否已经存在resultFlag++;else{if(position < bSize) //判断有无空闲物理块{ //若有则将页面放入空闲块block[position] = page[pageFlag];position++;noPageCount++;for(i = 0;i < position;i++)result[resultFlag][i] = block[i];resultFlag++;}else{for(i = 0;i < bSize;i++){for(j = pageFlag+1;j < pSize;j++){if(block[i] == page[j]){blockFlag[i] = j;break;}}if(j == pSize) blockFlag[i] = 999;}int optPos = 0,max = blockFlag[0];for(int i = 0;i < bSize;i++)if(max < blockFlag[i]){max = blockFlag[i];optPos = i;}block[optPos] = page[pageFlag];noPageCount++;for(i = 0;i < bSize;i++)result[resultFlag][i] = block[i];resultFlag++;}}pageFlag++;}cout<<endl<<"最佳置换算法:"<<endl;display(noPageCount);return;}//先进先出页面置换算法FIFOvoid FIFO(){int blockFlag = 0,pageFlag = 0,resultFlag = 0; //物理块标记,确定该换出的物理块下标int i = 0,j = 0,noPageCount = 0;int position = 0; //指示物理块,查找有无空闲while (pageFlag < pSize){if(Exist(page[pageFlag]) != -1)resultFlag++;else{if(position < bSize){block[position] = page[pageFlag];position++;noPageCount++;for(i = 0;i <= position;i++)result[resultFlag][i] = block[i];resultFlag++;}else{block[blockFlag] = page[pageFlag]; //blockFlag指示要换出的页面noPageCount++;for(i = 0;i < bSize;i++)result[resultFlag][i] = block[i];resultFlag++;blockFlag++;blockFlag = blockFlag % bSize;}}pageFlag++;}cout<<endl<<"先进先出页面置换算法FIFO:"<<endl;display(noPageCount);return;}//最近最久未用算法LRUvoid LRU(){int i = 0,noPageCount = 0;int pageFlag = 0,resultFlag = 0,position = 0;for(i = 0;i < BlockSize;i++) //初始化时间记录数组blockFlag[i] = 0;while(pageFlag < pSize){if(Exist(page[pageFlag]) != -1){ //判断页面是否已经在主存中resultFlag++;blockFlag[Exist(page[pageFlag])] = 0; //若在则将时间记录数组对应位置为0 }else{if(position < bSize){block[position] = page[pageFlag];blockFlag[position] = 0;position++;noPageCount++;for(i = 0;i <= position;i++)result[resultFlag][i] = block[i];resultFlag++;}else{int last = 0,min = blockFlag[0];for(int i = 0;i < bSize;i++)if(min < blockFlag[i]){min = blockFlag[i];last = i;}block[last] = page[pageFlag]; //置换最久未用页面blockFlag[last] = 0;noPageCount++;for(i = 0;i < bSize;i++)result[resultFlag][i] = block[i];resultFlag++;}}for(i = 0;i < bSize;i++)blockFlag[i]++;pageFlag++;}cout<<endl<<"最近最久未用算法LRU:"<<endl;display(noPageCount);return;}//时钟(clock)置换算法void clock(){int i = 0,position = 0,noPageCount = 0;bool boolBlockFlag[BlockSize];int flag = 0; //访问位循环标记int pageFlag = 0,resultFlag = 0;while(pageFlag < pSize){if(Exist(page[pageFlag]) != -1){resultFlag++;boolBlockFlag[Exist(page[pageFlag])] = true;}else{if(position < bSize){block[position] = page[pageFlag];noPageCount++;boolBlockFlag[position] = true;position++;for(i = 0;i < position;i++)result[resultFlag][i] = block[i];resultFlag++;}else{while(true){ //无限循环,找出访问位为false 的页面if(boolBlockFlag[flag] == false) break;boolBlockFlag[flag] = false; //若为true,置为falseflag++;flag = flag%bSize;}block[flag] = page[pageFlag];boolBlockFlag[flag] = true;flag++;flag = flag%bSize;noPageCount++;for(i = 0;i < position;i++)result[resultFlag][i] = block[i];resultFlag++;}}pageFlag++;}cout<<endl<<"时钟(clock)置换算法:"<<endl;display(noPageCount);return;}int main(){initPage();int func;while(func!=5){cout<<"请选择所需要的功能:"<<endl;cout<<"0.输入数据"<<endl;cout<<"1.最佳(optimal)置换算法"<<endl;cout<<"2.先进先出(FIFO)置换算法"<<endl;cout<<"3.最近最久未用(LRU)置换算法"<<endl;cout<<"4.时钟(clock)置换算法"<<endl;cout<<"5.退出"<<endl;switch(func){case 0:inputData();break;case 1:initBlockResult();OPT();break;case 2:initBlockResult();FIFO();break;case 3:initBlockResult();LRU();break;case 4:initBlockResult();clock();break;case 5:break;}cout<<"请选择功能:";cin>>func;system("cls");}return 0;}。
页面置换算法程序代码

//最近最少使用调度算法(LRU)
void LRU()
{
int absence=0;
int i,j;
int flag;
cout<<endl<<"----------------------------------------------------"<<endl;
pages[i].hit=0;
}
}
//读入页访问流
void readData()
{
FILE *fp;
char fname[20];
int i;
cout<<"请输入页面流文件名:";
cin>>fname;
if((fp=fopen(fname,"r"))==NULL)
{
//缺页处理
if(absence>=MAXQUEUE)
{cout<<pages[0].loaded<<" "; }// pages[0]是队列头
for(j=0;j<MAXQUEUE-1;j++)
{
pages[j]=pages[j+1];
}
pages[MAXQUEUE-1].loaded=queue[i];
{
cout<<"错误,文件打不开,请检查文件名";
}
else
{
while(!feof(fp))
{
fscanf(fp,"%d ",&queue[quantity]);
matlab实现fifo页面置换算法 -回复

matlab实现fifo页面置换算法-回复如何使用MATLAB实现FIFO页面置换算法FIFO页面置换算法,也称为先进先出页面置换算法,是最简单且最常见的页面置换算法之一。
该算法按照页面进入内存的顺序进行页面置换,即最早进入内存的页面最先被置换出去。
在本文中,我将逐步介绍如何使用MATLAB实现FIFO页面置换算法。
让我们一起开始吧!步骤1:导入所需模块和数据首先,我们需要导入MATLAB中所需的模块和数据。
在这个例子中,我们假设我们有一个页面引用序列,即一个包含许多页面的数组。
我们还需要定义内存的大小,即能容纳的页面数量。
导入页面引用序列page_references = [2, 3, 4, 2, 1, 5, 6, 2, 5, 4, 3, 2, 1, 5, 6];定义内存大小(页面数量)memory_size = 3;步骤2:初始化数据结构接下来,我们需要初始化一些数据结构。
我们将使用一个队列来表示内存中的页面,并使用一个集合来保存当前内存中的页面。
初始化一个空队列,用于表示内存中的页面memory_queue = [];初始化一个空集合,用于保存当前内存中的页面memory_set = [];步骤3:遍历页面引用序列现在,我们可以开始遍历页面引用序列,模拟页面的引用过程,并根据FIFO 页面置换算法将页面置换出去。
对于每个页面引用,我们需要执行以下步骤:1. 检查页面是否已经在内存中:如果页面已经在内存中,我们继续执行下一个页面引用。
2. 检查内存是否已满:如果内存已满,我们需要从内存中移除一个页面。
按照FIFO算法的原理,我们需要移除队列中的第一个页面,并从内存集合中删除该页面。
3. 将页面添加到内存中:将页面添加到队列的末尾,并将该页面添加到内存集合中。
以下是以上步骤的MATLAB代码实现:for i = 1:length(page_references)page = page_references(i);检查页面是否已经在内存中if ismember(page, memory_set)continue;end检查内存是否已满if length(memory_queue) == memory_size从队列中移除第一个页面removed_page = memory_queue(1);memory_queue = memory_queue(2:end);从内存集合中删除该页面memory_set = memory_set(memory_set ~=removed_page);end将页面添加到内存中memory_queue = [memory_queue, page];memory_set = [memory_set, page];end步骤4:计算页面置换次数在完成对页面引用序列的遍历后,我们可以计算页面置换的次数。
页面置换算法

#include "windows.h"#include <conio.h>#include <stdlib.h>#include <fstream.h>#include <io.h>#include <string.h>#include <stdio.h>void initialize(); //初始化相关数据结构void createps(); //随机生成访问序列void displayinfo(); //显示当前状态及缺页情况void fifo(); //先进先出算法int findpage(); //查找页面是否在内存void lru(); //最近最久未使用算法int invalidcount = 0; // 缺页次数int vpoint; //页面访问指针int pageframe[10]; // 分配的页框int pagehistory[10]; //记录页框中数据的访问历史int rpoint; //页面替换指针int inpflag; //缺页标志,0为不缺页,1为缺页struct PageInfo //页面信息结构{int serial[100]; // 模拟的最大访问页面数,实际控制在20以上int flag; // 标志位,0表示无页面访问数据int diseffect; // 缺页次数int total_pf; // 分配的页框数int total_pn; // 访问页面序列长度} pf_info;//////////////////////////////////////////////////////////////////////////初始化相关数据结构void initialize(){int i,pf;inpflag=0; //缺页标志,0为不缺页,1为缺页pf_info.diseffect =0; // 缺页次数pf_info.flag =0; // 标志位,0表示无页面访问数据printf("\n请输入要分配的页框数:"); // 自定义分配的页框数scanf("%d",&pf);pf_info.total_pf =pf;for(i=0;i<100;i++) // 清空页面序列{pf_info.serial[i]=-1;}}///////////////////////////////////////////////////////////////////// 随机生成访问序列void createps(void ){int s,i,pn;initialize(); //初始化相关数据结构printf("\n请输入要随机生成访问序列的长度:"); //自定义随机生成访问序列的长度scanf("%d",&pn);srand(rand()); //初始化随机数队列的"种子"s=((float) rand() / 32767) * 50 + pn; // 随机产生页面序列长度pf_info.total_pn = s;for(i=0;i<s;i++) //产生随机访问序列{pf_info.serial[i]=((float) rand() / 32767) * 16 ; //随机数的大小在0-15之间}}////////////////////////////////////////////////////////////////////////// 显示当前状态及缺页情况void displayinfo(void){int i,n;if(vpoint==0){printf("\n=============页面访问序列=============\n");for(i=0; i<pf_info.total_pn; i++){printf("%4d",pf_info.serial[i]);if ((i+1) % 10 ==0) printf("\n"); //每行显示10个}printf("\n======================================\n");}printf("访问%3d : 内存<",pf_info.serial[vpoint]);for(n=0;n<pf_info.total_pf;n++) // 页框信息{if (pageframe[n] >=0)printf("%3d",pageframe[n]);elseprintf(" ");}printf(" >");if(inpflag==1) //缺页标志,0为不缺页,1为缺页{printf(" ==>缺页");printf("缺页率%3.1f",(float)(pf_info.diseffect)*100.00/vpoint);}printf("\n");}////////////////////////////////////////////////////////////////////////// 查找页面是否在内存,1为在内存,0为不在即缺页int findpage(int page){int n;for(n=0;n<pf_info.total_pf;n++){pagehistory[n] ++; // 访问历史加1}for(n=0;n<pf_info.total_pf;n++){if (pageframe[n]==page ){inpflag=0 ; //inpflag缺页标志,0为不缺页,1为缺页pagehistory[n]=0; //置访问历史为0return 1;}}inpflag=1; //页面不存在,缺页return 0;}////////////////////////////////////////////////////////////////////////// FIFO页面置换算法void fifo(void){int n,count,pstate;rpoint=0; // 页面替换指针初始化为0invalidcount = 0; // 缺页数初始化为0createps(); // 随机生成访问序列count=0; // 是否装满是所有的页框for(n=0;n<pf_info.total_pf;n++) // 清除页框信息{pageframe[n]=-1;}inpflag=0; //缺页标志,0为不缺页,1为缺页for(vpoint=0;vpoint<pf_info.total_pn;vpoint++) // 执行算法{pstate=findpage(pf_info.serial[vpoint]); //查找页面是否在内存if(count<pf_info.total_pf) // 开始时不计算缺页{if(pstate==0) // 页不存在则装入页面{pageframe[rpoint]=pf_info.serial[vpoint];rpoint=(rpoint+1) % pf_info.total_pf;count++;}}else // 正常缺页置换{if(pstate==0) // 页不存在则置换页面{pageframe[rpoint]=pf_info.serial[vpoint];rpoint=(rpoint+1) % pf_info.total_pf;pf_info.diseffect++; // 缺页次数加1}}Sleep(10);displayinfo(); // 显示当前状态} // 置换算法循环结束_getch();return;}///////////////////////////////////////////////////////////////////// LRU页面置换算法void lru(void){int n,count,pstate,max;rpoint=0; // 页面替换指针invalidcount = 0; // 缺页次数初始化为0createps(); // 随机生成访问序列count=0; // 是否装满所有的页框for(n=0;n<pf_info.total_pf;n++){pageframe[n]=-1; // 清除页框信息pagehistory[n]=0; // 清除页框历史}inpflag=0; //缺页标志,0为不缺页,1为缺页for(vpoint=0;vpoint<pf_info.total_pn;vpoint++) // 执行算法{pstate=findpage(pf_info.serial[vpoint]); //查找页面是否在内存if(count<pf_info.total_pf) // 开始时不计算缺页{if(pstate==0) // 页不存在则装入页面{pageframe[rpoint]=pf_info.serial[vpoint]; //把要调入的页面放入一个空的页框里rpoint=(rpoint+1) % pf_info.total_pf;count++;}}else // 正常缺页置换{if(pstate==0)// 页不存在则置换页面{max=0;for(n=1;n<pf_info.total_pf;n++){if(pagehistory[n]>pagehistory[max]){max=n;}}rpoint=max;pageframe[rpoint]=pf_info.serial[vpoint];pagehistory[rpoint]=0;pf_info.diseffect++; // 缺页次数加1}}Sleep(10);displayinfo(); // 显示当前状态} // 置换算法循环结束_getch();return;}///////////////////////////////////////////////////////////////////// 主函数int main(){char ch;system("cls") ;while ( true ){//printf("若要执行FIFO页面置算法请按"1"\n");//printf("若要执行LRU 页面置算法请按"2" \n");//printf("若要退出请按"3"\n");printf("*******************************************\n");printf( "Enter your choice (1 or 2 or 3): ");do{ //如果输入信息不正确,继续输入ch = (char)_getch() ;}while(ch != '1' && ch != '2'&& ch != '3');printf("\n\n你按的是:%c ,现在为你执行对应操作。
页面置换算法(FIFO算法,LRU算法)

实验四页面置换算法一、实验流程图二、实验程序#include <stdio.h>#include <stdlib.h>#include <malloc.h>#define null 0#define len sizeof(struct page)struct page{ int num;int tag;struct page *next;};struct page *create(int n) /*建立分配的内存空间,并初始化,返回头结点*/{int count=1;struct page *p1,*p2,*head;head=p2=p1=(struct page *)malloc(len); //开辟一个新的单元,并将malloc返回的指针转换为结构体类型的指针p1->tag=-1;p1->num=-1;while(count<n){count++;p1=(struct page *)malloc(len);p1->tag=-1;p1->num=-1;p2->next=p1;p2=p1;}p2->next=null;return(head);}void FIFO(int array[],int n){int *p;struct page *cp,*dp,*head,*new1;int count=0;head=create(n);p=array;while(*p!=-1){ cp=dp=head;for(;cp->num!=*p&&cp->next!=null;) cp=cp->next;if (cp->num==*p) printf(" ! " );else{ count++;cp=head;for(;cp->tag!=-1&&cp->next!=null;) cp=cp->next;if(cp->tag==-1){cp->num=*p;printf(" * ");}else{new1=(struct page*)malloc(len);new1->num=*p;new1->tag=0;new1->next=null;cp->next=new1;head=head->next;printf(" %d ",dp->num);free(dp);}}p++;}printf("\nQueye Zongshu : %d \n",count);}void LRU(int array[],int n){int count=0,*p=array;struct page *head,*cp,*dp,*rp,*new1,*endp;head=create(n);while(*p!=-1){cp=dp=rp=endp=head;for(;endp->next!=null;) endp=endp->next;for(;cp->num!=*p&&cp->next!=null;){rp=cp;cp=cp->next;}if(cp->num==*p){printf(" ! ");if(cp->next!=null){if(cp!=head)rp->next=cp->next;else head=head->next;}endp->next=cp;cp->next=null;}else{count++;cp=rp=head;for(;cp->tag!=-1&&cp->next!=null;) cp=cp->next;{printf(" * ");cp->num=*p;cp->tag=0;}else{new1=(struct page *)malloc(len);new1->num=*p;new1->tag=0;new1->next=null;cp->next=new1;dp=head;head=head->next;printf(" %d ",dp->num);free(dp);}}p++;}printf("\nQueye Zongshu : %d \n",count);}OPT(int array[],int n){int *p,*q,count=0,i;struct page *head,*cp,*dp,*new1;p=array;head=create(n);while(*p!=-1){ cp=head;for(;cp->num!=*p&&cp->next!=null;) cp=cp->next;if(cp->num!=*p){ count++;cp=head;for(;cp->tag!=-1&&cp->next!=null;) cp=cp->next;if(cp->tag==-1){printf(" * ");cp->num=*p;cp->tag=0;}else{ i=1;q=p;q++;cp=head;while(*q!=-1&&i<n){ for(;*q!=cp->num&&cp->next!=null;) cp=cp->next;if(*q==cp->num){cp->tag=1;i++;}q++;cp=head;}if(i==n){for(;cp->tag!=0;) cp=cp->next;printf(" %d ",cp->num);cp->num=*p;}else{ cp=head;for(;cp->tag!=0;) cp=cp->next;if(cp==head){ for(;cp->next!=null;) cp=cp->next;new1=(struct page *)malloc(len);new1->num=*p;new1->tag=0;new1->next=null;cp->next=new1;dp=head;head=head->next;printf(" %d ",dp->num);free(dp);}else{ printf(" %d ",cp->num);cp->num=*p;}}cp=head;for(;cp->next!=null;) {cp->tag=0;cp=cp->next;}cp->tag=0;}}else printf(" ! ");p++;}printf("\nQueye Zongshu : %d \n",count);}main(){FILE *fp;char pt;char str[10];int i,j=0;int page[50],space=0;for(i=0;i<50;i++)page[i]=-1;fp=fopen("page.txt","r+");if(fp==NULL){printf("Cann't open the file\n");exit(0);}i=0;while((pt=fgetc(fp))!=EOF)/*将数字字符串转化成整型-开始*/ {if(pt>='0'&&pt<='9'){str[i]=pt;i++;space=0;}else{if(pt==' '||pt=='\n'){if(space==1) break;else{str[i]='\0';page[j]=atoi(str);if(pt=='\n') break;else{space=1;j++;i=0;}}}}}/*结束*/if(pt==EOF) {str[i]='\0';page[j]=atoi(str);}i=0;while(page[i]!=-1) {printf(" %d ",page[i]);i++;}fclose(fp);printf("\n");printf(" ! : mean no moved \n * : mean have free space \n\n"); printf("FIFO ");FIFO(page,3);printf("\nLRU ");LRU(page,3);printf("\nOPT ");OPT(page,3);}。
lfu页面置换算法代码

lfu页面置换算法代码下面是一个简单的 LFU (Least Frequently Used) 页面置换算法的Python 实现。
这个实现是基于一个字典和一个列表,其中字典存储了每个页面的访问频率,列表存储了所有页面的访问顺序。
```pythonclass LFU:def __init__(self, capacity):self.capacity = capacityself.cache = {}self.order = []self.freq = {}def get(self, key):if key in self.cache:value = self.cache[key]self.order.remove(key)self.order.append(key)self.update_freq(key)return valueelse:return -1def put(self, key, value):if len(self.cache) >= self.capacity:lfu_key = self.order[0]del self.cache[lfu_key]del self.freq[lfu_key]self.order.remove(lfu_key)else:self.order.append(key)self.cache[key] = valueself.update_freq(key)def update_freq(self, key):if key in self.freq:self.freq[key] += 1else:self.freq[key] = 1```在这个实现中,`get` 方法用于获取一个键的值,如果键在缓存中,那么它将被从缓存中移除并添加到访问顺序的末尾,然后更新访问频率。
如果键不在缓存中,那么返回 -1。
`put` 方法用于添加一个新的键值对到缓存中,如果缓存已经满了,那么将删除访问频率最低的键和它的值。
页面置换算法实验(内含完整代码)

实验二存储管理一、实验目的通过模拟实现请求页式存储管理的几种基本页面置换算法,了解虚拟存储技术的特点,掌握虚拟存储请求页式存储管理中几种基本页面置换算法的基本思想和实现过程,并比较它们的效率。
二、实验内容基于一个虚拟存储区和内存工作区,设计下述算法并计算访问命中率。
1、最佳淘汰算法(OPT)2、先进先出的算法(FIFO)3、最近最久未使用算法(LRU)4、简单时钟(钟表)算法(CLOCK)命中率=1-页面失效次数/页地址流(序列)长度三、实验原理简述UNIX中,为了提高内存利用率,提供了内外存进程对换机制;内存空间的分配和回收均以页为单位进行;一个进程只需将其一部分(段或页)调入内存便可运行;还支持请求调页的存储管理方式。
当进程在运行中需要访问某部分程序和数据时,发现其所在页面不在内存,就立即提出请求(向CPU发出缺中断),由系统将其所需页面调入内存。
这种页面调入方式叫请求调页。
为实现请求调页,核心配置了四种数据结构:页表、页帧(框)号、访问位、修改位、有效位、保护位等。
当CPU接收到缺页中断信号,中断处理程序先保存现场,分析中断原因,转入缺页中断处理程序。
该程序通过查找页表,得到该页所在外存的物理块号。
如果此时内存未满,能容纳新页,则启动磁盘I/O将所缺之页调入内存,然后修改页表。
如果内存已满,则须按某种置换算法从内存中选出一页准备换出,是否重新写盘由页表的修改位决定,然后将缺页调入,修改页表。
利用修改后的页表,去形成所要访问数据的物理地址,再去访问内存数据。
整个页面的调入过程对用户是透明的。
四、算法描述本实验的程序设计基本上按照实验内容进行。
即使用srand( )和rand( )函数定义和产生指令序列,然后将指令序列变换成相应的页地址流,并针对不同的算法计算出相应的命中率。
(1)通过随机数产生一个指令序列,共320条指令。
指令的地址按下述原则生成:A:50%的指令是顺序执行的B:25%的指令是均匀分布在前地址部分C:25%的指令是均匀分布在后地址部分具体的实施方法是:A:在[0,319]的指令地址之间随机选取一起点mB:顺序执行一条指令,即执行地址为m+1的指令C:在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m’D:顺序执行一条指令,其地址为m’+1E:在后地址[m’+2,319]中随机选取一条指令并执行F:重复步骤A-E,直到320次指令(2)将指令序列变换为页地址流设:页面大小为1K;用户内存(页帧)容量为4页~32页;用户虚存容量为32K。
存储管理的页面置换算法

FCFS算法设计说明:按照所要求的产生随机指令序列,存放在order[320]这个数组中。
通过循环产生这些随机指令,每产生一条都要进行下列判断:是否和内存中即mem_volume[4]中存放的页面相同,如果相同则不做任何操作,如果不相同,则产生缺页,相应的缺页次数加一,按照fcfs将最先进入内存的页数淘汰,并将该页写到内存中去。
重复上面的操作直到完成这320条指令。
Fcfs页面置换算法实现代码:#include <stdio.h>#include <stdlib.h>#include <time.h>int main(void){int order[320],mem_volume[4]={100,100,100,100};int l=0,i=0,j,num=0,cx,sign=0,add=0;float value=0,sum=0;srand(time(NULL));for(cx=0;cx<10;cx++){while(i<320){order[i]=rand()%320; //产生随机数放order中for(j=0;j<4;j++)if((order[i]+1)/10==mem_volume[j])sign=1; //通过sign标识判断所调页数是否在内存块中if(sign)sign=0;else{l++;if(mem_volume[3]==100)mem_volume[3]=(order[i]+1)/10;// 保证第一次调入的页面都产生缺页else{mem_volume[num]=(order[i]+1)/10; //将所缺页调入到内存块中num=(num+1)%4; //num值为下次所要置换出去的内存块中对应的页数}}i++;order[i]=rand()%(order[i-1]+2);for(j=0;j<4;j++)if(order[i]/10==mem_volume[j])sign=1;if(sign)sign=0;else {l++;if(mem_volume[2]==100)mem_volume[2]=order[i]/10;else{mem_volume[num]=order[i]/10;num=(num+1)%4;}}i++;order[i]=order[i-1]+1;for(j=0;j<4;j++)if(order[i]/10== mem_volume[j])sign=1;if(sign)sign=0;else{l++;if(mem_volume[1]==100)mem_volume[1]=order[i]/10;else{mem_volume[num]=order[i]/10;num=(num+1)%4;} }i++;order[i]=rand()%(319-order[i-1]-2)+(order[i-1]+2); for(j=0;j<4;j++)if(order[i]/10==mem_volume[0])sign=1;if(sign)sign=0;else {l++;if(mem_volume[0]==100)mem_volume[0]=(order[i]+1)/10;else{mem_volume[num]=order[i]/10;num=(num+1)%4;} }i++;}value=l/320.0*100;add=add+l;sum=sum+value;}printf("\2***************FCFS页面置换算法*******************\2\n");printf("*******************最后一次指令序列************************");for(i=0;i<320;i++){if(i%10==0)printf("\n");printf("%5d",order[i]);}printf("\n");printf("*****************************************************\n");printf("\t\t十次的平均缺页数为%d\n\t\t十次的平均缺页率为%.3f%%",add/10,sum/10);return 0;}LRU页面置换算法设计说明:这个算法同FCFS算法的不同之处在于,每产生一条随机指令,如果和4个内存块中的某一个页数相同的话,就要对这4个内存块中的页数重新排序,将每次要置换出去的页数放在mem_volume[3]中,这样,在每次产生缺页的时候,都先将所缺页数写入到该内存块,然后再排序,将其放到mem_volume[0]中去。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验原理:
在内存运行过程中,若其所要访问的页面不在内存而需要把他们调入内存,但内存已经没有空闲空间时,为了保证该进程能正常运行,系统必须从内存中调出一页程序或数据送磁盘的对换区中。
但应将那个页面调出,需根据一定的算法来确定。
通常,把选择换出页面的算法成为页面置换算法。
置换算法的好坏,将直接影响到系统的性能。
一个好的页面置换算法,应具有较低的页面更换频率。
从理论上讲,应将那些以后不再会访问的页面置换出,或者把那些在较长时间内不会在访问的页面调出。
目前存在着许多种置换算法(如FIFO,OPT,LRU),他们都试图更接近理论上的目标。
实验目的:
1.熟悉FIFO,OPT和LRU算法
2.比较三种算法的性能优劣
实验内容:
写出FIFO,OPT和LRU算法的程序代码,并比较它们的算法性能。
实验步骤:
代码如下:
#include <stdio.h>
#define M 4 //物理页数
#define N 20 //需要调入的页数
typedef struct page
{
int num;
int time;
//物理页项,包括调入的页号和时间}Page;
Page mm[M]; //4个物理页
int queue1[20],queue2[20],queue3[20];//记录置换的页
int K=0,S=0,T=0;
//置换页数组的标识
int pos=0;//记录存在最长时间项
//初始化内存页表项及存储内存情况的空间
. . . .
void INIT(){
int i;
for(i=0;i<M;i++){
mm[i].num =-1;
mm[i].time =0;
}
}
取得内存中存在时间最久的位置//int GetMax(){
int max=-1;
int i;
for(i=0;i<M;i++){
if(mm[i].time > max){
max=mm[i].time ;
pos=i;
}
}
return pos;
}
检查最长时间不使用页面//int longesttime(int fold)
{
int i;
int max=-1;
for(i=fold;i<N;i++){
if(mm[0].num!=i){
mm[0].time++;
}
if(mm[1].num!=i){
mm[1].time++;
. . . . }
if(mm[2].num!=i){
mm[2].time++;
}
if(mm[3].num!=i){
mm[3].time++;
}
}
for(i=0;i<M;i++){
if(mm[i].time>max){
max=mm[i].time;
pos=i;
}
}
return pos;
}
//检查某页是否在内存
int Equation(int fold){
int i;
for(i=0;i<M;i++){
if(mm[i].num == fold)
return i;
}
return -1;
}
//检查物理内存是否已满,-1表满,其他不满int Check(){
int i;
for(i=0;i<M;i++){
if(mm[i].num == -1)
. . . .
return i;
}
return -1;
}
//先进先出
void FIFO(int fold){
int i;
int a,b,c;
a=Equation(fold);
//页已存在
if(a != -1){}
//页不存在
else{
b=Check();
// 内存还有空闲
if(b != -1){
mm[b].num = fold;
}
// 内存已满,需要置换
else {
c=GetMax();
mm[c].num = fold;
mm[c].time = 0;
}
queue1[K++]=fold;
}
for(i=0;i<M;i++){
if(mm[i].num != -1){
mm[i].time ++;
}
. . . . }
}
void OPT(int fold)
{
int a,b,c;
a=Equation(fold);
if(a == -1){//页不在内存
b=Check();
//内存还有空闲
if(b != -1){
mm[b].num = fold;
}
内存已满,需要置换//
else{
c=longesttime(fold);
mm[c].num = fold;
mm[c].time = 0;
}
queue3[T++]=fold;
}
}
void LRU(int fold)
{
int i;
int a,b;
int p;
a=Equation(fold);
if(a != -1)//页已在内存{
. . . . //把此项移动到链表最后一项
if(a==3)// 此项已经在最后,不需要做任何改动
return;
else
{
p=Equation(-1);
if(p==-1)// 链表是满的
{
for(;a<3;a++)
mm[a].num=mm[a+1].num;
mm[3].num=fold;
}
else if(p<=3)// 链表不满
{
for(;a<p-1;a++)
mm[a].num=mm[a+1].num;
mm[a].num=fold;
}
}
}
else
{
b=Check();
if(b!=-1)//不满
mm[b].num=fold;
else
{
for(i=0;i<3;i++)
mm[i].num=mm[i+1].num;
mm[3].num=fold;
. . . . }
queue2[S++]=fold;
}
}
void main()
{
int A[N],B[N];
int i;
INIT();
牰湩晴尨请依次输入%d个页面号:\n,N);
for(i=0;i<N;i++){
scanf(%d,&A[i]);
}
//FIFO
for(i=0;i<N;i++){
B[i]=A[i];
}
for(i=0;i<N;i++){
FIFO( B[i] );
}
); printf(FIFO的); 调入队列为:牰湩晴尨
for(i=0;i<K;i++)
printf(=,queue1[i]);
printf(\
缺页次数为:m\n缺页率:_x0016_.6f\n\n,K,(float)K/N);
//LRU
INIT();
for(i=0;i<N;i++){
B[i]=A[i];
}
. . . . for(i=0;i<N;i++){
LRU( B[i] );
}
); printf(LRU的
); 牰湩晴尨调入队列为:for(i=0;i<S;i++)
printf(=,queue2[i]);
printf(\
缺页次数为:m\n缺页率:_x0016_.6f\n\n,S,(float)S/N);
//OPT
INIT();
for(i=0;i<N;i++){
B[i]=A[i];
}
for(i=0;i<N;i++){
OPT( B[i] );
}
); printf(OPT的
); 调入队列为:牰湩晴尨for(i=0;i<T;i++)
printf(=,queue3[i]);
printf(\
缺页次数为:m\n缺页率:_x0016_.6f\n\n,T,(float)T/N);
}
. . . .。