操作系统中讲到的OPT算法,即优化替换算法,是用当前时刻以后的的页地址流来判断当前应该替换哪一块。简而言之,是将当前frame中,以后最长时间不会用到的替换掉。OPT是一种理想算法,这种算法常常用于估算其他算法的效率,因为在实际中,当前时刻是不知道以后时刻的页地址流的,故这种算法在实际中是不可能实现的。
LRU算法,即近期最少使用算法(Least Recently Used),即选择近期最少访问的页作为被替换的页,这种算法能够正确的反应程序的局部性,一般来说,当前最少使用的页,未来也将最少被访问。但近期最少访问实现起来比较难,故一般用其变形--近期最久未被访问的页作为被替换页,即近期最久未使用算法。
代码如下://注释没有hhhhhh,这里就解释一下哈,n是地址流数目,m是frame数量,然后再输入n个地址流序列即可。
#include <stdio.h>
#include <iostream>
#include <string>
#include <string.h>
#include <math.h>
using namespace std;
const int maxn=1e3+7;
struct frame
{
int id;
int next=-1,last=-1;
bool change=false;
};
int n,m;
int a[maxn];
frame b[10];
bool hit(int num)
{
for(int i=0;i<m;i++)
if(num==b[i].id)
return true;
return false;
}
int getnext(int local)
{
for(int i=0;i<m;i++)
b[i].next=-1,b[i].change=false;
for(int i=local+1;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(a[i]==b[j].id)
b[j].next=i;
}
}
int maxx=-1,tmp=0;
for(int i=0;i<m;i++)
{
if(b[i].next==-1)
{
b[i].change=true;
return i;
}
if(b[i].next>maxx)
{
tmp=i;
maxx=b[i].next;
}
}
b[tmp].change=true;
return tmp;
}
int getnext2(int local)
{
for(int i=0;i<m;i++)
b[i].last=-1,b[i].change=false;
for(int j=0;j<m;j++)
{
for(int i=local;i>=0;i--)
{
if(a[i]==b[j].id)
{
b[j].last=i;
break;
}
}
}
int minn=local,tmp=0;
for(int i=0;i<m;i++)
{
if(b[i].last<minn)
{
minn=b[i].last;
tmp=i;
}
}
b[tmp].change=true;
return tmp;
}
void change(int num)
{
for(int i=0;i<m;i++)
{
if(b[i].change==true)
{
b[i].id=num;
b[i].last=-1;
b[i].next=-1;
}
}
}
int fill()
{
for(int i=0;i<m;i++)
{
if(b[i].id==-1)
return i;
}
return -1;
}
int main()
{
while(cin>>m>>n)
{
for(int i=0;i<m;i++)
b[i].id=-1;
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
int cnt=0;
printf("OPT方法:\n");
for(int i=0;i<n;i++)
{
if(hit(a[i]))//命中
{
printf("frame为:\t");
for(int j=0;j<m;j++)
printf("%d\t",b[j]);
printf("命中\n");
cnt++;
}
else//未命中
{
int empty = fill();
if(empty==-1)
{
getnext(i);
change(a[i]);
printf("frame为:\t");
for(int j=0;j<m;j++)
printf("%d\t",b[j]);
printf("替换\n");
}
else
{
b[empty].id=a[i];
printf("frame为:\t");
for(int j=0;j<m;j++)
printf("%d\t",b[j]);
printf("调进\n");
}
}
}
printf("OPT方法:页地址流数为%d,命中次数为%d,命中率为%.3f\n\n\n",n,cnt,(double)cnt/n);
printf("LRU方法:\n");
cnt=0;
for(int i=0;i<m;i++)
b[i].id=-1;
for(int i=0;i<n;i++)
{
if(hit(a[i]))//命中
{
printf("frame为:\t");
for(int j=0;j<m;j++)
printf("%d\t",b[j]);
printf("命中\n");
cnt++;
}
else//未命中
{
int empty = fill();
if(empty==-1)
{
getnext2(i);
change(a[i]);
printf("frame为:\t");
for(int j=0;j<m;j++)
printf("%d\t",b[j]);
printf("替换\n");
}
else
{
b[empty].id=a[i];
printf("frame为:\t");
for(int j=0;j<m;j++)
printf("%d\t",b[j]);
printf("调进\n");
}
}
}
printf("LRU方法:页地址流数为%d,命中次数为%d,命中率为%.3f\n",n,cnt,(double)cnt/n);
}
}
效果图如下: