頁面置換算法總結

頁面置換算法

百度百科對頁面置換算法給出的定義:在地址映射過程中,若在頁面中發現所要訪問的頁面不在內存中,則產生缺頁中斷。當發生缺頁中斷時,如果操作系統內存中沒有空閒頁面,則操作系統必須在內存選擇一個頁面將其移出內存,以便爲即將調入的頁面讓出空間。而用來選擇淘汰哪一頁的規則叫做頁面置換算法。

(1)OPT頁面置換算法(最佳頁面置換算法)
這是一種理想情況下的頁面置換算法,但實際上是不可能實現的。該算法的基本思想是:發生缺頁時,有些頁面在內存中,其中有一頁將很快被訪問(也包含緊接着的下一條指令的那頁),而其他頁面則可能要到10、100或者1000條指令後纔會被訪問,每個頁面都可以用在該頁面首次被訪問前所要執行的指令數進行標記。最佳頁面置換算法只是簡單地規定:標記最大的頁應該被置換。這個算法唯一的一個問題就是它無法實現。當缺頁發生時,操作系統無法知道各個頁面下一次是在什麼時候被訪問。雖然這個算法不可能實現,但是最佳頁面置換算法可以用於對可實現算法的性能進行衡量比較。
(2)FIFO頁面置換算法(先進先出頁面置換算法)
FIFO淘汰算法總是淘汰最先進入內存的頁面,即選擇在內存中駐留時間最久的頁面進行淘汰。該算法實現只需把一個進程已調入內存的頁面,按訪問的時間先後順序鏈接成一個隊列,並設置一個指針,該指針始終指向“最老“的頁面。

問題:隨機一訪問串和駐留集的大小,通過模擬程序顯示淘汰的頁號並統計命中率。示例:

輸入訪問串:7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 

駐留集大小:3

7  0  1  2  0  3  0  4  2  3  0  3  2  1  2  0  1 

7  7  7  2  2  2 2  4  4 4  0  0  0  0 0 0 0

    0  0  0 0  3  3 3  2  2  2 2  1  1  1  1

        1  1  1  1  0  0  0  3  3  3  3  3  2  2  2

         7     0 1  2  3  0  4         2  3

紅色表示:指針指向調入內存的頁面中“最老“的頁面

通過模擬程序輸出淘汰的頁號分別爲:7 0 1 2 3 0 4 2 3

命中率爲:5/13

注意:內存的頁面中“最老“的頁面,會被新的網頁直接覆蓋,而不是“最老“的頁面先出隊,然後新的網頁從隊尾入隊。

#include <stdio.h>
#include <string.h>
#include <malloc.h>
int len;
typedef struct Queue
{
    int  * pBase;
    int front;//隊列頭
    int rear;//隊列尾
}QUEUE;

void init(QUEUE *pQ)
{
    int N = len+1;
    pQ->pBase = (int *)malloc(sizeof(int ) * N);//N爲數組長度
    //初始化爲0
    pQ->front = 0;
    pQ->rear = 0;
}

int full_queue(QUEUE *pQ)
{
    int N = len+1;
    if((pQ->rear +1)%N == pQ->front)//循環隊列
        return 1;
    else
        return 0;
}

int en_queue(QUEUE *pQ, int val)//入隊前判斷隊列是否已滿
{
    int N = len+1;
    if( full_queue(pQ) )
    {
        return 0;
    }
    else
    {
        pQ->pBase[pQ->rear] = val;//壓棧在隊尾
        pQ->rear = (pQ->rear+1) % N;
        return 1;
    }
}

int empty_queue(QUEUE *pQ)
{
    int N = len+1;
    if(pQ->front == pQ->rear)
            return 1;
    else
            return 0;
}

int out_queue(QUEUE *pQ, int *pVal)//出隊前判斷隊列是否爲空
{
    int N = len+1;
    if(empty_queue(pQ))
    {
        return 0;
    }
    else
    {
        *pVal = pQ->pBase[pQ->front];//把出隊的元素保存起來
        pQ->front = (pQ->front+1)%N;
        return 1;
    }
}

int same_queue(QUEUE *pQ, int x)
{
    int N = len+1;
    int i = pQ->front;
    while( i != pQ->rear)
    {
        if( pQ->pBase[i] == x)
            return 1;
        i = (i+1) % N;
    }
    return 0;
}

int main()
{
    int cnt = 0;//記沒命中次數
    int i, val, data;
    char str[1000];

    scanf("%d", &len);//駐留集大小
    scanf("%s", str);

    QUEUE Q;
    init (&Q);

    for(i=0; str[i] != '\0'; i++)
    {
        if(str[i]  >= '0' && str[i] <= '9')
        {
            val= str[i] - '0';
            if( !full_queue(&Q) && !(same_queue(&Q, val)))
            {
                 en_queue(&Q, val);
                 cnt++;
            }
            else if( full_queue(&Q) && !(same_queue(&Q, val)) )
            {
                out_queue(&Q, &data);
                printf("%d ",data);
                en_queue(&Q, val);
                cnt++;
            }
        }
    }
    printf("\n%d/%d", strlen(str)- cnt, strlen(str));
    return 0;
}
(3)LRU頁面置換算法(最近未使用頁面置換算法)
LRU(Least Currently Used):FIFO總是優先淘汰那些進入內存早的頁面,它根據最早進入時間來選擇刪除某個頁面;而恰恰相反,LRU優先淘汰那些經常不使用的頁面,它根據最近進入時間來保留某個頁面。

問題:隨機一訪問串和駐留集的大小,通過模擬程序顯示淘汰的頁號並統計命中率。示例:

輸入訪問串:7 0 1 2 0 3 0 4 2 3 0 3 2

駐留集大小:3

算法的實現:由於LRU算法淘汰的是上次使用距離t時刻最遠的頁,故需記錄這個距離。

計數器:可使用計數器,給每一個頁幀增設一個計數器。每訪問一頁,就把對應頁幀的計數器清零,其餘頁幀的計數器加1.因此,計數器值爲最大的頁即上次訪問距當前最遠的頁。

7    0   1    2    0   3    0    4    2    3    0   3    2    

0/7 1/7  2/7  0/2    1/2  2/2  3/2  0/4  1/4   2/4    0/0   1/0 2/0

      0/0 1/0 2/0    0/0 1/0    0/0  1/0  2/0   0/3  1/3   0/3 1/3

             0/1 1/1    2/1  0/3    1/3  2/3  0/2  1/2   2/2   3/2 0/2

缺  缺   缺   缺     命     缺    命   缺   缺     缺    缺    命   命

紅色表示:每個頁幀對應的計數器值

通過模擬程序輸出淘汰的頁號分別爲:7 1 2 3 0 4

命中率爲:4/13

LRU的另一種通俗理解:

例如一個三道程序,等待進入的是1,2,3,4,4,2,5,6,3,4,2,1。先分別把1,2,3導入,然後導入4,置換的是1,因爲他離導入時間最遠。然後又是4,不需要置換,然後是2,也不需要,因爲內存中有,到5的時候,因爲3最遠,所以置換3,依次類推


#include <stdio.h>
#include <string.h>
#include <malloc.h>
int len;

typedef struct LRU
{
    int data;
    int time;//計次數
} LRU;

typedef struct Queue
{
    LRU *pBase;//結構數組
    int front;//隊列頭
    int rear;//隊列尾
}QUEUE;

void init(QUEUE *pQ)
{
    int N = len+1;
    pQ->pBase = (LRU*)malloc(sizeof(LRU ) * N);
    pQ->front = pQ->rear = 0;  //初始化爲0
}

int full_queue(QUEUE *pQ)
{
    int N = len+1;
    if((pQ->rear +1)%N == pQ->front)//循環隊列
        return 1;
    else
        return 0;
}

int en_queue(QUEUE *pQ, int val)//入隊前判斷隊列是否已滿
{
    int N = len+1;
    if( full_queue(pQ) )
    {
        return 0;
    }
    else
    {
        pQ->pBase[pQ->rear].data = val;//壓棧在隊尾
        pQ->pBase[pQ->rear].time = 0;//初始化次數爲0
        pQ->rear = (pQ->rear+1) % N;
        return 1;
    }
}

int empty_queue(QUEUE *pQ)//1-->空   0-->非空
{
    int N = len+1;
    if(pQ->front == pQ->rear)
            return 1;
    else
            return 0;
}

int out_queue(QUEUE *pQ, int *pVal)//出隊前判斷隊列是否爲空
{
    int N = len+1;
    if(empty_queue(pQ))
    {
        return 0;
    }
    else
    {
        *pVal = pQ->pBase[pQ->front].data;//把出隊的元素保存起來
        pQ->front = (pQ->front+1)%N;
        return 1;
    }
}

void add_time(QUEUE *pQ)
{
    int N = len+1;
    int i = pQ->front;
    while( i != pQ->rear)
    {
        pQ->pBase[i].time ++;
        i = (i + 1) % N;
        //printf("%d  %d", pQ->pBase[i].time, i);
    }
}

void Set_time_shot(QUEUE *pQ, int x)//若待入隊元素與隊中元素相同,將次數置爲0
{
    int N = len + 1;
    int i = pQ->front;
    while( i != pQ->rear)
    {
        if( pQ->pBase[i].data == x)
        {
            pQ->pBase[i].time = 0;
        }
        i = (i+1) % N;
    }
}

int Find_big_time(QUEUE *pQ)
{
    int N = len + 1;
    int i = pQ->front;
    int max_i = i;
    int max_time = pQ->pBase[pQ->front].time;
    while( i != pQ->rear)
    {
        if( pQ->pBase[i].time > max_time)
        {
            max_i = i; max_time = pQ->pBase[i].time;
        }
        i = (i+1) % N;
    }
    return max_i;
}

void Replace_big_time(QUEUE *pQ, int x)//若待入隊元素與隊中元素不相同,替換元素,並將次數置爲0
{
    int max_time = Find_big_time(pQ);
    printf("%d ", pQ->pBase[max_time].data);
    pQ->pBase[max_time].data = x;
    pQ->pBase[max_time].time = 0;
}

int same_queue(QUEUE *pQ, int x)//判斷待入隊元素是否與隊中元素相同
{
    int N = len+1;
    int i = pQ->front;
    while( i != pQ->rear)
    {
        if( pQ->pBase[i].data == x)
            return 1;
        i = (i+1) % N;
    }
    return 0;
}

int main(void)
{
    char str[100];
    int val, data;
    int i, cnt = 0;
    scanf("%d", &len);
    scanf("%s", str);

    QUEUE Q;
    init(&Q);
    for(i=0; str[i] != '\0'; i++)
    {
        val = str[i] - '0';
        if ( empty_queue( &Q ) )//如果隊列爲空
        {
            en_queue(&Q, val);
        }
        else
        {
                add_time(&Q);
                if(full_queue(&Q))//如果隊列已滿
                {
                        if( !same_queue(&Q, val))
                        {
                            Replace_big_time(&Q, val);
                        }
                        else
                        {
                            Set_time_shot(&Q, val);
                            cnt++;
                        }
                  }
                 else//如果隊列沒滿也不爲空
                  {
                        if( !same_queue(&Q, val))
                        {
                            en_queue(&Q, val);
                        }
                        else
                        {
                            Set_time_shot(&Q, val);
                            cnt++;
                        }
                  }
            }
    }
    printf("\n%d/%d", cnt, strlen(str));
    return 0;
}

注意:雖然兩個算法都是用隊列這種數據結構實現的,但具體操作不完全遵從隊列的原則。這一點不必糾結。
命中率是指在隊滿的情況下,新的元素的加入,不影響隊列其它元素。即該元素已存在在隊列中。
(4)LFU頁面置換算法(最少使用頁面排序算法)
LFU(Least Frequently Used):內存內使用越頻繁的頁面,被保留的時間也相對越長。

問題:
哈爾濱工業大學2000年考研操作系統真題操作系統考研輔導教程87頁一請求分頁存儲系統,進程P共有5頁,訪問串爲3,2,1,0,3,2,4,3,2,1,0,4,試採用LRU算法和LFU算法分析,當分配頁面數爲3時,發生的缺頁中斷次數。
解:
least frequently used (LFU),要求在頁置換時置換引用計數最小的頁。
	3,2,1
	0進入時,缺頁。置換最近最小的1。內存:3,2,0
	3,2
	4進入時,缺頁。置換最近最小的0。內存:3,2,4
	3,2
	1進入時,缺頁。置換最近最小的4。內存:3,2,1
	0進入時,缺頁。置換最近最小的1。內存:3,2,0
	4進入時,缺頁。置換最近最小的0。內存:3,2,4


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章