操作系统 页面替换算法LRU与OPT的实现

操作系统中讲到的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);

    }

}

效果图如下:

猜你喜欢

转载自blog.csdn.net/hrbust_cxl/article/details/90904139