介绍
-
假设分给一作业的内存块数为4,每个页面中可存放10条指令。
-
用C语言设计一个程序,模拟一作业的执行过程。设该作业共有320条指令,即它的地址空间为32页,目前它的所有页面都还未调入内存。在模拟过程中,如果所访问的指令已经在内存,则显示其物理地址,并转下一条指令。如果所访问的指令尚未装入内存,则发生缺页,此时需记录缺页的次数,并将相应页调入内存。如果4个内存块中均已装入该作业的虚页面,则需进行页面置换。最后显示其物理地址,并转下一条指令。在所有320条指令执行完毕后,请计算并显示作业运行过程中发生的缺页率。
-
置换算法:请考虑 LFU 算法。
-
作业中指令的访问次序要求按下述原则生成:
- 50%的指令是顺序执行的。
- 25%的指令是均匀分布在前地址(即低地址)部分。
- 25%的指令是均匀分布在后地址(即高地址)部分。
具体的实施办法是:
① 在[0,319]之间随机选取一条起始执行指令,其序号为m;
② 顺序执行下一条指令,即序号为m+1的指令;
③ 通过随机数,跳转到前地址部分[0,m-1]中的某条指令处,其序号为m1;
④ 顺序执行下一条指令,即序号为m1+1的指令;
⑤ 通过随机数,跳转到后地址部分[m1+2,319]中的某条指令处,其序号为m2;
⑥ 顺序执行下一条指令,即序号为m2+1的指令;
⑦ 重复“跳转到前地址部分、顺序执行、跳转到后地址部分、顺序执行”的过程,直至执行完全部320条指令。 -
指令序列转换成页访问序列。
第 0 条-第 9 条指令为第0页(对应虚存地址为[0,9])
第10条-第19条指令为第1页(对应虚存地址为[10,19])
………………………………
第310条-第319条指令为第31页(对应虚存地址为[310,319])
最近最少使用 ( LFU )
基于“如果一个数据在最近一段时间内使用次数很少,那么在将来一段时间内被使用的可能性也很小”的思路。LFU是基于访问次数的。
代码
//页面置换_LFU
#include<bits/stdc++.h>
using namespace std;
int s[320];
int cnt = 0;
int lost = 0;
typedef struct node {
int order; //页面序号
int sum; //页面访问次数
}cache_;//页面元素
list<cache_> cache ;
//初始化
void init()
{
cnt = 0; //访问次数为 0
lost = 0; //缺页次数为 0
for(int i=0;i<320;i++)
s[i] = 220+i; //设置指令的物理地址
}
//寻找当前指令是否在内存块中
bool find (int x)
{
bool judge = false;
for(list<cache_>::iterator iter = cache.begin() ; iter != cache.end() ; iter++)
{
if((*iter).order == x ){
judge = true;
(*iter).sum ++;
}
}
return judge;
}
//当内存空间已满的时候,进行页面置换
void delete_cache(){
//找到最少使用的页面
int minn = 10000;
list<cache_>::iterator it ;
for(list<cache_>::iterator iter = cache.begin() ; iter != cache.end() ; iter++)
{
if((*iter).sum < minn ){
it = iter;
minn = (*iter).sum;
}
}
//将该页面从内存块中删除
cache.erase( it);
}
//执行每一条指令
int process(int x)
{
cout<<"第"<< cnt<<" 条指令 " ;
cnt++;
cache_ y;
y.order = x/10;
y.sum = 0;
//判断当前指令是否在内存块中
bool judge = find(x/10);
//如果当前指令在内存块中,显示其物理地址
if(judge == true) {
cout <<" 物理地址:"<<s[x]<<endl;
}
//如果当前指令不在内存块中
else{
lost ++;
//如果内存块还有空余,直接将该指令所在页面调入内存块
if(cache.size() < 4 ){
cache.push_back(y);
}
//如果内存块没有空余,进行页面置换
else {
delete_cache();
cache.push_back(y);
}
cout <<" 物理地址:"<<s[x]<<endl;
}
return 1;
}
int main()
{
init();
int m=rand()%320;//在[0,319]之间随机选取一条起始执行指令,其序号为m
process(m);//执行指令,即序号为 m的指令
process(m+1);//顺序执行下一条指令,即序号为m+1的指令
// 重复"跳转到前地址部分、顺序执行、跳转到后地址部分、顺序执行"的过程,159次
for(int i=0;i<316;i+=4)
{
int m1=rand()%m;//通过随机数,跳转到前地址部分[0,m-1]中的某条指令处,其序号为m1
process(m1);//执行指令,即序号为m1的指令
process(m1+1);//顺序执行下一条指令,即序号为m1+1的指令
int m2=rand()%(320-(m1+2)) + m1 + 2;//通过随机数,跳转到后地址部分[m1+2,319]中的某条指令处,其序号为m2
process(m2);//执行指令,即序号为m1的指令
process(m2+1);//顺序执行下一条指令,即序号为m2+1的指令
}
int m1=rand()%m;//通过随机数,跳转到前地址部分[0,m-1]中的某条指令处,其序号为m1
process(m1);//执行指令,即序号为m1的指令
process(m1+1);//顺序执行下一条指令,即序号为m1+1的指令
cout<<endl<<"缺页率为"<<lost/320.0 <<endl;
return 0;
}