1. 程式人生 > >頁面置換演算法;最佳置換演算法、先進先出置換演算法、最近最久未使用置換演算法

頁面置換演算法;最佳置換演算法、先進先出置換演算法、最近最久未使用置換演算法

一、  實驗目的和要求

1.  瞭解虛擬儲存技術的特點。

2.  掌握請求頁式儲存管理的頁面置換演算法,如最佳(Optimal)置換演算法、先進先出(Fisrt In First Out)置換演算法和最近最久未使用(LeastRecently Used)置換演算法。

二、    實驗內容

設計模擬實現OPT、FIFO和LRU頁面置換演算法的C語言程式。

1.  OPT演算法:需要發生頁面置換時,演算法總是選擇在將來最不可能訪問的頁面進行置換。

2.  FIFO演算法:演算法總是選擇在佇列中等待時間最長的頁面進行置換。

3.  LRU演算法:如果某一個頁面被訪問了,它很可能還要被訪問;相反,如果它長時間不被訪問,那麼,在最近未來是不大可能被訪問的。

三、  實驗步驟

1.  使用C++語言編譯程式。

2.  完成演算法程式碼。

3.  執行程式,算出結果。

四、     實驗源程式

程式碼:

//’*’代表缺頁

#include <stdio.h>

#include <iostream>

#include <queue>

#include <stack>

#include <set>

#include <string>

#include <cstring>

#include <cmath>

#define MAX 1111

int mark[MAX];

using namespace std;

typedef structpage_replacement_algorithm

{

   char page;

   char interrupt;

}PRA;

char ans[MAX][MAX];

void FIFO()

{

   memset(ans,'0',sizeof(ans));

   queue<char> q;

   PRA pra[MAX];

   int n,m;

   printf("請輸入頁面走向(字元表示)和物理塊數(整型):\n");

   scanf("%d %d",&n,&m);

   getchar();

   printf("請輸入n個字元(不要有空格):\n");

   for(int i=0; i<n; i++){

       scanf("%c",&pra[i].page);

       q.push(pra[i].page);

   }

   queue<char> qq;

   int cnt = 0,tot = 0;

   for(int i=0; i<m; i++){

       qq = q;

       for(int j=0; j<=i; j++){

            ans[j][i] = qq.front();

            qq.pop();

       }

       pra[i].interrupt = '*';

   }

   q = qq;

   for(int j=m,i=0; j<n; j++,i=0){

       bool flag = true;

       while(i < m){

            ans[i][j] = ans[i][j-1];

            if(ans[i][j] == q.front()&& flag){

                q.pop();

                flag = false;

            }

            i++;

       }

       if(flag){

            pra[j].interrupt = '*';

            for(int r=0; r<m-1; r++)

                ans[r][j] = ans[r+1][j];

           ans[m-1][j] = q.front();

            q.pop();

       }

       else{

            pra[j].interrupt = ' ';

       }

   }

   printf("\n先進先出置換演算法:\n");

   printf("%8s:","頁面走向");

   for(int r=0; r<n; r++) printf("%3c ",pra[r].page);

   printf("\n");

   for(int i=0; i<m; i++){

       printf("%6s%2d:","物理塊",i+1);

       for(int j=0; j<n; j++) printf("%3c ",ans[i][j]);

   printf("\n");

   }

   printf("%8s:","缺頁中斷");

   for(int r=0; r<n; r++) printf("%3c ",pra[r].interrupt);

   printf("\n");

}

void LRU()

{

   memset(ans,'0',sizeof(ans));

   PRA pra[MAX];

   int n,m;

   printf("請輸入頁面走向(字元表示)和物理塊數(整型):\n");

   scanf("%d %d",&n,&m);

   getchar();

   printf("請輸入n個字元(不要有空格):\n");

   for(int i=0; i<n; i++) scanf("%c",&pra[i].page);

   for(int i=0; i<m; i++){

       for(int j=0; j<=i; j++){

            ans[j][i] = pra[j].page;

       }

       pra[i].interrupt = '*';

   }

   for(int i=m; i<n; i++){

       bool flag = true;

       for(int j=0; j<m; j++){

            ans[j][i] = ans[j][i-1];

            if(ans[j][i] == pra[i].page){

                pra[i].interrupt = ' ';

                flag = false;

            }

       }

       if(flag){

            pra[i].interrupt = '*';

           for(int j=0; j<m; j++);

                if(ans[j][i] == pra[i-m].page){

                    ans[j][i] = pra[i].page;

                    break;

                }

            }

       }

   }

   printf("最近最久未使用置換演算法:\n");

   printf("%8s:","頁面走向");

   for(int r=0; r<n; r++) printf("%3c ",pra[r].page);

   printf("\n");

   for(int i=0; i<m; i++){

       printf("%6s%2d:","物理塊",i+1);

       for(int j=0; j<n; j++) printf("%3c ",ans[i][j]);

   printf("\n");

   }

   printf("%8s:","缺頁中斷");

   for(int r=0; r<n; r++) printf("%3c ",pra[r].interrupt);

   printf("\n");

}

void OPT()

{

   memset(ans,'0',sizeof(ans));

   memset(mark,0,sizeof(mark));

   PRA pra[MAX];

   int n,m;

   printf("請輸入頁面走向(字元表示)和物理塊數(整型):\n");

   scanf("%d %d",&n,&m);

   getchar();

   printf("請輸入n個字元(不要有空格):\n");

   for(int i=0; i<n; i++) scanf("%c",&pra[i].page);

   for(int i=0; i<m; i++){

       for(int j=0; j<=i; j++){

            ans[j][i] = pra[j].page;

       }

       pra[i].interrupt = '*';

   }

   for(int i=m; i<n; i++){

       bool flag = true;

       for(int j=0; j<m; j++){

            ans[j][i] = ans[j][i-1];

            if(ans[j][i] == pra[i].page){

                pra[i].interrupt = ' ';

                flag = false;

            }

       }

       int im;

       bool Goto = true;

       int tot = 0;

       if(flag){

            pra[i].interrupt = '*';

           for(int t=i; t<n;t++){

                for(int j=0; j<m; j++){

                    if(ans[j][i] == pra[t].page&& !mark[pra[i].page]){

                        mark[pra[i].page] = 1;

                        tot++;

                        if(tot == 3){

                            ans[j][i] =pra[i].page;

                            Goto = false;

                            break;

                        }

                    }

                    else if(ans[j][i] !=pra[t].page) im = j;

                }

                if(!Goto) break;

            }

            if(tot<3) ans[im][i] =pra[i].page;

       }

   }

   printf("\n最佳置換演算法:\n");

   printf("%8s:","頁面走向");

   for(int r=0; r<n; r++) printf("%3c ",pra[r].page);

   printf("\n");

   for(int i=0; i<m; i++){

       printf("%6s%2d:","物理塊",i+1);

       for(int j=0; j<n; j++) printf("%3c ",ans[i][j]);

   printf("\n");

   }

   printf("%8s:","缺頁中斷");

   for(int r=0; r<n; r++) printf("%3c ",pra[r].interrupt);

   printf("\n");

}

int main()

{

   printf("*********************************************************************歡迎您!*********************************************************************\n");

   int ca = 0;

   do{

       printf("\n請選擇置換演算法或結束程式:\n");

       printf("0、結束程式\n1、最佳置換\n2、先進先出\n3、最近最久未使用\n");

       scanf("%d",&ca);

       if(ca == 1) OPT();

       if(ca == 2) FIFO();

       if(ca == 3) LRU();

   }while(ca);

   return 0;

}

五、  實驗結果

最佳置換演算法:

先進先出置換演算法:

 

最近未使用置換演算法: