虚拟分页存储管理

#define TRUE 1
#define FALSE 0
#define INVALID -1
#define  NULL    0
#define  total_instruction    320          /*指令流长*/
#define  total_vp    32                              /*虚页长*/
#define    clear_period    50                      /*清0周期*/
typedef struct                      /*页面结构*/
{
        int  pn,pfn,counter,time;
}pl_type;
pl_type  pl[total_vp];                              /*页面结构数组*/
struct pfc_struct{                  /*页面控制结构*/
        int  pn,pfn;
        struct  pfc_struct  *next;
};
typedef struct pfc_struct pfc_type;
pfc_type pfc[total_vp],*freepf_head,*busypf_head,*busypf_tail;
int  diseffect,    a[total_instruction];
int page[total_instruction],offset[total_instruction];
int    initialize(int);
int    FIFO(int);
int    LRU(int);
int    LFU(int);
int    NUR(int);
int    OPT(int);
int main( )
{
    int  s,i,j;
    srand(10*getpid());              /*由于每次运行时进程号不同,故可用来作为初始化随机数队列的"种子"*/
    s=(float)319*rand(  )/32767/32767/2+1;
    for(i=0;i<total_instruction;i+=4)  /*产生指令队列*/
    {
        if(s<0||s>319)
        {
            printf("Wheni==%d,Error,s==%d\n",i,s);
            exit(0);
        }
        a[i]=s;                            /*任选一指令访问点m*/
        a[i+1]=a[i]+1;                     /*顺序执行一条指令*/
        a[i+2]=(float)a[i]*rand( )/32767/32767/2; /*执行前地址指令m' */
        a[i+3]=a[i+2]+1;                   /*顺序执行一条指令*/
        s=(float)(318-a[i+2])*rand( )/32767/32767/2+a[i+2]+2;
        if((a[i+2]>318)||(s>319))
        printf("a[%d+2],a number which is :%d and s==%d\n",i,a[i+2],s);
}
for (i=0;i<total_instruction;i++) /*将指令序列变换成页地址流*/
{
    page[i]=a[i]/10;
    offset[i]=a[i]%10;
}
for(i=4;i<=32;i++)      /*用户内存工作区从4个页面到32个页面*/
{
    printf("---%2d  page  frames---\n",i);
    FIFO(i);
    LRU(i);
    LFU(i);
    NUR(i);
    OPT(i);
}
      return  0;
}
int initialize(total_pf)              /*初始化相关数据结构*/
int total_pf;                          /*用户进程的内存页面数*/
{
    int i;
    diseffect=0;
    for(i=0;i<total_vp;i++)
    {
        pl[i].pn=i;
        pl[i].pfn=INVALID;        /*置页面控制结构中的页号,页面为空*/
        pl[i].counter=0;
        pl[i].time=-1;         /*页面控制结构中的访问次数为0,时间为-1*/
    }
    for(i=0;i<total_pf-1;i++)
    {
        pfc[i].next=&pfc[i+1];
        pfc[i].pfn=i;
}      /*建立pfc[i-1]篬【i]之间的链接*/
pfc[total_pf-1].next=NULL;
pfc[total_pf-1].pfn=total_pf-1;
freepf_head=&pfc[0];                  /*空页面队列的头指针为pfc[0]*/
return 0;
}
int FIFO(total_pf)              /*先进先出算法*/
int total_pf;                    /*用户进程的内存页面数*/
{
int  i,j;
    pfc_type  *p;
    initialize(total_pf);         /*初始化相关页面控制用数据结构*/
    busypf_head=busypf_tail=NULL;  /*忙页面队列头,队列尾链接*/
    for(i=0;i<total_instruction;i++)
    {
        if(pl[page[i]].pfn==INVALID)      /*页面失效*/
        {
            diseffect+=1;                  /*失效次数*/
            if(freepf_head==NULL)         /*无空闲页面*/
            {
                  p=busypf_head->next;
                  pl[busypf_head->pn].pfn=INVALID;
                  freepf_head=busypf_head;    /*释放忙页面队列的第一个页面*/
                  freepf_head->next=NULL;
                  busypf_head=p;
            }
        p=freepf_head->next;         /*按FIF方式调新页面入内存页面*/
        freepf_head->next=NULL;
        freepf_head->pn=page[i];
        pl[page[i]].pfn=freepf_head->pfn;
        if(busypf_tail==NULL)
                busypf_head=busypf_tail=freepf_head;
        else
        {
            busypf_tail->next=freepf_head;    /*free页面减少一个*/
            busypf_tail=freepf_head;
        }
        freepf_head=p;
     }
}
printf("FIFO:%6.4f\n",1-(float)diseffect/320);
return 0;
}
int LRU (total_pf)       /*最近最久未使用算法*/
int total_pf;
{
    int  min,minj,i,j,present_time;
    initialize(total_pf);
    present_time=0;
    for(i=0;i<total_instruction;i++)
    {
        if(pl[page[i]].pfn==INVALID)                          /*页面失效*/
        {
            diseffect++;
            if(freepf_head==NULL)              /*无空闲页面*/
            {

                min=32767;
                for(j=0;j<total_vp;j++){                        /*找出time的最小值*/
                    if(min>pl[j].time&&pl[j].pfn!=INVALID)
                    {
                        min=pl[j].time;
                        minj=j;
                    }
                }
                freepf_head=&pfc[pl[minj].pfn];   //腾出一个单元
                pl[minj].pfn=INVALID;
                pl[minj].time=-1;
                freepf_head->next=NULL;
        }
        pl[page[i]].pfn=freepf_head->pfn;      //有空闲页面,改为有效
        pl[page[i]].time=present_time;
        freepf_head=freepf_head->next;            //减少一个free页面
     }
     else
     pl[page[i]].time=present_time;        //命中则增加该单元的访问次数
     present_time++;
}
printf("LRU:%6.4f\n",1-(float)diseffect/320);
return 0;
}
int NUR(total_pf)                  /*最近未使用算法*/
int    total_pf;
{
    int i,j,dp,cont_flag,old_dp;
    pfc_type *t;
    initialize(total_pf);
    dp=0;
    for(i=0;i<total_instruction;i++)
    {
        if (pl[page[i]].pfn==INVALID)         /*页面失效*/
        {   diseffect++;
            if(freepf_head==NULL)               /*无空闲页面*/
            {
                cont_flag=TRUE;
                old_dp=dp;
                while(cont_flag)
                    if(pl[dp].counter==0&&pl[dp].pfn!=INVALID)
                        cont_flag=FALSE;
                    else
                    {
                        dp++;
                        if(dp==total_vp)
                            dp=0;
                        if(dp==old_dp)
                            for(j=0;j<total_vp;j++)
                              pl[j].counter=0;
                    }
                freepf_head=&pfc[pl[dp].pfn];
                pl[dp].pfn=INVALID;
                freepf_head->next=NULL;
            }
            pl[page[i]].pfn=freepf_head->pfn;
            freepf_head=freepf_head->next;
      }
      else
          pl[page[i]].counter=1;
          if(i%clear_period==0)
            for(j=0;j<total_vp;j++)
                pl[j].counter=0;
}
printf("NUR:%6.4f\n",1-(float)diseffect/320);
return 0;
}
int  OPT(total_pf)              /*最佳置换算法*/
int total_pf;
{
    int i,j, max,maxpage,d,dist[total_vp];
    pfc_type *t;
    initialize(total_pf);
    for(i=0;i<total_instruction;i++)
    {               //printf("In OPT for 1,i=%d\n",i);
                //i=86;i=176;206;250;220,221;192,193,194;258;274,275,276,277,278;
        if(pl[page[i]].pfn==INVALID)            /*页面失效*/
        {
            diseffect++;
            if(freepf_head==NULL)         /*无空闲页面*/
            {
                for(j=0;j<total_vp;j++)
                    if(pl[j].pfn!=INVALID)  dist[j]=32767;    /*最大距离" */
                    else dist[j]=0;
                d=1;
                for(j=i+1;j<total_instruction;j++)
                {
                    if(pl[page[j]].pfn!=INVALID)
                        dist[page[j]]=d;
                    d++;
                }
                max=-1;
                for(j=0;j<total_vp;j++)
                    if(max<dist[j])
                    {
                        max=dist[j];
                        maxpage=j;
                    }
                    freepf_head=&pfc[pl[maxpage].pfn];
                    freepf_head->next=NULL;
                    pl[maxpage].pfn=INVALID;
                }
                pl[page[i]].pfn=freepf_head->pfn;
                freepf_head=freepf_head->next;
            }
    }
    printf("OPT:%6.4f\n",1-(float)diseffect/320);
    return 0;
}
int    LFU(total_pf)                /*最不经常使用置换法*/
int total_pf;
{
    int  i,j,min,minpage;
    pfc_type  *t;
    initialize(total_pf);
    for(i=0;i<total_instruction;i++)
    {
        if(pl[page[i]].pfn==INVALID)            /*页面失效*/
        {
            diseffect++;
            if(freepf_head==NULL)          /*无空闲页面*/
            {
                min=32767;
                for(j=0;j<total_vp;j++)
                {
                    if(min>pl[j].counter&&pl[j].pfn!=INVALID)
                    {
                        min=pl[j].counter;
                        minpage=j;
                    }
                    pl[j].counter=0;
                }
                freepf_head=&pfc[pl[minpage].pfn];
                pl[minpage].pfn=INVALID;
                freepf_head->next=NULL;
            }
            pl[page[i]].pfn=freepf_head->pfn;      //有空闲页面,改为有效
            pl[page[i]].counter++;
            freepf_head=freepf_head->next;            //减少一个free页面
        }
        else
            pl[page[i]].counter++;
      }
      printf("LFU:%6.4f\n",1-(float)diseffect/320);
      return 0;
}




  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的虚拟分页存储管理的代码示例: ```c++ #include <iostream> #include <vector> #include <algorithm> using namespace std; struct Page { int id; bool in_memory; Page(int i) : id(i), in_memory(false) {} }; class PagingManager { private: vector<Page> pages; int memory_size; int page_faults; public: PagingManager(int num_pages, int mem_size) : memory_size(mem_size), page_faults(0) { for (int i = 0; i < num_pages; i++) { pages.push_back(Page(i)); } } void access_page(int page_id) { auto page = find_if(pages.begin(), pages.end(), [page_id](const Page& p) { return p.id == page_id; }); if (page == pages.end()) { cout << "Page " << page_id << " is invalid." << endl; return; } if (page->in_memory) { cout << "Page " << page_id << " is already in memory." << endl; return; } if (count_if(pages.begin(), pages.end(), [](const Page& p) { return p.in_memory; }) < memory_size) { page->in_memory = true; cout << "Page " << page_id << " is loaded into memory." << endl; } else { auto victim = find_if(pages.begin(), pages.end(), [](const Page& p) { return p.in_memory; }); victim->in_memory = false; page->in_memory = true; cout << "Page " << page_id << " is loaded into memory, replacing page " << victim->id << "." << endl; page_faults++; } } int get_page_faults() const { return page_faults; } }; int main() { PagingManager pm(10, 3); pm.access_page(1); pm.access_page(2); pm.access_page(3); pm.access_page(4); pm.access_page(5); pm.access_page(6); pm.access_page(7); pm.access_page(8); pm.access_page(9); pm.access_page(10); pm.access_page(11); pm.access_page(9); pm.access_page(5); cout << "Number of page faults: " << pm.get_page_faults() << endl; return 0; } ``` 在此示例中, `Page` 结构表示一个页面,包含其唯一标识符和一个指示它是否当前在内存中的标志。 `PagingManager` 类负责管理所有页面,并模拟访问页面的行为。它跟踪内存中当前页面的数量(由 `memory_size` 属性指定)以及页面错误的数量。 `access_page` 方法接受一个页面 ID,并尝试将该页面加载到内存中。如果页面 ID 无效,则什么也不发生。如果页面已经在内存中,则打印一条消息并返回。否则,如果内存中的页面数少于 `memory_size`,则将页面加载到内存中,并打印一条消息。否则,将选择一个“牺牲”页面(即当前在内存中的页面之一),将其换出,并将新页面加载到内存中。在这种情况下,打印一条消息并增加页面错误计数器。 在此示例中,我们构造了一个 `PagingManager` 对象,其中包含 10 个页面和一个内存大小为 3。然后我们依次访问每个页面,以模拟一些页面访问。请注意,第 11 个页面是无效的,因此不会发生任何事情。我们还试图多次访问一些页面,以测试页面是否正确地保留在内存中。最后,我们输出页面错误计数器的值。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值