实验目的:
实现分页式存储地址转换过程,在此基础上实现请求分页的地址转换。实现请求分页式地址转换中出现的缺页现象中,用到的FIFO、LRU、OPT置换算法。
实现方法:
用一张位示图,来模拟内存的分配情况,利用随机数产生一组0和1的数对应内存的使用情况。
利用结构体数组将页表和内存块封装。
实现过程:
#include<stdio.h> #include<stdlib.h> #include<iostream.h> #include<time.h> struct Page { int kuai; int stage; }FPage[1000],LPage[1000]; struct Memory { int num; int page; }FMemory[1000],LMemory[1000],OMemory[1000]; int PageLength; /*页表长度*/ int Memsize; /*内存块数*/ int FAbsent,LAbsent,OAbsent,visit; /*FIFO中的缺页次数 LRU中的缺页次数 访问内存次数 */ int Logical; /*逻辑地址*/ int Pagenumber,Pageaddr;/*页号 页内地址*/ int Physical; /*物理地址*/ int PageSize; /*块的大小*/ int Freemem; /*空闲内存*/ int G[8][8]; int opt[10000]; int oth=0; int temp[1000]; void GShow() { int i,j; printf("位式图:\n"); for(i=0;i<8;i++) { printf("\t"); for(j=0;j<8;j++) printf("%d ",G[i][j]); printf("\n"); } } void init() /*初始化*/ { srand((unsigned)time(NULL)); int i,j; for(i=0;i<8;i++) G[0][i]=1; for(i=1;i<8;i++) { for(j=0;j<8;j++) G[i][j]=rand()%2; } for(i=0;i<PageLength;i++) { FPage[i].kuai=-1; FPage[i].stage=0; LPage[i].kuai=-1; LPage[i].stage=0; } for(i=0;i<Memsize;i++) { FMemory[i].page=-1; } for(i=0;i<Memsize;i++) { LMemory[i].page=-1; } for(i=0;i<Memsize;i++) { OMemory[i].num=i; OMemory[i].page=-1; } FAbsent=LAbsent=visit=0; } void Show() { int i; printf("FPage:\t\t\t\t\tLPage:\n"); printf("\t页号\t块号\t状态位\t\t\t页号\t块号\t状态位\n"); for(i=0;i<PageLength;i++) { printf("\t%d\t",i); if(FPage[i].kuai==-1) printf(" \t"); else printf("%d\t",FPage[i].kuai); printf("%d",FPage[i].stage); printf("\t\t\t%d\t",i); if(LPage[i].kuai==-1) printf(" \t"); else printf("%d\t",LPage[i].kuai); printf("%d\n",LPage[i].stage); } printf("\nFMemory:\t\t\t\tLMemory:\n"); printf("\t块号\t页号\t\t\t\t块号\t\t页号\n"); for(i=Memsize-1;i>=0;i--) { printf("\t%d\t",i); if(FMemory[i].page==-1) printf(" \t\t"); else printf("%d\t\t",FMemory[i].page); printf("\t\t%d\t",i); if(LMemory[i].page==-1) printf("\n"); else printf("\t%d\n",LMemory[i].page); } printf("Logical: %d\n",Logical); printf("Count: %d %d\n",Pagenumber,Pageaddr); printf("Physical: %d\n",Physical); printf("PageSize: %d\n",PageSize); printf("Visit: %d\n",visit); printf("FAbsent: %d LAbsent: %d\n",FAbsent,LAbsent); printf("FRate: %.2f%% LRate: %.2f%%\n",(double)FAbsent*100/(double)visit,(double)LAbsent*100/(double)visit); } void FIFO() /*FIFO算法*/ { int i; int m,n; if(FPage[Pagenumber].stage==1) /*命中*/ ; else /*缺页*/ { FAbsent++; FPage[Pagenumber].stage=1; for(i=0;i<Memsize;i++) { if(FMemory[i].page==-1) { for(m=1;m<8;m++) { for(n=0;n<8;n++) if(G[m][n]==0) { break; } if(n<8) break; } Freemem=(m-1)*8+n; FMemory[i].page=Pagenumber; FPage[Pagenumber].kuai=Freemem; break; } } if(i==Memsize) { FPage[Pagenumber].kuai=FPage[FMemory[0].page].kuai; FPage[FMemory[0].page].kuai=-1; FPage[FMemory[0].page].stage=0; for(i=0;i<Memsize-1;i++) FMemory[i].page=FMemory[i+1].page; FMemory[i].page=Pagenumber; } } } void LRU() /*LRU算法*/ { int i,j,m,n,l; //bool flag=true; for(l=0;l<Memsize;l++) if(LMemory[l].page==-1) break; if(LPage[Pagenumber].stage==1)/*命中*/ { for(i=0;i<l;i++) { if(LMemory[i].page==Pagenumber) { for(j=i;j<l-1;j++) { LMemory[j].page=LMemory[j+1].page; } LMemory[j].page=Pagenumber; break; } } } else /*没命中*/ { LAbsent++; LPage[Pagenumber].stage=1; if(l<Memsize) //问题出在这里,l++之前需要判断一下 如果l<memsize说明有空闲块,则l++ ,否则块已经满了,l不能++ ... l++; for(i=0;i<l;i++) { if(LMemory[i].page==-1) { for(m=1;m<8;m++) { for(n=0;n<8;n++) if(G[m][n]==0) { G[m][n]=1; break; } if(n<8) break; } Freemem=(m-1)*8+n; LMemory[i].page=Pagenumber; LPage[Pagenumber].kuai=Freemem; for(j=i;j<l-1;j++) { LMemory[j].page=LMemory[j+1].page; } LMemory[j].page=Pagenumber; break; } } if(i==l) { LPage[LMemory[0].page].stage=0; LPage[Pagenumber].kuai=LPage[LMemory[0].page].kuai; LPage[LMemory[0].page].kuai=-1; for(j=0;j<l-1;j++) LMemory[j].page=LMemory[j+1].page; LMemory[j].page=Pagenumber; } } } void OPTshow() { int i; printf("\t"); for(i=Memsize-1;i>=0;i--) { if(OMemory[i].page==-1) printf(" "); else printf(" %d",OMemory[i].page); } printf("\n"); } void OPT() { printf("\nOPTMemory:\n"); printf("\t 2 1 0\n\n"); int i,j,k,l,m,n; int count=0; for(i=0;i<oth;i++) { for(j=0;j<Memsize;j++) { if(OMemory[j].page==opt[i]) break; } if(j<Memsize) ; else { for(j=0;j<Memsize;j++) { if(OMemory[j].page==-1) /*如果此时内存没满还有空缺 就直接将页号写进去*/ { OMemory[j].page=opt[i]; break; } } if(j==Memsize) /*需要发生置换*/ { OAbsent++; for(n=0;n<Memsize;n++) temp[n]=0; for(k=i+1;k<oth;k++) { for(l=0;l<Memsize;l++) { if(OMemory[l].page==opt[k]) { temp[l]++; break; } } count=0; for(m=0;m<Memsize;m++) { if(temp[m]==0) count++; } if(count>1&&k<oth-1) ; else { for(m=0;m<Memsize;m++) if(temp[m]==0) { OMemory[m].page=opt[i]; break; } } } } } OPTshow(); } printf("OAbsent: %d\n",OAbsent); printf("ORate: %.2f%%\n",(double)OAbsent*100/(double)visit); } void cometrue() { printf("输入页表长度(页):"); scanf("%d",&PageLength); printf("输入内存块数(块):"); scanf("%d",&Memsize); printf("输入页面大小(kb):"); scanf("%d",&PageSize); init(); while(printf("输入逻辑地址(10进制): ")&&scanf("%d",&Logical)) { if(Logical!=-1) { Pagenumber=Logical/(PageSize*1024); Pageaddr=Logical%(PageSize*1024); if(Pagenumber>=PageLength) { printf("越界中断......!\n"); continue; } opt[oth++]=Pagenumber; GShow(); FIFO(); LRU(); Physical=Freemem*PageSize*1024+Pageaddr; visit++; Show(); } else if(Logical==-1) { int i; printf("页号访问序列:\n"); for(i=0;i<oth;i++) printf("%d ",opt[i]); printf("\n"); OPT(); break; } } } int main() { cometrue(); return 0; }