在之前系列的博客中介紹了頁面調度算法的原理:
https://www.cnblogs.com/wkfvawl/p/11700301.html#_label2_3
這里編寫代碼模擬一些頁面調度算法的實現。
(1)最佳淘汰算法——OPT(Optimal)
這是Belady貝萊迪於1966年提出的一種理論上的算法。該算法每次都淘汰以后
永不使用的,或者過最長的時間后才會被訪問的頁面。顯然,采用這種算法會保證最低的缺頁率,但它是無法實現的,因為它必須知道頁面“將來”的訪問情況。不過,該算法仍有一定意義,可作為衡量其他算法優劣的一個標准。
(2)先進先出淘汰算法——FIFO
這是最早出現的淘汰算法。
總是淘汰最先進入內存的頁面。它實現簡單,只需把進程中已調入內存的頁面,按先后次序鏈成一個隊列,並設置一個所謂的替換指針,使它總是指向內存中最老的頁面。
(3) 最近最久未使用算法——(LRU, Least Recently Used)
根據頁面調入內存后的使用情況,選擇內存中最久未使用的頁面被置換。這是局部性原理的合理近似,性能接近最佳算法。
OPT算法使用頁面將要被訪問的時間,LRU算法使用頁面最后一次被訪問的時間。二者唯一的差別是:OPT是向前看的,而LRU是向后看的。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int N;//進程虛頁數 int M;//內存塊個數 int page[100];//進程虛頁 int block[100];//內存塊 int weight[100];//當前內存塊在后面出現的次數 int success;//命中次數 int fail;//未命中次數 void FIFO() { int i,j; int flag; int pos=0; int success=0; int fail=0; for(i=0; i<N; i++) { flag =0; for(j=1; j<=M; j++) { if(page[i]==block[j])//命中 { flag=1; success++; pos--; break; } } if(flag==0) { fail++; block[pos%M+1]=page[i]; } pos++; for(j=1; j<=M; j++) { printf("%d ",block[j]); } printf("\n"); } printf("命中次數為:%d\n",success); printf("未命中次數為:%d\n",fail); } void OPT() { int i,j,k; int flag; int success=0; int fail=0; int needReplace; for(i=0; i<N; i++) { flag=0; for(j=1; j<=M; j++) { if(page[i]==block[j])//命中 { flag=1; success++; } } if(flag==0)//未命中 { fail++; for(j=1; j<=M; j++) //若內存塊未滿,先將內存塊填滿 { if(block[j]==0) { block[j]=page[i]; break; } } int minCnt=100; memset(weight,0,sizeof(weight)); if(j>M)//若內存塊已滿,需要進行調度 { for(k=i+1; k<N; k++) //向后 { for(j=1; j<=M; j++) { if(block[j]==page[k]) { weight[j]=N-k;//越靠近,權值越大 break; } } } for(j=1; j<=M; j++) //找權值最小的那一個 { if(weight[j]<=minCnt) { minCnt=weight[j]; needReplace=j; } } block[needReplace]=page[i];//替換掉權值最小的 } } for(j=1; j<=M; j++) { printf("%d ",block[j]); } printf("\n"); } printf("命中次數為:%d\n",success); printf("未命中次數為:%d\n",fail); } void LRU() { int i,j; int flag; int success=0; int fail=0; int needReplace; for(i=0; i<N; i++) { flag=0; for(j=1; j<=M; j++) { if(page[i]==block[j])//命中 { flag=1; success++; } } if(flag==0)//未命中 { fail++; for(j=1; j<=M; j++) //現將內存塊填滿 { if(block[j]==0) { block[j]=page[i]; break; } } if(j>M)//內存塊已滿,需要進行調度 { //向前找,需要替換的頁面為i-M needReplace=page[i-M]; for(j=1; j<=M; j++) { if(block[j]==needReplace)//找到后替換掉 { block[j]=page[i]; break; } } } } for(j=1; j<=M; j++) { printf("%d ",block[j]); } printf("\n"); } printf("命中次數為:%d\n",success); printf("未命中次數為:%d\n",fail); } int main() { printf("請輸入進程執行時頁面訪問個數:\n"); scanf("%d",&N); printf("請輸入空閑內存塊的個數:\n"); scanf("%d",&M); printf("請輸入進程執行時頁面訪問次序:\n"); memset(page,0,sizeof(page)); memset(block,0,sizeof(block)); int i; int needReplace; for(i=0; i<N; i++) { scanf("%d",&page[i]); } printf("采用最佳淘汰算法OPT:\n"); OPT(); memset(block,0,sizeof(block)); printf("采用先進先出淘汰算法FIFO:\n"); FIFO(); memset(block,0,sizeof(block)); printf("采用最近最久未使用淘汰算法LRU:\n"); LRU(); return 0; } /* 12 3 2 3 2 1 5 2 4 5 3 2 5 2 */