l 页面大小为 1K;
l 用户内存容量为 4 页到 40 页;
l 用户外存的容量为 40k;
在用户外存中,按每 K 存放 10 条指令,400 条指令在外存中的存放方式为:
Ø 0-9 条指令为第 0 页;
Ø 10-19 条指令为第 1 页;
Ø 。。。。。
Ø 390-399 条指令为第 39 页;
Ø 按以上方式,用户指令可组成 40 页;
通过随机数产生一个指令序列,共 400 个指令(
0-399)。
模拟请求页式存储管理中页面置换算法。执行一条指令,首先在外存中查找
所对应的页面和页面号,然后将此页面调入内存中,模拟并计算下列各述算法在
不同内存容量下的命中率(页面有效次数/页面流的个数)。
(1). 最佳置换算法
(2). 先进先出置换算法(FIFO)
(3). 最久未使用置换算法(LRU)
这一题利用我在这里主要使用OPT、FIFO、LRU算法来计算命中率。这里我主要是使用0~399的十进制数字来抽象为一个指令,利用随机函数rand()获取一个十进制随机值,通过查找得到该抽象指令并且得到页号,将这个页号调入内存,注意内存的大小不是固定的这里需要手动输入内存块数目。利用三中算法求出页面有效次数以及页面流的个数 ,页面流的个数这里我理解的是400,主要问题就是页面流里可不可以出现连续的相同页号。但是由于没有确切的依据可以证明我是错误的,所以这里的页面流的个数是400,读取的是400条指令。
废话少说,直接上代码!
#include<iostream>
#include<cstdlib>
#include"time.h"
using namespace std;
struct p_str{
int pagenum; /* 页号 */
int count; /* 访问页面的次数 */
struct p_str *next; /* 下一指针 */
}p_str;
int replace_OPT(int memory[],int page[],int M,int n){
int position=0;
int max=0;
//找到置换的位置
for(int i=0;i<M;i++){
int j;
for(j=n+1;j<400;j++){
if(memory[i]==page[j]){
break;
}
}
if(j>max){
max=j;
position=i;
}
}
return position;
}
void OPT(int page[],int M){
int memory[400];
int lose=0;//页面失效数
int i,j;
for(i=0;i<400;i++){
if(i<=M-1){
memory[i]=page[i];
}
else{
//先查找有没有在内存里
for(j=0;j<M;j++){
if(page[i]==memory[j])
break;
}
if(j<M){
continue;
}
else{
//没有在内存里页面访问失效
lose++;
// cout<<"lose:"<<lose<<endl;
memory[replace_OPT(memory,page,M,i)]=page[i];
// cout<<"memory: ";
// for(int k=0;k<M;k++)
// cout<<memory[k]<<" ";
// cout<<endl;
}
}
}
cout<<"利用OPT算法得到的命中率为:"<<(397-lose)/((double)400)<<endl;
}
int replace_LRU(int memory_time[],int M){
int position=0;
int max=0;
for(int i=0;i<M;i++){
if(memory_time[i]>max){
max=memory_time[i];
position=i;
}
}
return position;
}
void LRU(int page[],int M){
int memory[400];
int memory_time[400]={0};//记录时间
int lose=0;
int i,j;
for(int i=0;i<400;i++){
//先让页面进入内存这个时候算失效的
if(i<=M-1){
memory[i]=page[i];
memory_time[i]++;
}
else{
//先找有没有在内存里
for(j=0;j<M;j++){
if(page[i]==memory[j])
break;
}
if(j<M){
for(int l=0;l<M;l++){
if(l==j)
memory_time[j]=0;
else
memory_time[l]++;
}
continue;
}
else{
//产生缺页中断,页面失效
lose++;
int position=replace_LRU(memory_time,M);
memory[position]=page[i];
for(int l=0;l<M;l++){
if(l==position)
memory_time[position]=0;
else
memory_time[l]++;
}
}
}
}
cout<<"利用LRU算法得到的命中率为:"<<(397-lose)/((double)400)<<endl;
}
int replace_FIFO(int memory_time[],int M){
int position=0;
int max=0;
for(int i=0;i<M;i++){
if(memory_time[i]>max){
max=memory_time[i];
position=i;
}
}
return position;
}
void FIFO(int page[],int M){
int memory[400];
int lose=0;
int i,j;
int memory_time[400];
for(int i=0;i<400;i++){
//先让页面进入内存
if(i<=M-1){
memory[i]=page[i];
memory_time[i]++;
}
else{
//先找没有在内存里
for(j=0;j<M;j++){
if(page[i]==memory[j])
break;
}
if(j<M){
for(int l=0;l<M;l++)
memory_time[l]++;
continue;
}
else{
//没有在内存里发生缺页中断
lose++;
int position=replace_FIFO(memory_time,M);
memory_time[position]=page[i];
for(int l=0;l<M;l++){
if(l==position)
memory_time[position]=0;
else
memory_time[l]++;
}
}
}
}
cout<<"利用FIFO算法得到的命中率为:"<<(397-lose)/((double)400)<<endl;
}
int main(){
int M;
int external_storage[400];
cout<<"输入内存块的个数(4~40)"<<endl;
cin>>M;
//在外存里存储好指令集
for(int i=0;i<400;i++){
external_storage[i]=i;
}
//产生的400条指令得到的页面集
int page[400];
srand((unsigned)time(NULL));//产生不同的随机种子
for(int i=0;i<400;i++){
page[i]=(rand()%400)/10;
}
OPT(page,M);
LRU(page,M);
FIFO(page,M);
}
运行结果:
从测试的数据来看,相同内存块的情况下,命中率:OPT>LRU>FIFO;随着内存块的增加,OPT、LRU、FIFO算法的的命中率都有所提高。其中OPT的命中率更是接近于100%