1. 程式人生 > >頁面置換演算法 1

頁面置換演算法 1

#include <stdio.h>
#include <stdlib.h>
/*全域性變數*/
int mSIZE;						//物理塊數
int pSIZE;						//頁面號引用串個數
static int memery[10]={0};		//物理塊中的頁號
static int page[100]={0};		//頁面號引用串
static int temp[100][10]={0};	//輔助陣列
/*置換演算法函式*/
void FIFO();
void LRU();
void OPT();
/*輔助函式*/
void print(unsigned int t);
/*主函式*/
void main()
{
    int i,k,code;
    printf("請輸入物理塊的個數(M<=10):");
    scanf("%d",&mSIZE);
    printf("請輸入頁面號引用串的個數(P<=100):");
    scanf("%d",&pSIZE);
    puts("請依次輸入頁面號引用串(用空格隔開):");
    for(i=0;i<pSIZE;i++)
        scanf("%1d",&page[i]);
    system("cls");
    do{ 
        puts("\n 輸入的頁面號引用串為:");
        for(k=0;k<=(pSIZE-1)/20;k++)
        {
            for(i=20*k;(i<pSIZE)&&(i<20*(k+1));i++)
            {
                if(((i+1)%20==0)||(((i+1)%20)&&(i==pSIZE-1)))
                    printf("%d\n",page[i]);
                else
                    printf("%d   ",page[i]);
            }
        }
        printf("*************************************************\n");
        printf("*\t請選擇頁面置換演算法:                    *\n");
		printf("*\t\t\t\t\t\t*\n");
		printf("*\t1.最佳置換演算法(OPT)                     *\n");
        printf("*\t2.先進先出演算法(FIFO)                    *\n");
		printf("*\t3.最近最久未使用(LRU)                   *\n");
		printf("*\t4.退出                                  *\n");
        printf("*************************************************\n");
        printf("請選擇操作:[ ]\b\b");
        scanf("%d",&code);
		printf("\n");
        switch(code)
        {
        case 1:
			OPT();
            break;
        case 2:
			FIFO();
            break;
        case 3:
			LRU();
            break;
        case 4:
            system("cls");
            exit(0);
        default:
            printf("\n輸入錯誤,請重新輸入!!!\n\n\n");
        }
    }while (code!=4);
    getchar();
}

void print(unsigned int t)
{
    int i,j,k,l;
    int flag;
    for(k=0;k<=(pSIZE-1)/20;k++)
    {
        for(i=20*k;(i<pSIZE)&&(i<20*(k+1));i++)
        {
            if(((i+1)%20==0)||(((i+1)%20)&&(i==pSIZE-1)))
                printf("%d\n",page[i]);
            else
                printf("%d   ",page[i]);
        }
        for(j=0;j<mSIZE;j++)
        {
            for(i=20*k;(i<mSIZE+20*k)&&(i<pSIZE);i++)
            {
                if(i>=j)
                    printf(" |%d|",temp[i][j]);
                else
                    printf(" | |");
            }
            for(i=mSIZE+20*k;(i<pSIZE)&&(i<20*(k+1));i++)
            {
                for(flag=0,l=0;l<mSIZE;l++)
                    if(temp[i][l]==temp[i-1][l])
                        flag++;
                if(flag==mSIZE)			//頁面在物理塊中
                    printf("    ");
                else
                    printf(" |%d|",temp[i][j]);
            }
            printf("\n");
        }
    }
    printf("\n------------------------------------------\n");
    printf("  缺頁次數:%d\t\t",t+mSIZE);
    printf("缺頁率:%d/%d\n",t+mSIZE,pSIZE);
    printf("  置換次數:%d\t\t",t);
    printf("訪問命中率:%d%%\n",(pSIZE-(t+mSIZE))*100/pSIZE);
    printf("------------------------------------------\n");    
}


/*先進先出頁面置換演算法*/
void FIFO()
{
    int memery[10]={0};
    int time[10]={0};	//記錄進入物理塊的時間
    int i,j,k,m;
    int max=0;			//記錄換出頁
    int count=0;		//記錄置換次數
    /*前mSIZE個數直接放入*/
    for(i=0;i<mSIZE;i++)
    {
        memery[i]=page[i];
        time[i]=i;
        for(j=0;j<mSIZE;j++)
            temp[i][j]=memery[j];
    }
    for(i=mSIZE;i<pSIZE;i++)
    {
        /*判斷新頁面號是否在物理塊中*/
        for(j=0,k=0;j<mSIZE;j++)
        {
            if(memery[j]!=page[i])
                k++;
        }
        if(k==mSIZE)		//如果不在物理塊中
        {
            count++;
            /*計算換出頁*/
            max=time[0]<time[1]?0:1;
            for(m=2;m<mSIZE;m++)
                if(time[m]<time[max])
                    max=m;
            memery[max]=page[i];
            time[max]=i;	//記錄該頁進入物理塊的時間
            for(j=0;j<mSIZE;j++)
                temp[i][j]=memery[j];
        }
        else
        {
            for(j=0;j<mSIZE;j++)
                temp[i][j]=memery[j];
        } 
    }
    print(count);
}

/*最近最久未使用置換演算法*/
void LRU()
{
    int memery[10]={0};
    int flag[10]={0};	//記錄頁面的訪問時間
    int i,j,k,m;
    int max=0;			//記錄換出頁
    int count=0;		//記錄置換次數
    /*前mSIZE個數直接放入*/
    for(i=0;i<mSIZE;i++)
    {
        memery[i]=page[i];
        flag[i]=i;
        for(j=0;j<mSIZE;j++)
            temp[i][j]=memery[j];
    }
    for(i=mSIZE;i<pSIZE;i++)
    {
        /*判斷新頁面號是否在物理塊中*/
        for(j=0,k=0;j<mSIZE;j++)
        {
            if(memery[j]!=page[i])
                k++;
            else 
                flag[j]=i; //重新整理該頁的訪問時間
        }
        if(k==mSIZE)		//如果不在物理塊中
        {
            count++;
            /*計算換出頁*/
            max=flag[0]<flag[1]?0:1;
            for(m=2;m<mSIZE;m++)
                if(flag[m]<flag[max])
                    max=m;
            memery[max]=page[i];
            flag[max]=i;	//記錄該頁的訪問時間
            for(j=0;j<mSIZE;j++)
                temp[i][j]=memery[j];
        }
        else
        {
            for(j=0;j<mSIZE;j++)
                temp[i][j]=memery[j];
        }
    }
    print(count);
}

/*最佳置換演算法*/
void OPT()
{
    int memery[10]={0};
    int next[10]={0};	//記錄下一次訪問時間
    int i,j,k,l,m;
    int max;			//記錄換出頁
    int count=0;		//記錄置換次數
    /*前mSIZE個數直接放入*/
    for(i=0;i<mSIZE;i++)
    {
        memery[i]=page[i];
        for(j=0;j<mSIZE;j++)
            temp[i][j]=memery[j];
    }
    for(i=mSIZE;i<pSIZE;i++)
    {
        /*判斷新頁面號是否在物理塊中*/
        for(j=0,k=0;j<mSIZE;j++)
        {
            if(memery[j]!=page[i])
                k++;
        }
        if(k==mSIZE)	//如果不在物理塊中
        {
            count++;
            /*得到物理快中各頁下一次訪問時間*/
            for(m=0;m<mSIZE;m++)
            {
                for(l=i+1;l<pSIZE;l++)
                    if(memery[m]==page[l])
                        break;
                next[m]=l;
            }
            /*計算換出頁*/
            max=next[0]>=next[1]?0:1;
            for(m=2;m<mSIZE;m++)
                if(next[m]>next[max])
                    max=m;
            /*下一次訪問時間都為pSIZE,則置換物理塊中第一個*/
            memery[max]=page[i];
            for(j=0;j<mSIZE;j++)
                temp[i][j]=memery[j];
        }
        else {
            for(j=0;j<mSIZE;j++)
                temp[i][j]=memery[j];
        }
    }
    print(count);
}