首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

FIFO 跟 LRU 页面置换算法

2013-09-05 
FIFO 和 LRU 页面置换算法FIFO页面置换算法问题:随机一访问串和驻留集的大小,通过模拟程序显示淘汰的页号

FIFO 和 LRU 页面置换算法

FIFO页面置换算法

问题:随机一访问串和驻留集的大小,通过模拟程序显示淘汰的页号并统计命中率。示例:

输入访问串:7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 

驻留集大小:3

算法的实现:FIFO淘汰算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面进行淘汰。该算法实现只需把一个进程已调入内存的页面,按访问的时间先后顺序链接成一个队列,并设置一个指针,该指针始终指向“最老“的页面。

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 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;}

 

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

代码:

#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;}

 

 总结:

虽然两个算法都是用队列这种数据结构实现的,但具体操作不完全遵从队列的原则。这一点不必纠结。

命中率是指在队满的情况下,新的元素的加入,不影响队列其它元素。即该元素已存在在队列中。

热点排行