虚拟存储器实验报告.docx
《虚拟存储器实验报告.docx》由会员分享,可在线阅读,更多相关《虚拟存储器实验报告.docx(12页珍藏版)》请在冰豆网上搜索。
虚拟存储器实验报告
佛山科学技术学院
实验报告
课程名称操作系统原理实验
实验项目虚拟存储器
专业班级姓名学号
指导教师成绩日期
一、实验目的
1、了解虚拟存储器的基本原理和实现方法。
2、掌握几种页面置换算法。
二、实验内容
设计模拟实现采用不同内外存调度算法进行页面置换,并计算缺页率。
三、实验原理
内存在计算机中的作用很大,电脑中所有运行的程序都需要经过内存来执行,如果执行的程序很大或很多,就会导致内存消耗殆尽。
为了解决这个问题,Window中运用了虚拟内存技术,即拿出一部分硬盘空间来充当内存使用,当内存占用完时,电脑就会自动调用硬盘来充当内存,以缓解内存的紧张。
虚拟存储器是指具有请求调入功能和置换功能,能从逻辑上对内存容量加以扩充的一种存储器系统。
它是采用一定的方法将一定的外存容量模拟成内存,同时对程序进出内存的方式进行管理,从而得到一个比实际内存容量大得多的内存空间,使得程序的运行不受内存大小的限制。
虚拟存储区的容量与物理主存大小无关,而受限于计算机的地址结构和可用磁盘容量。
虚拟内存的设置主要有两点,即内存大小和分页位置,内存大小就是设置虚拟内存最小为多少和最大为多少;而分页位置则是设置虚拟内存应使用那个分区中的硬盘空间。
(一)页式虚拟存储器
在页式虚拟存储系统中,将程序按统一的大小划分成多个页,同时也将虚拟存储器划分为同样大小的页,其中虚拟空间的页称为虚页(逻辑页),而主存空间的页称为实页(物理页),并对这些页按地址从低到高的顺序编号。
在编程时,程序的虚地址由高位字段的虚页号和低位字段的页内地址两部分组成,虚页号标识页。
虚地址到实地址之间的变换是由页表来实现的。
页表是一张存放在主存中的虚页号和实页号的对照表,记录着程序的虚页调入主存时被安排在主存中的位置。
若计算机采用多道程序工作方式,则可为每个用户作业建立一个页表,硬件中设置一个页表基址寄存器,存放当前所运行程序的页表的起始地址。
页表中的每一行记录了与某个虚页对应的若干信息,包括虚页号、装入位和实页号等。
页表基址寄存器和虚页号拼接成页表索引地址。
根据这个索引地址可读到一个页表信息字,然后检测页表信息字中装入位的状态。
若装入位为1,表示该页面已在主存中,将对应的实页号与虚地址中的页内地址相拼接就得到了完整的实地址;若装入位为0,表示该页面不在主存中,于是要启动I/O系统,把该页从辅存中调入主存后再供CPU使用,若主存已满,还需要使用替换算法替换页。
(二)页面置换算法
在地址映射过程中,若在页面中发现所要访问的页面不再内存中,则产生缺页中断。
当发生缺页中断时操作系统必须在内存选择一个页面将其移出内存,以便为即将调入的页面让出空间。
而用来选择淘汰哪一页的规则叫做页面置换算法。
几中常见的页面置换方法如下:
1.最佳置换算法(OPT):
选择永不使用或是在最长时间内不再被访问(即距现在最长时间才会被访问)的页面淘汰出内存。
2.先进先出置换算法(FIFO):
选择最先进入内存即在内存驻留时间最久的页面换出到外存。
3.最近最久未使用置换算法(LRU):
以“最近的过去”作为“最近的将来”的近似,选择最近一段时间最长时间未被访问的页面淘汰出内存
4.时钟置换算法Clock:
为进入内存的页面设置一个访问位,当内存中某页被访问,访问位置一,算法在选择一页淘汰时,只需检查访问位,若为0,则直接换出,若为1,置该访问位为0,检测内存中的下一个页面的访问位。
5.最少使用置换算法(LFU):
在内存中为每个页面设置一个移位寄存器,用来记录该页面被访问的频率。
选择在最近时期使用最少的页面作为淘汰页
6.随机置换算法(S):
产生一个取值范围在0和N-1之间的随机数,该随机数即可表示应被淘汰出内存的页面。
四、实验步骤
1.定义页表的存储结构,设置作业进程所占内存空间为640K,页面大小为1K/2K/4K/8K,随机生成100个页面,用于分配页面大小的内存总空间为32K。
2.初始化进程的页面引用序列。
3.选择下列六种置换算法中的三种编写程序,进行页面置换,并计算缺页次数和缺页率。
(1)最佳置换算法(OPT)
(2)先进先出置换算法(FIFO):
(3)最近最久未使用算法(LRU)
(4)时钟置换算法(CLOCK)
(5)最少使用置换算法(LFU)
(6)随机置换算法(S)
4.使用菜单形式,选择不同的置换方法,显示换页过程、缺页次数及缺页率。
五、实验代码
#include
#include
#include
#defineM3//内存页数
#defineN20//页面引用序列数
#defineMyprintfprintf("---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---\n")
/*表格控制*/
//定义页面的存储结构
typedefstructpage
{
intnum;//记录页面号
inttime;//记录调入内存时间
intvisitBit;//访问位
}Page;
PageP[M];//内存单元数
intc[M][N];//暂保存内存当前的状态
intqueue[M]={-1,-1,-1};//记录调入内存的页面
intfront=0;//队列头指针
intcurrent=0;
//初始化内存单元、缓冲区
voidInit(Page*p,intc[M][N])
{
inti,j;
for(i=0;i{
p[i].num=-1;
p[i].time=N-i-1;
p[i].visitBit=0;
}
for(i=0;ifor(j=0;jc[i][j]=-1;
}
//判断页面是否已在内存中
intEquation(intfold,Page*p)
{
inti;
for(i=0;i{
if(fold==p[i].num)
returni;
}
return-1;
}
//先进先出页面置换算法,加载的页面已在内存中,则
//返回0。
否则置换出最先调入内存的页,并返回1
intFIFO(intfold,Page*p)
{
inti,y;
intval=Equation(fold,p);
if(val<0)//请求页面不在内存
{
y=queue[front];//最先调入内存的页出队
queue[front]=fold;//加入队尾
front=(front+1)%M;
for(i=0;iif(y==p[i].num)
{
p[i].num=fold;//页面置换
break;
}
return1;
}
return0;
}
//LRU置换算法
//取得在内存中停留最久的页面,默认状态下为最早调入的页面
intGetMax(Page*p)
{
inti;
intmax=-1;
inttag=0;
for(i=0;i{
if(p[i].time>max)
{
max=p[i].time;
tag=i;
}
}
returntag;
}
//LRU核心部分
intLRU(intfold,Page*p)
{
inti;
inta;
a=Equation(fold,p);
if(a>=0)
{
p[a].time=0;
for(i=0;iif(i!
=a)
p[i].time++;
return0;
}
else
{
a=GetMax(p);
p[a].num=fold;
p[a].time=0;
for(i=0;iif(i!
=a)
p[i].time++;
return1;
}
}
//时钟置换算法
//取的内存中访问位为0的淘汰页面
intGetClockPage(Page*p)
{
inti;
for(i=0;i{
if(0==p[current].visitBit)
returncurrent;
else
{
p[current].visitBit=0;
current=(current+1)%M;
}
}
returncurrent;
}
intClock(intfold,Page*p)
{
intval;
val=Equation(fold,p);
if(val<0)
{
val=GetClockPage(p);
p[val].num=fold;
p[val].visitBit=1;
return1;
}
return0;
}
//显示换页过程
voidPrintf(inta[],intq[],intk)
{
inti,j;
printf("显示换页过程:
\n");
Myprintf;
for(j=0;jprintf("%2d|",a[j]);
Myprintf;
for(i=0;i{
for(j=0;j{
if(c[i][j]==-1)
printf("%2c|",32);
else
printf("%2d|",c[i][j]);
}
}
Myprintf;
printf("\n调入队列为:
");
for(i=0;iprintf("%3d",q[i]);
printf("\n缺页次数为:
%6d\n缺页率:
%16.6f\n",k+1,(float)(k+1)/N);
printf("\n");
}
intMenu()
{
inti;
printf("\t\t*******************页面置换算法*******************\n");
printf("\t1.先进先出置换算法(FIFO)\n");
printf("\t2.最近最久未使用算法(LRU)\n");
printf("\t3.时钟置换算法(CLOCK)\n");
printf("\t4.退出\n");
printf("\t\t******************请输入您的选择******************\n");
scanf("%d",&i);
getchar();
returni;
}
//主函数
voidmain()
{
inti,j,flag;
intq[100];//记录调入队列
intk;//调入队列计数变量
inta[N]={7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1};
while
(1)
{
flag=Menu();
switch(flag)
{
case1:
//先进先出置换算法(FIFO)
{
Init(P,c);
k=-1;
for(i=0;i{
if(FIFO(a[i],P))
q[++k]=a[i];//记录调入页面
c[0][i]=a[i];
for(j=0;jc[j][i]=P[j].num;
}
Printf(a,q,k);
}
break;
case2:
//最近最久未使用算法(LRU)
{
Init(P,c);
k=-1;
for(i=0;i{
if(LRU(a[i],P))
q[++k]=a[i];//记录调入页面
for(j=0;jc[j][i]=P[j].num;
}
Printf(a,q,k);
}
break;
case3:
//时钟置换算法(CLOCK)
{
Init(P,c);
k=-1;
for(i=0;i{
if(Clock(a[i],P))
q[++k]=a[i];//记录调入页面
else//访问页已在内存,访问位置1
{
for(j=0;jif(a[i]==P[i].num)
P[i].visitBit=1;
}
current=(current+1)%M;
for(j=0;jc[j][i]=P[j].num;
}
Printf(a,q,k);
}
break;
case4:
{
printf("欢迎使用!
\n");
exit
(1);
}
break;
}
}
}
六、实验结果及分析
1.先进先出置换算法
2.最近最久未使用算法
3.时钟置换算法
4.退出操作
七、心得体会及实验改进建议
经过这次操作系统实验我知道了不同的内外存调度算法进行页面置换,模拟了3种的算法调度。
我做完了实验之后觉得我自己对虚拟存储器认识增加了不少,虽然在做完实验之后觉的成就感让我很高兴,但是更让我高兴的是在做这个实验的过程中我对书本上的理论知识加深了很多。
虽然在做实验的过程中遇到了很多问题,但是每当我解决完一个问题的时候都会觉得自己的能力提高了很多,真的让人很兴奋!
如果有机会我真的很想多做类似的实验,锻炼一下自己,让自己能够更快地提高!