1. 程式人生 > >實驗七 儲存管理---------常用頁面置換演算法模擬實驗

實驗七 儲存管理---------常用頁面置換演算法模擬實驗

 實驗七 儲存管理---------常用頁面置換演算法模擬實驗

實驗目的
通過模擬實現請求頁式儲存管理的幾種基本頁面置換演算法,瞭解虛擬儲存技術的特點,掌握虛擬儲存請求頁式儲存管理中幾種基本頁面置換演算法的基本思想和實現過程,並比較它們的效率。

實驗內容
設計一個虛擬儲存區和記憶體工作區,並使用下述演算法計算訪問命中率。
1、最佳淘汰演算法(OPT)
2、先進先出的演算法(FIFO)
3、最近最久未使用演算法(LRU)
4、最不經常使用演算法(LFU)
5、最近未使用演算法(NUR)
命中率=1-頁面失效次數/頁地址流長度

實驗準備
本實驗的程式設計基本上按照實驗內容進行。即首先用srand( )和rand( )函式定義和產生指令序列,然後將指令序列變換成相應的頁地址流,並針對不同的演算法計算出相應的命中率。
(1)通過隨機數產生一個指令序列,共320條指令。指令的地址按下述原則生成:
A:50%的指令是順序執行的
B:25%的指令是均勻分佈在前地址部分
C:25%的指令是均勻分佈在後地址部分
具體的實施方法是:
A:在[0,319]的指令地址之間隨機選取一起點m
B:順序執行一條指令,即執行地址為m+1的指令
C:在前地址[0,m+1]中隨機選取一條指令並執行,該指令的地址為m’
D:順序執行一條指令,其地址為m’+1
E:在後地址[m’+2,319]中隨機選取一條指令並執行
F:重複步驟A-E,直到320次指令
(2)將指令序列變換為頁地址流
設:頁面大小為1K;
使用者記憶體容量4頁到32頁;
使用者虛存容量為32K。
在使用者虛存中,按每K存放10條指令排列虛存地址,即320條指令在虛存中的存放方式為:
第 0 條-第 9 條指令為第0頁(對應虛存地址為[0,9])
第10條-第19條指令為第1頁(對應虛存地址為[10,19])
………………………………
第310條-第319條指令為第31頁(對應虛存地址為[310,319])
按以上方式,使用者指令可組成32頁。

實驗指導
一、虛擬儲存系統
UNIX中,為了提高記憶體利用率,提供了內外存程序對換機制;記憶體空間的分配和回收均以頁為單位進行;一個程序只需將其一部分(段或頁)調入記憶體便可執行;還支援請求調頁的儲存管理方式。
當程序在執行中需要訪問某部分程式和資料時,發現其所在頁面不在記憶體,就立即提出請求(向CPU發出缺中斷),由系統將其所需頁面調入記憶體。這種頁面調入方式叫請求調頁。
為實現請求調頁,核心配置了四種資料結構:頁表、頁框號、訪問位、修改位、有效位、保護位等。
二、頁面置換演算法
當CPU接收到缺頁中斷訊號,中斷處理程式先儲存現場,分析中斷原因,轉入缺頁中斷處理程式。該程式通過查詢頁表,得到該頁所在外存的物理塊號。如果此時記憶體未滿,能容納新頁,則啟動磁碟I/O將所缺之頁調入記憶體,然後修改頁表。如果記憶體已滿,則須按某種置換演算法從記憶體中選出一頁準備換出,是否重新寫盤由頁表的修改位決定,然後將缺頁調入,修改頁表。利用修改後的頁表,去形成所要訪問資料的實體地址,再去訪問記憶體資料。整個頁面的調入過程對使用者是透明的。
常用的頁面置換演算法有
1、最佳置換演算法(Optimal)
2、先進先出法(Fisrt In First Out)
3、最近最久未使用(Least Recently Used)
4、最不經常使用法(Least Frequently Used)
5、最近未使用法(No Used Recently)
三、參考程式:
#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("When i==%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]和pfc[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;         /*按FIFO方式調新頁面入記憶體頁面*/
        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 page frams
FIFO: 0.7312
LRU: 0.7094
LFU: 0.5531
NUR: 0.7688
OPT: 0.9750
5 page frams
   …………
五、分析
1、從幾種演算法的命中率看,OPT最高,其次為NUR相對較高,而FIFO與LRU相差無幾,最低的是LFU。但每個頁面執行結果會有所不同。
2、OPT演算法在執行過程中可能會發生錯誤
五、思考
1、為什麼OPT在執行時會有錯誤產生?

相關推薦

實驗 儲存管理---------常用頁面置換演算法模擬實驗

 實驗七 儲存管理---------常用頁面置換演算法模擬實驗 實驗目的通過模擬實現請求頁式儲存管理的幾種基本頁面置換演算法,瞭解虛擬儲存技術的特點,掌握虛擬儲存請求頁式儲存管理中幾種基本頁面置換演算法的基本思想和實現過程,並比較它們的效率。 實驗內容設計一個虛擬儲存區和記憶

請求頁式儲存管理頁面置換演算法的java實現

        儲存管理的主要功能之一是合理地分配空間。請求頁式管理是一種常用的虛擬儲存管理技術。         模擬頁式虛擬儲存管理中硬體的地址轉換和缺頁中斷,並用先進先出排程演算法(FIFO)處理缺頁中斷。 &nb

頁面置換演算法模擬程式實現實驗報告

通過編寫本實驗,不僅理解了OS中頁面置換演算法,也鍛鍊java的awt程式設計能力,特別是佈局設計和事件響應,程式設計過程中會遇到些小問題,可以通過各種途徑解決,另外,程式設計之前要做好整體規劃,最好寫出來,把各個模組的功能和主要變數都寫成文件,這樣效率很高。程式設計是體力活, (

5.3. 虛擬儲存管理------頁面置換演算法

程序執行過程中,訪問的頁面不在記憶體,調入時記憶體已無空閒空間,需要將記憶體中的一頁程式或資料調到外存。 頁面置換演算法(page replacement algorithms):選擇換出哪些頁面的演算法,其好壞直接影響系統的效能。 應具有較低的缺頁率: &nbs

作業系統:虛擬頁式儲存管理(缺頁中斷、頁面置換演算法

1、基本工作原理 1、基本工作原理 在程序開始執行之前,不是全部裝入頁面,而是裝入一個或者零個頁面,之後根據程序執行的需要,動態裝入其他頁面;當記憶體已滿,而又需要裝入 新的頁面時,則根據某種演算法淘

作業系統實驗之記憶體頁面置換演算法實驗

vmrp.h #include <iostream> #include <iomanip> #include <malloc.h> class Replace{ public: Replace(); ~Replace(); void

作業系統-1-儲存管理之LFU頁面置換演算法(leetcode460)

LFU快取 題目:請你為 最不經常使用(LFU)快取演算法設計並實現資料結構。它應該支援以下操作:get 和 put。    get(key) - 如果鍵存在於快取中,則獲取鍵的值(總是正數),否則返回 -1。    put(key, value) - 如果鍵不存在,請

作業系統(5)虛擬儲存--頁面置換演算法:區域性置換演算法、全域性置換演算法

文章目錄 1:頁面置換演算法的相關概念 2:區域性置換演算法 1.最優、先進先出、最近最久未使用演算法 2.時鐘置換演算法和最不常用演算法 3.Belady現象和區域性置換演算法的比較 3:

作業系統- 實驗模擬FIFO頁面置換演算法(Java實現)

                                          &

c模擬 頁式管理頁面置換演算法之FIFO

寫的作業系統作業。。。。 放上來給需要的小夥伴 需要注意的地方: 1.該演算法只涉及單程序 2.只是用c模擬FIFO的思想 FIFO思想:選擇在記憶體中存活時間最久的頁面淘汰 關於該演算法我的理解: 一個程序可以分為多個頁面,頁面大小一致,每個頁面需要佔用一個相同大小的記憶體塊,在程序的頁面較多而記憶體塊較少

實驗五 虛擬記憶體頁面置換演算法

一、  需求分析 說明程式設計的任務和目的,明確規定下述內容: 加深對虛擬記憶體頁面置換概念的理解,進一步掌握先進先出FIFO、最佳置換OPI和最近最久未使用LRU頁面置換演算法的實現方法。 (1)    輸入的形式和輸入值的範圍; 輸入1-3的整數選擇演算法 已在程式中預

頁面置換演算法 2

#include<stdio.h> #include<stdlib.h> #include<windows.h> void Print(int bc[],int blockCount) { int i; for(i=0;i<blockCount;i+

頁面置換演算法 1

#include <stdio.h> #include <stdlib.h> /*全域性變數*/ int mSIZE; //物理塊數 int pSIZE; //頁面號引用串個數 static int memery[10]={0}; //物理塊中的頁號 sta

2.6 Linux儲存管理-物理頁面的使用和週轉

說明一些概念: 虛擬頁面:指虛擬空間中,一段固定大小、邊界與頁面大小對齊的區間及其內容。 物理頁面:虛擬頁面對映到的介質上,可以在記憶體上( 記憶體頁面),也可以在磁碟上( 盤上頁面)。 頁面的換進換出指的是頁面內容

2.7 Linux儲存管理-物理頁面分配

程序需要的連續的頁面,通過alloc_pages來完成 該函式在mm/numa.c和mm/page_alloc.h中都有定義 NUMA和UMA分配記憶體的函式是不併存的,根據CONFIG_DISCONTIGMEM的勾選與否選擇其中一個

作業系統之頁面置換演算法(最佳置換OPT,先進先出FIFO,最近最久未使用LRU)

最近學習作業系統時,實驗要求實現常見的三種頁面置換演算法,博主按照書上要求試著編寫,實現了案例,並記錄在部落格隨記中,以便後續自己複習並也給需要的同學分享參考一下!水平有限,若有錯,請悄悄告訴博主!博主好立即改正。 最佳置換演算法(optimal replacement,OPT)是從記憶體中選擇今後不再訪問

頁面置換演算法——最近最久未使用演算法(c語言實現)

作業系統實驗:用C語言程式設計實現最近最久未使用置換演算法(LRU) 最近最久未使用置換演算法(LRU),全稱Least Recently Used,是一種頁面置換演算法。 對於在記憶體中但又不用的資料塊(記憶體塊)叫做LRU,作業系統會根據哪些資料屬於LRU而將其移出記憶體而騰出空間來載入另外

頁面置換演算法及例題

一、頁面置換演算法 不適當的演算法可能會導致程序發生“抖動”:即剛被換出的頁很快又要被訪問,需要將他重新調入,此時又需要再選一頁調出。而此剛被調出的頁面很快又被訪問,又需將它調入,如此頻繁地更換頁面,以致一個程序在執行中把大部分時間都花費在頁面置換工作上,我們稱該程序發生了“抖動”。 一個好的頁面置換演算

作業系統頁面置換演算法 ---之---FIFO置換演算法、OPTIMAL置換算

                                 作業系統頁面置換演算法     &nbs

頁面置換演算法具體步驟

頁面置換演算法也是作業系統考試的重中之重首先要知道每種排程演算法的名稱和具體的操作過程; 名稱 特點 OPT 將未來一段時間用不到的調出 LRU