作業系統實驗七之記憶體頁面置換演算法實驗
阿新 • • 發佈:2019-02-01
vmrp.h #include <iostream> #include <iomanip> #include <malloc.h> class Replace{ public: Replace(); ~Replace(); void InitSpace(char * MethodName); //初始化頁號記錄 void Report(void); // 報告演算法執行情況 void Fifo(void); //先進先出演算法 void Lru(void); //最近最舊未用演算法 void Clock(void); //時鐘(二次機會)置換演算法 void Eclock(void); //增強二次機會置換演算法 void Lfu(void); //最不經常使用置換演算法 void Mfu(void); //最經常使用置換演算法 private: int * ReferencePage ; //存放要訪問到的頁號 int * EliminatePage ; //存放淘汰頁號 int * PageFrames ;//存放當前正在實存中的頁號 int PageNumber;//訪問頁數 int FrameNumber;//實存幀數 int FaultNumber;//失敗頁數 int *Referencebit; int *count; int *Modifybit; };
請在以上實驗程式中補充演算法的模擬程式。
輸入不同的
記憶體頁面引用串和實存幀數,觀察並分析其頁面置換效果和效能,並將其與 LRU 和
FIFO 演算法進行比較。
改進以上示例實驗程式,
使之能夠隨機的產生記憶體頁面引用串,
以便能動態的觀測各種置換演算法的效能。
#include "vmrp.h" Replace::Replace() { int i; //設定總得訪問頁數,並分配相應的引用頁號和淘汰頁號記錄陣列空間 cout << "Please input page numbers :" ; cin >> PageNumber;//存放要訪問到的頁號 ReferencePage = new int[sizeof(int) * PageNumber];//訪問頁數 EliminatePage = new int[sizeof(int) * PageNumber];//存放淘汰頁號 cout << "Please input reference page string :"; for (i = 0; i < PageNumber; i++) cin >> ReferencePage[i]; cout << "Please input page frames :"; cin >> FrameNumber;//實存幀數 PageFrames = new int[sizeof(int) * FrameNumber];//存放當前正在實存中的頁號 Referencebit=new int[sizeof(int) * FrameNumber];//引用位 count=new int[sizeof(int)*FrameNumber]; Modifybit=new int[sizeof(int)*FrameNumber];//修改位 } Replace::~Replace() { } void Replace::InitSpace(char * MethodName) { int i; cout << endl << MethodName << endl; FaultNumber=0;//失敗頁數 //引用還未開始,-1表示無引用頁 for (i = 0; i < PageNumber; i++) EliminatePage[i] = -1;//淘汰頁號初始都設為-1 for(i = 0; i < FrameNumber; i++) { PageFrames[i] = -1;//存放當前正在實存中的頁號 Referencebit[i]=0;//未被使用引用位設定為0 count[i]=0;//計數 Modifybit[i]=0;//修改位初始為0 } } //分析統計選擇的演算法對於當前輸入的頁面走向的效能 void Replace::Report(void) { //報告淘汰頁順序 cout << endl << "Eliminate page:"; for(int i=0; EliminatePage[i]!=-1; i++) cout << EliminatePage[i] << " "; //報告缺頁數和缺頁率 cout << endl << "Number of page faults = " << FaultNumber << endl; cout << setw(6) << setprecision(3) ; cout << "Rate of page faults = " << 100*(float)FaultNumber/(float)PageNumber << "%"<<endl; } //最近最舊未用置換演算法 void Replace::Lru(void) { int i,j,k,l,next; InitSpace("LRU");//初始化頁號記錄 //迴圈裝入引用頁 for(k=0,l=0; k < PageNumber; k++) //l為淘汰頁的標記 { next=ReferencePage[k]; //檢測引用頁當前是否已在實存 for (i=0; i<FrameNumber; i++) { if(next == PageFrames[i]) //與當前正在實存中的頁號比較 { //引用頁已在實存將其調整到頁記錄棧頂 next= PageFrames[i]; for(j=i; j>0; j--) PageFrames[j] = PageFrames[j-1]; PageFrames[0]=next; break; } } if(PageFrames[0] == next) { //如果引用頁已放棧頂,則為不缺頁,報告當前記憶體頁號 for(j=0; j<FrameNumber; j++) if(PageFrames[j]>=0) cout << PageFrames[j] << " "; cout << endl; continue; //繼續裝入下一頁 } else // 如果引用頁還未放棧頂,則為缺頁,缺頁數加1 FaultNumber++; //棧底頁號記入淘汰頁陣列中 EliminatePage[l] = PageFrames[FrameNumber-1]; //向下壓棧 for(j=FrameNumber-1; j>0; j--) PageFrames[j]= PageFrames[j-1]; PageFrames[0]=next; //引用頁放棧頂 //報告當前實存中頁號 for(j=0; j<FrameNumber; j++) if(PageFrames[j]>=0) cout << PageFrames[j] << " "; //報告當前淘汰的頁號 if(EliminatePage[l]>=0) cout << "->" << EliminatePage[l++] << endl; else cout << endl; } //分析統計選擇的演算法對於當前引用的頁面走向的效能 Report(); } //先進先出置換演算法 void Replace::Fifo(void) { int i,j,k,l,next; InitSpace("FIFO"); //迴圈裝入引用頁 for(k=0,j=l=0; k < PageNumber; k++) { next=ReferencePage[k]; //如果引用頁已在實存中,報告實存頁號 for (i=0; i<FrameNumber; i++) if(next==PageFrames[i]) break; if (i<FrameNumber) { for(i=0; i<FrameNumber; i++) cout << PageFrames[i] << " "; cout << endl; continue;// 繼續引用下一頁 } //引用頁不在實存中,缺頁數加1 FaultNumber++; //最先入頁號記入淘汰頁陣列 EliminatePage[l]= PageFrames[j]; PageFrames[j]=next;//引用頁號放最先入頁號處 j = (j+1)%FrameNumber;//最先入頁號迴圈下移 //報告當前實存頁號和淘汰頁號 for(i=0; i<FrameNumber; i++) if(PageFrames[i]>=0) cout << PageFrames[i] << " "; if(EliminatePage[l]>=0) cout << "->" << EliminatePage[l++] << endl; else cout << endl; } Report(); } //時鐘(二次機會)置換演算法 void Replace::Clock(void) { int j,i,k,l,next; InitSpace("Clock"); for(k=0,j=l=0; k < PageNumber; k++) { next=ReferencePage[k]; for (i=0; i<FrameNumber; i++) //檢測引用頁當前是否已在實存 if(next==PageFrames[i]) { Referencebit[i]=1;//引用位設定為1 break; } if (i<FrameNumber) { for(i=0; i<FrameNumber; i++) cout << PageFrames[i] << " "; cout << endl; continue; } if(Referencebit[j]==1) //如果引用位為1 { Referencebit[j]==0;//在判斷之後,重新設定成0 } EliminatePage[l]=PageFrames[j];//最先入頁號記入淘汰頁陣列 PageFrames[j]=next; //引用頁號放最先入頁號處 Referencebit[j]=1;//引用位設定為1 FaultNumber++;//缺頁數加1 j=(j+1)%FrameNumber;//最先入頁號迴圈下移 for(i=0; i<FrameNumber; i++) if(PageFrames[i]>=0) cout << PageFrames[i] << " "; if(EliminatePage[l]>=0) cout << "->" << EliminatePage[l++] << endl; else cout << endl; } Report(); } //增強二次機會置換演算法 void Replace::Eclock (void) { int j,i,k,l,next; InitSpace("EClock"); for(k=0,j=l=0; k < PageNumber; k++) { next=ReferencePage[k]; //迴圈裝入引用頁 for (i=0; i<FrameNumber; i++) //檢測引用頁當前是否已在實存 if(next==PageFrames[i]) { Referencebit[i]=1;//引用位設定為1 count[i]++; //如果被引用了兩次,就把修改位設定成1 if(count[i]%2==0) Modifybit[i]=0;//修改位設定為0 else Modifybit[i]=1; break; } if (i<FrameNumber) { for(i=0; i<FrameNumber; i++) cout << PageFrames[i] << " "; cout << endl; continue; } if(Referencebit[j]==1) { Referencebit[j]==0; } if(Modifybit[j]==1) { Modifybit[j]=0; } int min=10*Referencebit[j]+Modifybit[j]; int index=j; for(i=0; i<FrameNumber; i++) { if(10*Referencebit[i]+Modifybit[i]<min) { min=10*Referencebit[i]+Modifybit[i]; index=i; } } EliminatePage[l]=PageFrames[index]; PageFrames[index]=next; Referencebit[index]=0; Modifybit[index]=1; count[index]=0; FaultNumber++;//引用頁不在實存中,缺頁數加1 j=(j+1)%FrameNumber;//最先入頁號迴圈下移 for(i=0; i<FrameNumber; i++) if(PageFrames[i]>=0) cout << PageFrames[i] << " "; if(EliminatePage[l]>=0) cout << "->" << EliminatePage[l++] << endl; else cout << endl; } Report(); } //最不經常使用置換演算法 void Replace::Lfu(void) { int j,i,k,l,next; InitSpace("Lfu"); for(k=0,j=l=0; k < PageNumber; k++) { next=ReferencePage[k]; for (i=0; i<FrameNumber; i++) if(next==PageFrames[i]) { count[i]++;//記錄使用次數 break; } if (i<FrameNumber) { for(i=0; i<FrameNumber; i++) cout << PageFrames[i] << " "; cout << endl; continue; } FaultNumber++; int min=count[0]; int index=0; for(i=0; i<FrameNumber; i++) { if(count[i]<min) { min=count[i]; index=i; } } EliminatePage[l]= PageFrames[index];//最不經常使用的頁號記入淘汰頁陣列 PageFrames[index]=next; count[index]=1; for(i=0; i<FrameNumber; i++) if(PageFrames[i]>=0) cout << PageFrames[i] << " "; if(EliminatePage[l]>=0) cout << "->" << EliminatePage[l++] << endl; else cout << endl; } Report(); } //最經常使用置換演算法 void Replace::Mfu(void) { int j,i,k,l,next; InitSpace("Mfu"); for(i=0; i<FrameNumber; i++) count[i]=1; for(k=0,j=l=0; k < PageNumber; k++) { next=ReferencePage[k]; for (i=0; i<FrameNumber; i++) if(next==PageFrames[i]) { count[i]++; break; } if (i<FrameNumber) { for(i=0; i<FrameNumber; i++) cout << PageFrames[i] << " "; cout << endl; continue; } FaultNumber++; int max=count[0]; int index=0; for(i=0; i<FrameNumber; i++) { if(count[i]>max) { max=count[i]; index=i; } } EliminatePage[l]= PageFrames[index]; PageFrames[index]=next; count[index]=0; for(i=0; i<FrameNumber; i++) if(PageFrames[i]>=0) cout << PageFrames[i] << " "; if(EliminatePage[l]>=0) cout << "->" << EliminatePage[l++] << endl; else cout << endl; } Report(); } int main(int argc,char *argv[]) { Replace * vmpr = new Replace(); vmpr->Lru(); vmpr->Fifo(); vmpr->Clock(); vmpr->Eclock(); vmpr->Lfu(); vmpr->Mfu(); return 0; }
makefile
head = vmrp.h
srcs = vmrp.cc
objs = vmrp.o
opts = -w -g -c
all: vmrp
vmrp: $(objs)
g++ $(objs) -o vmrp
vmrp.o: $(srcs) $(head)
g++ $(opts) $(srcs)
clean:
rm vmrp *.o