操作系统课设之虚拟内存页面置换算法的模拟与实现
前言
課程設計開始了,實驗很有意思,寫博客總結學到的知識
白嫖容易,創作不易,學到東西才是真
本文原創,創作不易,轉載請注明!!!
本文鏈接
個人博客:https://ronglin.fun/archives/181
PDF鏈接:見博客網站
CSDN: https://blog.csdn.net/RongLin02/article/details/118309055
為了美觀,實驗源代碼在結尾處,整合版見下
鏈接:https://pan.baidu.com/s/1rXj1QJGuw-BVc5sQWret9w
提取碼:Lin2
操作系統課程設計源代碼
本次操作系統課程設計合集
操作系統課設之Windows 進程管理
操作系統課設之Linux 進程管理
操作系統課設之Linux 進程間通信
操作系統課設之Windows 的互斥與同步
操作系統課設之內存管理
操作系統課設之虛擬內存頁面置換算法的模擬與實現
操作系統課設之基于信號量機制的并發程序設計
操作系統課設之簡單 shell 命令行解釋器的設計與實現
僅用于學習,如有侵權,請聯系我刪除
實驗題目
虛擬內存頁面置換算法的模擬與實現
實驗目的
通過對頁面、頁表、地址轉換和頁面置換過程的模擬,加深對虛擬頁式內存管理系統的頁面置換原理和實現過程的理解。
總體設計
背景知識:
需要調入新頁面時,選擇內存中哪個物理頁面被置換,稱為置換策略。頁面置換算法的目標:
把未來不再使用的或短期內較少使用的頁面調出,通常應在局部性原理指導下依據過去的統計數據進行預測,減少缺頁次數。
本次模擬的頁面置換算法有:
1)最佳置換算法(OPT):置換時淘汰“未來不再使用的”或“在離當前最遠位置上出現的”頁面。
2)先進先出置換算法(FIFO):置換時淘汰最先進入內存的頁面,即選擇駐留在內存時間最長的頁面被置換。
3)最近最久未用置換算法(LRU):置換時淘汰最近一段時間最久沒有使用的頁面,即選擇上次
同時為了兼顧程序的局部性原理,要通過隨機數產生一個指令序列
① 50%的指令是順序執行的;
② 25%的指令是均勻分布在前地址部分;
③ 25%的指令是均勻分布在后地址部分; 這樣生成的指令序列是隨機且有局部性
模塊設計:
本次代碼設計一共包括三大部分,第一大部分就是數據結構的設計,頁框、指令的數據類型等;第二大部分是指令序列的生成,要根據題目要求生成一個體現局部性原理的隨機數列;第三大部分就是要模擬實現OPT,FIFO,LRU算法。
詳細設計
第一部分 數據結構:
頁框的數據結構
struct MemoryCell {int index;//頁號int time;//時間戳 };因為要兼顧3種算法,尤其是LRU,增加了一個時間戳,所以頁框數據類型最后確定如上
int commds[COMMD_NUM]; //存放的是每一條指令的頁號commds存放的是這一條指令對應的頁號
MemoryCell memory[MEM_PAHE_NUM]; //內存塊memory就是內存了,也就是分配給一作業的內存塊,按照本題目就是大小是4個頁框。
vector<int> order_commd;這個存放的是按照題目需求生成的隨機指令序列
vector<int> order_page;這個存放的是按照指令序列轉化而成的頁號序列。
第二部分 指令序列的生成
先上需求:
通過隨機數產生一個指令序列,共 320 條指令。
① 50%的指令是順序執行的;
② 25%的指令是均勻分布在前地址部分;
③ 25%的指令是均勻分布在后地址部分;
具體的實施方法是:
① 在[0, 319]的指令地址之間隨機選取一起點 m;
② 順序執行一條指令,即執行地址為 m+1 的指令;
③ 在前地址[0, m+1]中隨機選取一條指令并執行,該指令的地址為 m1;
④ 順序執行一條指令,其地址為 m1+1;32
⑤ 在后地址[m1+2, 319]中隨機選取一條指令并執行;
⑥ 重復上述步驟①~⑤,直到執行 320 條指令。
這是指導書給的實現方法
實際代碼實現時,還要注意邊界問題,就是m + 1的時候會不會超過319,需要特判,其余按照題目所說直接實現。最后將指令序列再轉化為頁號序列就行了
核心代碼如下:
第三部分 置換算法的實現
FIFO
最簡單的就是FIFO的實現
如果頁框沒滿(不足4個)就直接按順序排下來,如果滿了,就將第一份踢出,然后將新頁號插到尾部,因為用的數組,替換就用的是后一個覆蓋前一個,如果是鏈表的數據結構的話,就直接修改指針就行了。
核心代碼:
LRU
然后就是LRU的模擬
LRU的實現也簡單,只需要一直更新時間戳就行了,如果內存沒滿,就直接插入尾部,如果內存滿了,就找出時間戳最早的,然后把它覆蓋就行了。時間戳我實現的是用的頁號的順序數組下標索引,就是0-319,置換的時候將最小的換出去就行了。
核心代碼:
OPT
最后是OPT模擬
OPT是最佳適配算法,置換時淘汰“未來不再使用的”或“在離當前最遠位置上出現的”頁面。由于實際中是不可能提前知道未來所需的頁號,所以也只是理論上的最優算法。我的實現思路是每次置換出現最遠的。
如果內存沒滿,就按照順序直接插入尾部,如果內存頁框滿了,就置換,置換的時候依次掃描頁框中的頁號,看它在頁號序列中下一次出現的位置,用一個數組記錄下來,數組初始化的時候,賦最大值,意義是如果掃描的時候沒找到下一次出現,則距離最大。將內存4個頁框都找完之后,選擇其中“下一次出現最遠的”一個,置換掉就行了。
源碼參考:
實驗結果與分析
五次結果如上,很有意思的結果,FIFO和LRU的缺頁情況相差不大,也有幾次兩者缺頁率相同,甚至偶爾FIFO的缺頁率低于LRU。
仔細分析代碼,應該不是代碼邏輯錯誤,我想可能還是指令數量太少,頁框比較小,我幾次調大內存頁框數和指令數,確實有所改善,當然OPT的缺頁率永遠是最低的,也有一部分指導意義。
小結與心得體會
在學習操作系統的時候,我也曾用C模擬過這幾個算法,主要模擬的是FIFO,LRU和Clock算法,不用當時的結果更加離譜,多次改變數據之后仍不符合預期,后來和同學老師討論之后得出的結論是我的頁號序列沒有體現程序局部性,我用Python生成了1百萬個隨機數到文件中,然后C程序讀取文件測試,最后不論如何測試幾種算法的缺頁率都很相近。這次用指導書上的方法生成的頁號序列比較有參考意義的,結果比較符合預期,尤其是LRU算法,本實驗收獲很多。=w=
源代碼
#include <iostream> #include <cstdio> #include <time.h> #include <cstdlib> #include <vector>#define MEM_PAHE_NUM 4 #define COMMD_NUM 320 #define PAGE_COMMD 10 #define MAX_FAR 1000000000using namespace std;struct MemoryCell {int index;//頁號int time;//時間戳 };int commds[COMMD_NUM]; //存放的是每一條指令的頁號 MemoryCell memory[MEM_PAHE_NUM]; //內存塊 vector<int> order_commd; vector<int> order_page;void initPage(); //初始化頁表 void createArray(); //生成序列 double FIFO(); //用FIFO置換算法 double LRU(); //用LRU置換算法 double OPT(); //用OPT置換算法int main() {initPage();createArray();double fifo = FIFO();double lru = LRU();double opt = OPT();printf("fifo = %f lru = %f opt = %f\n",fifo,lru,opt);return 0; }void initPage() {//現在開始給每個頁分配指令int page_index=0;for(int i=0;i<COMMD_NUM;i++){commds[i]=page_index;if((i+1) % PAGE_COMMD ==0){page_index++;}}// for(int i=0;i<COMMD_NUM;i++) // { // printf("%d ",commds[i]); // if((i+1) % PAGE_COMMD ==0) // { // printf("\n"); // } // } }void createArray() {srand((unsigned)time(NULL));int commd = 0;while(commd < COMMD_NUM){//范圍是[0,319]int m = rand()%COMMD_NUM;order_commd.push_back(m);commd++;if(commd >= COMMD_NUM)break;if(m == COMMD_NUM-1)continue;order_commd.push_back(m+1);commd++;if(commd >= COMMD_NUM)break;//范圍是[0,m+1]m = rand()% (m+2);order_commd.push_back(m);commd++;if(commd >= COMMD_NUM)break;if(m == COMMD_NUM-1)continue;order_commd.push_back(m+1);commd++;if(commd >= COMMD_NUM)break;//范圍是[m+2,319]m = rand()% (COMMD_NUM -m -2) + m+2;order_commd.push_back(m);commd++;if(commd >= COMMD_NUM)break;}//將指令序列轉化為頁號序列for(int i=0;i<order_commd.size();i++){order_page.push_back(commds[order_commd[i]]);}// printf("order_commd_size = %d\n",order_commd.size()); // for(int i=0;i<order_commd.size();i++) // { // printf("%d ",order_commd[i]); // }// printf("order_page_size = %d\n",order_page.size()); // for(int i=0;i<order_page.size();i++) // { // printf("%d ",order_page[i]); // } }double FIFO() {int memory_page_num = 0;int err = 0;for(int i=0;i<order_page.size();i++){bool flag =0;for(int j=0;j<memory_page_num;j++){if(memory[j].index == order_page[i]){flag = true;break;}}if(!flag) //沒找到,發生缺頁{err++;if(memory_page_num < MEM_PAHE_NUM){memory[memory_page_num++].index = order_page[i];}else //利用置換算法開始置換{for(int j=1;j<memory_page_num;j++){memory[j-1] = memory[j];//將第一個置換出去}memory[memory_page_num-1].index=order_page[i];}}for(int j=0;j<memory_page_num;j++){printf("%d",memory[j].index);(memory[j].index == order_page[i])?printf("* "):printf(" ");}if(!flag) printf("F");printf("\n");}printf("FIFO err =%d\n",err);return (double)err / COMMD_NUM; }double LRU() {int memory_page_num = 0;int err = 0;for(int i=0;i<order_page.size();i++){bool flag =0;for(int j=0;j<memory_page_num;j++){if(memory[j].index == order_page[i]){flag = true;memory[j].time = i; //更新時間戳break;}}if(!flag) //沒找到,發生缺頁{int minn=0;//標記最小的err++;if(memory_page_num < MEM_PAHE_NUM){memory[memory_page_num].time = i; //留下時間戳memory[memory_page_num++].index = order_page[i];}else //利用置換算法開始置換{for(int j=0;j<memory_page_num;j++){if(memory[minn].time > memory[j].time){minn = j;}}memory[minn].time = i;memory[minn].index = order_page[i];}}for(int j=0;j<memory_page_num;j++){printf("%d",memory[j].index);(memory[j].index == order_page[i])?printf("* "):printf(" ");}if(!flag) printf("F");printf("\n");}printf("LRU err =%d\n",err);return (double)err / COMMD_NUM; }double OPT() {int memory_page_num = 0;int err = 0;for(int i=0;i<order_page.size();i++){bool flag =0;for(int j=0;j<memory_page_num;j++){if(memory[j].index == order_page[i]){flag = true;break;}}if(!flag) //沒找到,發生缺頁{err++;if(memory_page_num < MEM_PAHE_NUM){memory[memory_page_num++].index = order_page[i];}else //利用置換算法開始置換{int far[MEM_PAHE_NUM] ;//存儲距離int furthest = 0;//找最遠的位置;for(int j=0;j<MEM_PAHE_NUM;j++) //初始化為最大值far[j] = MAX_FAR;for(int j=0;j<memory_page_num;j++){for(int k=i+1;k<order_page.size();k++){if(memory[j].index == order_page[k]) //未來出現的位置far[j] = k;}}for(int j=0;j<memory_page_num;j++) //找最遠的位置if(far[furthest] < far[j])furthest = j;//找到之后,置換memory[furthest].index = order_page[i];}}for(int j=0;j<memory_page_num;j++){printf("%d",memory[j].index);(memory[j].index == order_page[i])?printf("* "):printf(" ");}if(!flag) printf("F");printf("\n");}printf("OPT err =%d\n",err);return (double)err / COMMD_NUM; }總結
以上是生活随笔為你收集整理的操作系统课设之虚拟内存页面置换算法的模拟与实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 魅蓝3 官方android系统,魅蓝3获
- 下一篇: RTX5 | 消息队列03 - 获取消息