JAVA 頁面置換先進先出演算法(FIFO)
設計四:頁面置換
設計目的:
加深對請求頁式儲存管理實現原理的理解,掌握頁面置換演算法。
設計內容:
設計一個程式,有一個虛擬儲存區和記憶體工作區,實現下述三種演算法中的任意兩種,計算訪問命中率(命中率=1-頁面失效次數/頁地址流長度)。附加要求:能夠顯示頁面置換過程。
演算法包括:先進先出的演算法(FIFO)、最少使用演算法(LFU)、最近未使用演算法(NUR)
該系統頁地址流長度為320,頁面失效次數為每次訪問相應指令時,該指令對應的頁不在記憶體的次數。
程式首先用srand()和rand()函式分別進行初始化、隨機數定義和產生指令序列,然後將指令序列變換成相應的頁地址流,並針對不同的演算法計算出相應的命中率。
通過隨機數產生一個指令序列。共320條指令,指令的地址按下述原則生成:
(1)50%的指令是順序執行的。
(2)25%的指令是均勻分佈在前地址部分。
(3)25%的指令是均勻分佈在後地址部分。
具體的實施方法如下:
在【0,319】的指令地址之間隨機選取一起點m。
順序執行一條指令,即執行地址為m+1的指令。
在前地址【0,m+1】中隨機選取一條指令並執行,該指令的地址為m’。
順序執行一條指令,其地址為m’+1。
在後地址【m’+2,319】中隨機選取一條指令並執行。
重複步驟(1)-(5),直到320次指令。
將指令序列變換為頁地址流。
設:
頁面大小為1KB。
使用者記憶體容量4頁到32頁。
使用者虛存容量為32KB。
在使用者虛存中,按每K存放10條指令虛存地址,即320條指令在虛存中的存放方式為:
第0條~9條指令為第0頁(對應虛存地址為【0,9】)。
第10條~19條指令為第1頁(對應虛存地址為【10,19】)。
……
第310條~319條指令為第31頁(對應虛擬地址為【310,319】)。
按以上方式,使用者指令可組成32頁。
計算每種演算法在不同記憶體容量下的命中率。
import java.util.Random; public class Hello { public static void main(String[] args){ int order=320; //指令數 int [] c=new int[order]; //地址訪問順序 int [] b=new int[order]; //頁面訪問順序 int memory=16; //記憶體容量 int lose=0; //頁面失效次數 double hit_rate=0; //命中率 int i,j,k; int count1=0; int count2=0; int m1,m2,m3; Random rand = new Random(); ///////////////////////////////////////////////////////////////////////////////////////// System.out.println("產生的隨機數為:"); for(i=0;;i++){ m1=rand.nextInt(320); //在0--319之間隨機產生一個數 c[count1]=m1+1; System.out.print(c[count1]+" "); count1++; count2++; if(count1==order) break; if(count2==32){ System.out.print("\n"); count2=0; } m2=rand.nextInt(m1+1); //在0--m1+1之間隨機產生一個數 c[count1]=m2+1; System.out.print(c[count1]+" "); count1++; count2++; if(count1==order) break; if(count2==32){ System.out.print("\n"); count2=0; } m3=rand.nextInt(320-m2-2)+m2+2; //在m2+2--319之間隨機產生一個數 c[count1]=m3+1; System.out.print(c[count1]+" "); count1++; count2++; if(count1==order) break; if(count2==32){ System.out.print("\n"); count2=0; } } System.out.print("\n"); /////////////////////////////////////////////////////////////////////////////////////// System.out.println("訪問頁面的順序為:"); count2=0; for(i=0;i<order;i++){ b[i]=c[i]/10; System.out.print(b[i]+" "); count2++; if(count2==32){ System.out.print("\n"); count2=0; } } System.out.print("\n"); /////////////////////////////////////////////////////////////////////////////////////// // for(memory=4;memory<=32;memory++){ System.out.println("頁面進入記憶體的步驟為:"); Queue queue=new Queue(); for(i=0;i<order;i++){ if((queue.L-queue.F)==memory){ //如果記憶體滿了,就淘汰最早進入記憶體的頁面,否則直接進入記憶體 for(j=queue.F;j<queue.L;j++){ if(b[i]==queue.a[j]) break; } if(j==queue.L){ //如果沒有命中,先進去的頁面就先出來 lose++; queue.out(); queue.come(b[i]); } } else{ for(j=queue.F;j<queue.L;j++){ if(b[i]==queue.a[j]) break; } if(j==queue.L){ //如果沒有命中,頁面進入記憶體 lose++; queue.come(b[i]); } } for(k=queue.F;k<queue.L;k++) System.out.print(queue.a[k]+" "); System.out.print("\n"); } ///////////////////////////////////////////////////////////////////////////////////////// System.out.println("頁面失效次數為:"+lose); hit_rate=1-(lose/320.0); System.out.println("命中率="+hit_rate); lose=0; hit_rate=0; // } } } class Queue{ //佇列 int a[]=new int[10000]; int F=0; int L=0; void come(int num){ if(L>=999) System.out.println("隊滿"); a[L]=num; L++; } void out(){ if(F>L) System.out.println("隊空"); F++; } int isexit() { if(L>F) return 1; else return 0; } void exchange(int i){ int t; t=a[F];a[F]=a[i];a[i]=t; } }