广州大学2020操作系统实验三:内存管理

在这里插入图片描述
五份实验报告下载链接:click~

课程设计下载链接:click~

一、实验目的

1、了解虚拟存储技术的特点,掌握虚拟存储请求页式存储管理中几种基本页面置换算法的基本思想和实现过程,并比较它们的效率。
2、了解程序设计技术和内存泄露的原因

二、实验内容

模拟实现请求页式存储管理的几种基本页面置换算法
(1)最佳淘汰算法(OPT)
(2)先进先出的算法(FIFO)
(3)最近最久未使用算法(LRU))

三、实验原理

四、实验中用到的系统调用函数(包括实验原理中介绍的和自己采用的),自己采用的系统调用函数要按照指导书中的格式说明进行介绍。

因为是模拟程序,可以不使用系统调用函数。

五、实验步骤

1、画出每个页面置换算法流程图
最佳淘汰算法(OPT)

选择永不使用或在未来最长时间内不再被访问的页面予以替换。

在这里插入图片描述

先进先出的算法(FIFO)

选择在内存中驻留时间最久的页面予以替换。
在这里插入图片描述

最近最久未使用算法(LRU)

选择过去最长时间未被访问的页面予以替换。
在这里插入图片描述

2、对算法所用的数据结构进行说明;
int instructionset[N];	//指令序列
int page[N];	//指令序列对应的页面
int record[n],memory[n]//memory为内存,record记录进程内页面的信息

record使用较为灵活,在三种算法中担任的角色均不相同,详情可看程序框图的蓝色框框,里面重点讲述页面置换算法的实际操作。

六、实验数据及源代码(学生必须提交自己设计的程序源代码,并有注释,源代码电子版也一并提交),包括思考题的程序。

process.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define N 320 //指令数
#define MAX 1000

int instructionset[N]; //指令序列
int page[N]; //指令序列对应的页面

void init(); //随机初始化测试数据
void OPT(int n); //最佳淘汰算法(OPT)
void FIFO(int n); //先进先出的算法(FIFO)
void LRU(int n); //最近最久未使用算法(LRU)

int main()
{
srand((unsigned long)time(0)); //产生随机数种子 
init(); //随机初始化测试数据
printf("最佳淘汰算法(OPT):\n");
for(int i=4;i<=32;i++)OPT(i);

printf("先进先出的算法(FIFO):\n");
for(int i=4;i<=32;i++)FIFO(i); 

printf("最近最久未使用算法(LRU):\n");
for(int i=4;i<=32;i++)LRU(i);
}

void LRU(int n)
{
int i,j,k,flag,record[n],memory[n],value=0; //memory为内存,record记录进程内页面的信息,记录上次使用到现在的时间
double right=0;
for(i=0;i<n;i++){
record[i]=-1;
memory[i]=-1;
}

for(i = 0;i<N;i++){
flag = 0;
for(j=0;j<n;j++) //记录该页面占用的时间
if(record[j]!=-1)record[j]=record[j]+1 ;

for(j=0;j<n;j++)
if(page[i]==memory[j]){
right+=1;
record[j]=0;
flag = 1;
break;
}
if(flag==1)continue;
for(j=0;j<n;j++){ //缺页中断
if(record[j] == -1){ //有空余内存,可直接进入
record[j] = 0;
memory[j] = page[i];
flag = 1;
break;
}
}
if(flag==1)continue;
for(j=0;j<n;j++) //记录页面占用的时间最多的下标
if(record[j]>=record[value]) value = j;
memory[value] = page[i]; //替换
}
printf("内存%d页命中率=%lf\n",n,right/N);
FILE *fp;
fp=fopen("LRU.txt","a");
fprintf(fp,"%lf ",right/N);
fclose(fp);
}

void FIFO(int n)
{ 
int i,j,k,flag,record[n],memory[n],value=0; //memory为内存,record记录进程内页面的信息,是否已经使用
double right=0;
for(i=0;i<n;i++){
record[i]=-1;
memory[i]=-1;
}
for(i = 0;i<N;i++){
flag = 0;
for(j=0;j<n;j++)
if(page[i]==memory[j]){
right+=1;
flag = 1;
break;
}
if(flag==1)continue;
for(j=0;j<n;j++) //缺页中断
if(record[j] == -1){ //有空余内存,可直接进入
record[j] = MAX;
memory[j] = page[i];
flag = 1;
break;
}
if(flag==1)continue;
memory[value] = page[i]; //value记录最早进来的,因为是按顺序,接下来加一即可
value = (value+1)%n;

}
printf("内存%d页命中率=%lf\n",n,right/N); 
FILE *fp;
fp=fopen("FIFO.txt","a");
fprintf(fp,"%lf ",right/N);
fclose(fp);
}

void OPT(int n)
{
int i,j,k,flag,record[n],memory[n],value=0; //memory为内存,record记录进程内页面的信息,用于淘汰
double right=0;
for(i=0;i<n;i++){
record[i]=-1;
memory[i]=-1;
}
for(i = 0;i<N;i++){
flag = 0;
for(j=0;j<n;j++)
if(page[i]==memory[j]){
right+=1;
flag = 1;
break;
}
if(flag==1)continue;
for(j=0;j<n;j++) //缺页中断
if(record[j] == -1){ //有空余内存,可直接进入
record[j] = MAX;
memory[j] = page[i];
flag = 1;
break;
}
if(flag==1)continue;
for(j=0;j<n;j++){ //遍历已占内存的页面在将来最早使用是什么时候,在遍历的过程中顺便把最远的记录下来淘汰 
record[j] = MAX; 
for(k=i+1;k<N;k++)
if(memory[j]==page[k]){
record[j] = k-i;
break;}
if(record[j]>=record[value])value=j;
}
memory[value] = page[i];
}
printf("内存%d页命中率=%lf\n",n,right/N);
FILE *fp;
fp=fopen("OPT.txt","a");
fprintf(fp,"%lf ",right/N);
fclose(fp);
}



void init()
{
int i= 0;

while(1){ //按照实验要求随机生成指令的地址
instructionset[i] = rand()%N;
instructionset[i] = instructionset[i++]+1;
if(i>=N)break;
instructionset[i] = rand()%(instructionset[i++]+1);
instructionset[i] = instructionset[i++]+1;
if(i>=N)break;
instructionset[i] = rand()%(N-instructionset[i]-1)+instructionset[i++]+1;
instructionset[i++] = instructionset[i++]+1;
if(i>=N)break;
}
/* 
while(1){ //展开实验,不按照要求随机生成指令的地址
instructionset[i++] = rand()%N;
if(i>=N)break;
}

while(1){ //展开实验,模拟较早调入的页往往是经常访问的页
instructionset[i++] = rand()%N;
if(i>=N)break;
if(i>=20){
int num = rand()%10;
if(num<=4)
instructionset[i++] = instructionset[num];
}
if(i>=N)break;
}
*/

for(i=0;i<N;i++)
page[i] = instructionset[i]/10;
/*
for(i=0;i<N;i++)
printf("->%d",instructionset[i]);
printf("\n");
*/

printf("指令序列对应的页面:\n");
for(i=0;i<N;i++)
printf("->%d",page[i]);
printf("\n");
}

绘制折线图主要代码(python)

from matplotlib import pyplot as plt
x = [i+4 for i in range(29)]
y1 = OPT
y2 = FIFO
y3 = LRU

fig,ax=plt.subplots(figsize=(15,5))
plt.xticks([i+4 for i in range(0, 29)], fontsize=10, rotation=0)  
line1,=ax.plot(x,y1,color='darkblue',linestyle='-',label='OPT')
line2,=ax.plot(x,y2,color='deeppink',linestyle='-',label='FIFO')
line3,=ax.plot(x,y3,color='black',linestyle='-',label='LRU')
plt.legend()  # 让图例生效
plt.xlabel("Memory pages") #X轴标签
plt.ylabel("hit ratio") #Y轴标签
plt.grid() 
plt.show()
七、实验结果分析(截屏的实验结果,与实验结果对应的实验分析)
展示部分结果

结果一:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

命中率结果分析

将以上五次实验得到的结果平均后,绘制内存页数-命中率折线图,观察比较三种算法的效果。
在这里插入图片描述
(一)由上图可得结论,不同算法随着内存页数的增多,命中率也会逐渐上升,假设N条指令均匀分布在n页中,缺页率最小可到达n/N = 32/320 *100%=10%,所以命中率最大即为90%。
(二)三种算法之间不分伯仲,OPT算法在内存页数充足的情况下明显优于另外两种算法。
(三)OPT其实是一种理想算法,它通过预知未来进行了页面调度,因此效果好确实是应该的。
(四)LRU算法从整体来看,与FIFO算法曲线大致重合,是因为这个输入的指令序列的缘故,每前后两页基本重合,然后每两页都是通过随机生成的,体现不出LRU的优势。

展开实验分析

这三种算法都是非常经典的算法,因此接下来尝试使用多组数据去比较它们的优劣。

① 指令序列完全随机

将五次随机指令序列输入实验得到的结果平均后,绘制内存页数-命中率折线图,观察比较三种算法的效果。
在这里插入图片描述
(一)在指令序列随机的情况下,OPT由于拥有预知未来的能力,效果明显优于另外两种算法。
(二)FIFO和LRU整体效果差不多,因为对于完全随机的序列,基本每次的页号都不相同,在这种情况下,FIFO和LRU被替换的往往是同一页,因此它们的效果也如上图所示。

② 指令序列模拟较早调入的页往往是经常访问的页

将五次模拟“较早调入的页往往是经常访问的页”序列输入实验得到的结果平均后,绘制内存页数-命中率折线图,观察比较三种算法的效果。
在这里插入图片描述
(一)在这种输入的情况下,就可以看出LRU的微小优势了,因为在现实场景下,首先调入的页往往是较为重要的,而FIFO的先进先出是导致算法效果差的主要原因。

③ 在2的基础上,把指令序列调至1000

在这里插入图片描述
(一)在这种输入的情况下,就可以看出LRU的巨大优势了,前面的内存给的实在是太多了,还有指令序列给的太随机性了,不符合现实场景,这个很好地诠释了LRU的优点。
(二)LRU作为结合了OPT和LRU的算法,效果确实很明显,但是它需要实际硬件的支持。

八、思考题

1、从几种算法的命中率看,哪个算法最高?哪个算法最低?对每个页面的执行结果进行分析。

将以上五次实验得到的结果平均后,绘制内存页数-命中率折线图,观察比较三种算法的效果。
在这里插入图片描述
(一)在前面的命中率结果分析中已经简单总结了这三个算法的命中率差别。
(二)经过前面的展开实验进行分析,可知该实验的数据集存在约束性,不能正确反映算法在所有情况下的好坏,该图只能反映在这一特定指令序列下的命中率。

2、OPT算法在执行过程中可能会发生错误,为什么?

(一)OPT算法在实现上有困难,因为它需要预先知道一个进程在整个运行过程中页面走向的全部情况。
(二)想要实现OPT算法是不现实的,它只是一种理想算法,因为我们无法预知将来主存的页面调度情况,所以我们可以采用与它接近的算法LRU。

猜你喜欢

转载自blog.csdn.net/weixin_43999137/article/details/107566453