Chinaunix首页 | 论坛 | 博客
  • 博客访问: 246693
  • 博文数量: 5
  • 博客积分: 1410
  • 博客等级: 上尉
  • 技术积分: 363
  • 用 户 组: 普通用户
  • 注册时间: 2007-06-04 00:21
文章分类

全部博文(5)

文章存档

2009年(1)

2008年(4)

我的朋友

分类:

2008-12-22 21:39:08

实验名称

使用LRU方法更新Cache

 

实验目的

了解和掌握寄存器分配和内存分配的有关技术

 

实验内容

结合数据结构的相关知识,使用LRU的策略,对一组访问序列进行内部的Cache更新

 

问题描述与分析

最近最久未使用(LRU)置换算法,是根据页面调入内存后的使用情况进行决策的。

由于无法预测各页面将来的使用情况,只能利用“最近的过去”作为“最近的将来”的近似,因此,LRU置换算法是选择最近最久未使用的页面予以淘汰。

该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间t,,当须淘汰一个页面时,选择现有页面中其t值最大的,即最近最久未使用的页面予以淘汰。

 

函数说明

 

typedef struct node{

    int id;

    struct node *next;

}page_node;   

/* 页面逻辑结构,结构为方便算法实现设计*/

int page_id_status[MAX_ID];  

 /*该数组为状态数组,用于说明作业的某一页是否在内存中*/

int page_id[NUM]={0,1,7,2,3,2,17,1,0,3,0,3,0,3,0,10};  

/*作业页号数组*/

page_node *initialize(int total);     /*初始化内存单元、缓冲区*/

void LRU(page_node *head);    

 /*LRU算法,用到一个链表,表头为work_head指针指向内存中最久未被访问过的页面,表尾为work_tail指针指向内存中最近被访问过的页面*/

main();                            /*主函数*/ 

重要算法解释

   void LRU(page_node *head)   /*LRU算法,用到一个链表,表头为work_head指针指向内存中最久未被访问过的页面,表尾为work_tail指针指向内存中最近被访问过的页面*/

  {   page_node *phead,*work_head=NULL,*work_tail,*prenode;

      int i,diseffect=0;  

      for(i=0;i

if(page_id_status[page_id[i]]==0)  /*如果第page_id[i]页不在内存则发生页面中断*/

{  if(head!=NULL)           /*内存空间已全部被占用,要求换出一页,即从work_head表头取出一页换出*/

                {  phead=head->next;                

                   head->next=NULL;

                   head->id=page_id[i];                

                   head=phead;

                }

else                 /*内存空间还有部分未被使用,可直接将页面放入,即放在work_head链表尾部即work_tail*/

           diseffect++;

           page_id_status[page_id[i]]=1;

         }

else                  /*如果第page_id[i]页在内存则调整页面顺序,最近被访问的页面调到链表尾部*/

          {  phead=work_head;       

          phead=work_head;

          while(phead->id!=page_id[i])

                 {

             prenode=phead;

                    phead=phead->next;

                 }

             if(phead==work_head)

                   work_head=work_head->next;

          else if(phead==work_tail)

            work_tail=prenode;

             else

                   prenode->next=phead->next;

             phead->next=NULL;

             work_tail->next=phead;

             work_tail=work_tail->next;

          }

          printf("LRU: %d",diseffect);  /*输出页面中断次数*/

   }

 

八、使用说明

编译后,按提示输入页架数与访问序列,回车;运行后,将看到输出结果即页面置换与装入情况。

如此显然要花费较大的系统开销(包括时间和空间上的),这也是实际系统中不直接采用LRU算法作为页面置换算法的直接原因,但由于其在页面置换的优越性,实际系统常使用LRU的近似算法。

 

调试报告

调试时出错情况有三类:

低级错误。编写时字母写错,‘}’或‘;’丢失,等;

警告错误。使用指针错误,或定义的指针没有使用等;

匹配错误。在编译子程序时出现类型不匹配,以及一些语法错误等。

 

程序执行是稳定的,高效的。在LRU算法中,要找出最近最久未使用的页面的话,就必须设置有关的访问记录项,且每一次访问这些记录项,页面都必须更新这些记录项。这个记录项在此程序中为。

 

十、程序清单

#include

#define NUM 16   /*页序列总长*/

#define MAX_ID 18   /*作业的总页数+1,即序列中出现的最大页号+1,为开page_id_status[MAX_ID]数组所用*/

typedef struct node{

    int id;

    struct node *next;

    }page_node;

int page_id_status[MAX_ID];    /*该数组为状态数组,用于说明作业的某一页是否在内存中*/

int page_id[NUM]={0,1,7,2,3,2,17,1,0,3,0,3,0,3,0,10};   /*作业页号数组*/

page_node *initialize(int total)     /*初始化*/

  {page_node *head=NULL,*node,*pnode;

   int i;

   for(i=0;i

      page_id_status[i]=0;  /*0指明作业第t页不在内存中*/

   for(i=1;i<=total;i++)    /*total指明在内存中总共可以装入total*/

       {node=(page_node *)malloc(sizeof(page_node));

        if(head==NULL)

         {head=node;

          pnode=node;

         }

        else

         {pnode->next=node;

          pnode=pnode->next;

         }

       }

   return head;   /*head为模拟内存为作业开辟的内存空间的链表的头指针*/

  }

void LRU(page_node *head)   /*LRU算法,用到一个链表,表头为work_head指针指向内存中最久未被访问过的页面,表尾为work_tail指针指向内存中最近被访问过的页面*/

  {page_node *phead,*work_head=NULL,*work_tail,*prenode;

   int i,diseffect=0;  

   for(i=0;i

       if(page_id_status[page_id[i]]==0)  /*如果第page_id[i]页不在内存则发生页面中断*/

         {if(head!=NULL)  /*内存空间已全部被占用,要求换出一页,即从work_head表头取出一页换出*/

              {phead=head->next;                

               head->next=NULL;

               head->id=page_id[i];               

               if(work_head==NULL)

                 {work_head=head;                  

                  work_tail=head;

                 }

               else

                 {work_tail->next=head;                  

                  work_tail=work_tail->next;

                 }

               head=phead;

              }

          else   /*内存空间还有部分未被使用,可直接将页面放入,即放在work_head链表尾部即work_tail*/

              { head=work_head;    

               work_head=work_head->next;

                 head->next=NULL;

               page_id_status[head->id]=0;

               head->id=page_id[i];

               work_tail->next=head;

               work_tail=work_tail->next;

                 head=NULL;     

              }

          diseffect++;

          page_id_status[page_id[i]]=1;

         }

       else  /*如果第page_id[i]页在内存则调整页面顺序,最近被访问的页面调到链表尾部*/

         {phead=work_head;       

           phead=work_head;

           while(phead->id!=page_id[i])

              {

                 prenode=phead;

               phead=phead->next;

              }

          if(phead==work_head)

               work_head=work_head->next;

           else if(phead==work_tail)

                 work_tail=prenode;

          else

               prenode->next=phead->next;

          phead->next=NULL;

          work_tail->next=phead;

          work_tail=work_tail->next;

         }

       printf("LRU: %d",diseffect);  /*输出页面中断次数*/

  }

main()

{ int i,j;

  page_node *head,*node;

  for(i=4;i<=7;i++)

    {   

         head=initialize(i);

        printf("\n %d page frames:",i);

        LRU(head);

        do{

           node=head;

           head=head->next;

           node->next=NULL;

           free(node);

          }while(head!=NULL);

    }

}

 

阅读(2941) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~