最近最久未使用(LRU)頁面置換演算法 C語言實現
廣東工業大學 作業系統實驗
實驗內容
假設每個頁面中可存放10條指令,分配給作業的記憶體塊數為4。用C語言模擬一個作業的執行過程,該作業共有320條指令,即它的地址空間為32頁,目前它的所有頁都還未調入記憶體。在模擬過程中,如果所訪問的指令已在記憶體,則顯示其實體地址,並轉下一條指令。如果所訪問的指令還未裝入記憶體,則發生缺頁,此時需記錄缺頁的次數,並將相應頁調入記憶體。如果4個記憶體塊均已裝入該作業,則需進行頁面置換,最後顯示其實體地址,並轉下一條指令。在所有320指令執行完畢後,請計算並顯示作業執行過程中發生的缺頁率。
置換演算法:採用最近最久未使用(LRU)頁面置換演算法。
通過隨機數產生一個指令序列,共320條指令:
1)指令的地址按下述原則生成:
① 50%的指令是順序執行的;
② 25%的指令是均勻分佈在前地址部分;
③ 25%的指令是均勻分佈在後地址部分;
具體的實施方法是:
① 在[0,319]的指令地址之間隨機選取一起點m;
② 順序執行一條指令,即執行序號為m+1的指令;
③ 在前地址[0,m-1]中隨機選取一條指令並執行,該指令的序號為m1;
④ 順序執行一條指令,其序號為m1+1的指令;
⑤ 在後地址[m1+2,319]中隨機選取一條指令並執行,該指令的序號為m2;
⑥ 順序執行一條指令,其序號為m2+1的指令;
重複上述步驟①~⑥,直到執行320次指令。
2)將指令序列變換為頁地址流
設頁面大小為1K, 使用者虛存容量為32K。在使用者虛存中,按每K存放10條指令排列虛存地址,即320條指令在虛存中的存放方式為:
第0條~第9條指令為第0頁(對應虛存地址為[0,9]);
第10條~第19條指令為第1頁(對應虛存地址為[10,19]);
……
……
第310條~第319條指令為第31頁(對應虛存地址為[310,319])。
按以上方式,使用者指令可組成32頁。
程式碼實現
#include <stdio.h>
#include <stdlib.h>
float count = 0; //缺頁次數
int instrAddr[320]; //指令地址流陣列
int pageAddr[320]; //頁地址流陣列
typedef struct Data //資料域
{
int pageNum; //裝進的使用者虛存頁號
int blockNum; //塊號
int t; //自上次被訪問以來所經歷的時間
} Data;
typedef struct BlockNode //單向迴圈連結串列
{
Data data;
struct BlockNode *next;
} Block, *BlockList;
//定義記憶體塊
BlockList block1;
BlockList block2;
BlockList block3;
BlockList block4;
void initialize() //初始化
{
block1 = (BlockList)malloc(sizeof(Block));
block2 = (BlockList)malloc(sizeof(Block));
block3 = (BlockList)malloc(sizeof(Block));
block4 = (BlockList)malloc(sizeof(Block));
block1->data.pageNum = -1;
block2->data.pageNum = -1;
block3->data.pageNum = -1;
block4->data.pageNum = -1;
block1->data.blockNum = 0;
block2->data.blockNum = 1;
block3->data.blockNum = 2;
block4->data.blockNum = 3;
block1->data.t = 0;
block2->data.t = 0;
block3->data.t = 0;
block4->data.t = 0;
block1->next = block2;
block2->next = block3;
block3->next = block4;
block4->next = block1;
for(int i = 0; i < 320; ) //初始化地址流
{
int m = rand() % 320;
instrAddr[i] = m + 1;
pageAddr[i] = instrAddr[i] / 10;
i++;
int m1 = rand() % (m - 1);
instrAddr[i] = m1;
pageAddr[i] = m1 / 10;
i++;
instrAddr[i] = m1 + 1;
pageAddr[i] = instrAddr[i] / 10;
i++;
int m2 = rand() % (319 - m1 - 1) + m1 + 2;
instrAddr[i] = m2;
pageAddr[i] = m2 / 10;
i++;
instrAddr[i] = m2 + 1;
pageAddr[i] = instrAddr[i] / 10;
i++;
}
}
int LRU(int pageNum, int virAddr)
{
Block *p = block1;
for(int i = 0; i < 4; i++) //遍歷所有記憶體塊,若不進行任何操作則遍歷結束時候仍指向block1
{
if(p->data.pageNum == -1) //塊為空閒
{
p->data.pageNum = pageNum;
count++; //缺頁次數+1
printf("指令地址:%d \n", virAddr);
printf("指令未裝入記憶體!頁面置換完成!\n使用者指令第%d頁第%d條的實體地址為:第%d塊第%d條 \n\n", pageNum, (virAddr % 10), p->data.blockNum, (virAddr % 10));
//將所有塊經歷的時間+1,再將當前訪問塊的時間置0
for(int i = 0; i < 4; i++)
{
p->data.t++;
p = p->next;
}
p->data.t = 0;
return 1;
}
if(p->data.pageNum == pageNum)
{
printf("指令地址:%d \n", virAddr);
printf("指令已在記憶體中!\n使用者指令第%d頁第%d條的實體地址為:第%d塊第%d條 \n\n", pageNum, (virAddr % 10), p->data.blockNum, (virAddr % 10));
for(int i = 0; i < 4; i++)
{
p->data.t++;
p = p->next;
}
p->data.t = 0;
return 1;
}
p = p->next;
}
//頁面置換
int largestT = -1;
for(int i = 0; i < 4; i++) //
{
if(p->data.t > largestT)
{
largestT = p->data.t;
}
p = p->next;
}
for(int i = 0; i < 4; i++)
{
if(p->data.t == largestT)
{
for(int j = 0; j < 4; j++)
{
p->data.t++;
p = p->next;
}
p->data.pageNum = pageNum;
count++;
p->data.t = 0;
printf("指令地址:%d \n", virAddr);
printf("指令未裝入記憶體且記憶體塊已滿!頁面置換完成!\n使用者指令第%d頁第%d條的實體地址為:第%d塊第%d條 \n\n", pageNum, (virAddr % 10), p->data.blockNum, (virAddr % 10));
return 1;
}
p = p->next;
}
return 1;
}
void calculate() //計算缺頁率
{
for(int i = 0; i < 320; i++)
{
LRU(pageAddr[i], instrAddr[i]);
}
printf("\n");
printf("缺頁次數:%.0f\n", count);
printf("計算得到的缺頁率為:%.4f \n", count / 320);
}
int main()
{
printf("----------最近最久未使用置換演算法----------\n\n");
initialize();
calculate();
return 0;
}
相關文章
- LRU(Least Recently Used)最近未使用置換演算法--c實現AST演算法
- 【作業系統】頁面置換演算法(最佳置換演算法)(C語言實現)作業系統演算法C語言
- InnoDB Buffer Pool改進LRU頁面置換
- 排序演算法-C語言實現排序演算法C語言
- PID演算法的C語言實現演算法C語言
- LRU快取替換策略及C#實現快取C#
- 頁面置換演算法你學會了嗎?演算法
- C語言實現九大排序演算法C語言排序演算法
- C++實現蠻力最近對演算法C++演算法
- 經典排序演算法的 C語言 | Java 實現排序演算法C語言Java
- 掃雷--C語言實現C語言
- c語言實現階乘C語言
- 面試題目:手寫一個LRU演算法實現面試題演算法
- 【作業系統】銀行家演算法實現(C語言)作業系統演算法C語言
- 常見快取演算法和LRU的c++實現快取演算法C++
- C 語言實現物體檢測:使用 YOLO 模型YOLO模型
- go語言實現簡單爬蟲獲取頁面圖片Go爬蟲
- 如何使用Python語言實現計數排序演算法?Python排序演算法
- WPF手動實現切換頁面
- C語言__LINE__實現原理C語言
- C語言實現檔案加密C語言加密
- c語言實現this指標效果C語言指標
- 高精度加法(C語言實現)C語言
- C語言實現TCP通訊C語言TCP
- C語言,實現數字譜到簡譜的轉換(二)C語言
- dijkstra演算法筆記(C語言實現,顯示路徑)演算法筆記C語言
- 手把手使用 PHP 實現 LRU 快取淘汰演算法PHP快取演算法
- 作業系統:程式狀態轉換模擬,C語言實現作業系統C語言
- 面試官:如何用LinkedHashMap實現LRU面試HashMap
- Perceptron演算法—C語言演算法C語言
- 高精度減法(C語言實現)C語言
- C語言實現推箱子游戲C語言
- C語言實現繼承多型C語言繼承多型
- C語言實現桌面貪吃蛇C語言
- Android 實現APP可切換多語言AndroidAPP
- JS 實現快取演算法(FIFO/LRU)JS快取演算法
- 使用LinkedHashMap來實現一個使用LRU(Least Recently Used)演算法的cacheHashMapAST演算法
- 從理念到LRU演算法實現,起底未來React非同步開發方式演算法React非同步