操作系统课程设计五、请求分页系统中的置换算法
操作系统课程设计五、请求分页系统中的置换算法#
实验内容###
1.通过如下方法产生一指令序列,共 320 条指令。
A. 在[1,32k-2]的指令地址之间随机选取一起点,访问 M;
B. 顺序访问M+1;
C. 在[0,M-1]中随机选取M1,访问 M1;
D. 顺序访问M1+1;
E. 在[M1+2,32k-2]中随机选取M2,访问 M2;
F. 顺序访问M2+1;
G. 重复 A—F,直到执行 320 次指令。
2. 指令序列变换成页地址流设:
(1)页面大小为 1K;
(2) 分配给用户的内存页块个数为 4 页到 32 页,步长为1页;
(3)用户虚存容量为 32K。
- 计算并输出下述各种算法在不同内存页块下的命中率。
A. 先进先出(FIFO)页面置换算法
B. 最近最久未使用(LRU)页面置换算法
C. 最佳(Optimal)页面置换算法
实验功能及设计思路###
程序功能:
采用题目要求在随机生成的指令序列,页面大小为 1K,分配给用户的内存页块个数为 4 页到 32 页,步长为1页。用户虚存容量为 32K。分别计算先进先出(FIFO)页面置换算法,B.最近最久未使用(LRU)页面置换算法,C.最佳(Optimal)页面置换算法在不同内存页块下的命中率。以表格形式给出。
设计思路:
- 希望程序设计出的效果为依次打印不同内存页块下三种算法的命中率,主程序中只需要设计一个循环,调用函数计算,依次打印即可。
- 设计一个预处理函数,按照题目要求设计出320个随机的指令序列。取用srand(time(0));设定时间种子。使用随机函数rand()%M得到0~M-1的随机数(M<MAX_INT),当指令到达320时,停止生成指令。由于产生的为地址,最后需要除以1024得到所在的页号。
- FIFO算法,用链表模拟队列。初始化之后,每次取得下一个指令,检查队列中存在对应的页号,如果存在命中次数加1,否则删除队列中最后一个页号,插入当前页号。
- LRU算法,选择最近且最久未被使用的页面进行淘汰。利用局部性原理,根据一个作业在执行过程中过去的页面访问历史来推测未来的行为。它认为过去一段时间里不曾被访问过的页面,在最近的将来可能也不会再被访问。所以,这种算法的实质是:当需要淘汰一个页面时,总是选择在最近一段时间内最久不用的页面予以淘汰。 设置一个结构体,保存指令所在的页号和在队列中没有被访问的次数。如果需要淘汰,每次淘汰没有被访问次数最多的页号。
- OPT算法:从主存中移出永远不再需要的页面;如无这样的页面存在,则选择最长时间不需要访问的页面。于所选择的被淘汰页面将是以后永不使用的,或者是在最长时间内不再被访问的页面,这样可以保证获得最低的缺页率。每次淘汰时,评估每一个页号将来的位置,选择最长时间不需要访问的页面淘汰。
- 程序只需要集成一个初始化函数和三个页面置换算法函数即可。
源代码##
#include <iostream>
#include<algorithm>
#include<list>
#include<vector>
#include<iomanip>
#include<climits>
#include<time.h>
#include<stdio.h>
using namespace std;
const int minn=4;
const int maxx=32;
const int N=320;
int ins[2*N];
double hit_num=0;
const int max_add=32766;//32k-2
struct node{
int id;
int num;
};
void get_input(){
int cnt=0;
srand(time(0));
while(cnt<N){
int m=rand()%max_add+1;
ins[cnt++]=m;
if(cnt>=N)break;
ins[cnt++]=m+1;
if(cnt>=N)break;
int m1=rand()%m;
ins[cnt++]=m1;
if(cnt>=N)break;
ins[cnt++]=m1+1;
if(cnt>=N)break;
int m2=rand()%(max_add-1-m1)+(m1+2);
ins[cnt++]=m2;
if(cnt>=N)break;
ins[cnt++]=m2+1;
if(cnt>=N)break;
}
for(int i=0;i<N;i++){
ins[i]=ins[i]/1024;//得到所在的
}
// for(int i=0;i<N;i++){
// cout<<ins[i]<<" ";
// }
}
double FIFO(int page){
hit_num=0;
list<int>temp;
for(int i=0;i<page;i++){
temp.push_back(-1);
}
for(int i=0;i<N;i++){
list<int>::iterator it=find(temp.begin(),temp.end(),ins[i]);
if(it==temp.end()){
temp.pop_front();
temp.push_back(ins[i]);
}else{
hit_num++;
}
}
hit_num=hit_num/N;
hit_num*=100;
return hit_num;
}
double LRU(int page){
hit_num=0;
list<node>temp;
for(int i=0;i<page;i++){
temp.push_back(node{-1,0});
}
list<node>::iterator it;
for(int i=0;i<N;i++){
for(it=temp.begin();it!=temp.end();it++){
it->num++;
}
bool flag=false;
for(it=temp.begin();it!=temp.end();it++){
if(it->id==ins[i]){
flag=true;
it->num=0;
hit_num++;
break;
}
}
if(!flag){
//找到一个最大的
list<node>::iterator max_it=temp.begin();
for(it=temp.begin();it!=temp.end();it++){
if(it->num>max_it->num){
max_it=it;
}
}
temp.erase(max_it);
temp.push_back(node{ins[i],0});
}
}
hit_num=hit_num*1.0/N;
hit_num*=100;
return hit_num;
}
double OPT(int page){
list<int>temp;
hit_num=0;
for(int i=0;i<page;i++){
temp.push_back(-1);
}
for(int i=0;i<N;i++){
list<int>::iterator it=find(temp.begin(),temp.end(),ins[i]);
if(it==temp.end()){
int max_id=-1;
list<int>::iterator ans;
for(it=temp.begin();it!=temp.end();it++){
//初始化
int cur=0x3f3f3f3f;
for(int j=i+1;j<N;j++){
if(ins[j]==*it){
cur=j;
break;
}
}
if(cur>max_id){
max_id=cur;
ans=it;
}
}
temp.erase(ans);
temp.push_back(ins[i]);
}else{
hit_num++;
}
}
hit_num=hit_num*1.0/N;
hit_num*=100;
return hit_num;
}
int main()
{
get_input();
cout<<" 三种算法命中率比较表格 "<<endl;
cout<<"内存页块 FIFO LRU OPT"<<endl;
for(int i=minn;i<=maxx;i++){
printf("%d %.2f %.2f %.2f\n",i,FIFO(i),LRU(i),OPT(i));
}
return 0;
}
不疯魔不成活