FIFO和LRU算法实现操作系统中主存管理

embedded/2024/11/22 20:04:24/

FIFO,用数组实现

1和2都是使用nextReplace实现新页面位置的更新

1、不精确时间:用ctime输出运行时间都是0.00秒

#include <iostream>
#include <iomanip>
#include<ctime>//用于计算时间
using namespace std;// 页访问顺序
int pages[20] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };// FIFO算法
void fifo(int n) {int memory[5] = { -1, -1, -1, -1, -1 };  // 用于存储主存块,初始化为 -1 表示空int table[5][20] = { -1 };               // 用于记录每次访问的内存状态,初始化为 -1 表示空bool status[20];                         // 记录是否缺页int pageFaults = 0;                      // 缺页次数int nextReplace = 0;                     // 记录下一个要替换的位置// 获取开始时间(时钟周期数)clock_t start = clock();// 遍历每个页面访问for (int j = 0; j < 20; j++) {int page = pages[j];bool found = false;// 检查页面是否已在内存中for (int i = 0; i < n; i++) {if (memory[i] == page) {found = true;break;}}if (!found) {  // 缺页情况memory[nextReplace] = page;       // 替换页面nextReplace = (nextReplace + 1) % n; // 更新替换位置status[j] = false;                // 标记缺页pageFaults++;}else {status[j] = true;                 // 标记命中}// 记录当前内存状态到表格for (int i = 0; i < n; i++) {table[i][j] = memory[i];}}// 获取结束时间(时钟周期数)clock_t end = clock();// 输出结果表格cout << "主存块号 ";for (int j = 0; j < 20; j++) {cout << pages[j] << " ";}cout << endl;for (int i = 0; i < n; i++) {cout << "   " << i << "     ";for (int j = 0; j < 20; j++) {if (table[i][j] == -1) {cout << "  ";  // 空块显示为空格}else {cout << table[i][j] << " ";}}cout << endl;}// 输出缺页标记cout << "是否缺页 ";for (int j = 0; j < 20; j++) {if (status[j]) {cout << "\u221A ";  // Unicode "√"}else {cout << "\u00D7 ";  // Unicode "×"}}cout << endl;cout << "FIFO 缺页率: " << fixed << setprecision(2) << (float)pageFaults / 20 * 100 << "%" << endl;cout << "运行时间: " << (double)(end - start) / CLOCKS_PER_SEC << " 秒" << endl; // 输出运行时间
}int main() {cout << "内存容量为 3 块:\n";fifo(3);cout << endl;cout << "内存容量为 4 块:\n";fifo(4);return 0;
}

2、精确时间:用chrono输出运行时间都是xx微秒,输出时间不定

#include <iostream>
#include <iomanip>
#include <chrono> // 引入chrono库using namespace std;
using namespace std::chrono; // 使用chrono命名空间// 页访问顺序
int pages[20] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };// FIFO算法
void fifo(int n) {int memory[5] = { -1, -1, -1, -1, -1 };  // 用于存储主存块,初始化为 -1 表示空int table[5][20] = { -1 };               // 用于记录每次访问的内存状态,初始化为 -1 表示空bool status[20];                         // 记录是否缺页int pageFaults = 0;                      // 缺页次数int nextReplace = 0;                     // 记录下一个要替换的位置// 获取开始时间auto start = high_resolution_clock::now();// 遍历每个页面访问for (int j = 0; j < 20; j++) {int page = pages[j];bool found = false;// 检查页面是否已在内存中for (int i = 0; i < n; i++) {if (memory[i] == page) {found = true;break;}}if (!found) {  // 缺页情况memory[nextReplace] = page;       // 替换页面nextReplace = (nextReplace + 1) % n; // 更新替换位置status[j] = false;                // 标记缺页pageFaults++;}else {status[j] = true;                 // 标记命中}// 记录当前内存状态到表格for (int i = 0; i < n; i++) {table[i][j] = memory[i];}}// 获取结束时间auto stop = high_resolution_clock::now();auto duration = duration_cast<microseconds>(stop - start);// 输出结果表格cout << "主存块号 ";for (int j = 0; j < 20; j++) {cout << pages[j] << " ";}cout << endl;for (int i = 0; i < n; i++) {cout << "   " << i << "     ";for (int j = 0; j < 20; j++) {if (table[i][j] == -1) {cout << "  ";  // 空块显示为空格}else {cout << table[i][j] << " ";}}cout << endl;}// 输出缺页标记cout << "是否缺页 ";for (int j = 0; j < 20; j++) {if (status[j]) {cout << "\u221A ";  // Unicode "√"}else {cout << "\u00D7 ";  // Unicode "×"}}cout << endl;cout << "FIFO 缺页率: " << fixed << setprecision(2) << (float)pageFaults / 20 * 100 << "%" << endl;cout << "运行时间: " << duration.count() << " 微秒" << endl; // 输出运行时间
}int main() {cout << "内存容量为 3 块:\n";fifo(3);cout << endl;cout << "内存容量为 4 块:\n";fifo(4);return 0;
}

3、数组模拟队列、类似滑动窗口

#include <iostream>
#include <iomanip>
#include <chrono>
#include <cstring>using namespace std;
using namespace std::chrono;const int N = 1010;
int memory[N];//每次查找页面进行记录的滑动窗口
int table[5][20]; // 最终输出的表格状态
// 页访问顺序
int pages[20] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };// FIFO算法
void fifo(int n) {memset(memory, 0x3f, sizeof memory);bool status[20];  // 记录是否缺页int pageFaults = 0;       // 缺页次数int hh = 0, tt = -1;      // 队首和队尾指针auto start = high_resolution_clock::now(); // 获取开始时间for (int j = 0; j < 20; j++) {int page = pages[j];bool found = false;// 检查页面是否已在内存中for (int i = hh; i <= tt; i++) {if (memory[i] == page) {found = true;break;}}if (!found) {  // 缺页情况memory[++tt] = page; // 新页面加入队尾// 控制滑动窗口大小为 nif (tt - hh + 1 > n) {hh++; // 超过容量,队首出队}status[j] = false;  // 标记缺页pageFaults++;}else {status[j] = true;   // 标记命中}// 记录当前内存状态到表格for (int i = 0; i < n; i++) {//如果只写memory[hh]的话不就移动队首指针了吗,不可以,现在是赋值阶段,只需要控制负责赋值的滑动指针首先不能超过队尾指针,确保在滑动窗口范围内,//因为有可能这个滑动窗口不足n长,你就会多余赋值本来不能存在的页面号赋值成0x3f,其次需要满足当前检查是否缺页的一次记录memory,该位置是否有值if (i + hh <= tt && memory[i + hh] != 0x3f) {table[i][j] = memory[i + hh];}else {table[i][j] = -1; // 空位显示为 -1}}}auto stop = high_resolution_clock::now(); // 获取结束时间auto duration = duration_cast<microseconds>(stop - start);// 输出结果表格cout << "主存块号 ";for (int j = 0; j < 20; j++) {cout << pages[j] << " ";}cout << endl;for (int i = 0; i < n; i++) {cout << "   " << i << "     ";for (int j = 0; j < 20; j++) {if (table[i][j] == -1) {cout << "  ";  // 空块显示为空格}else {cout << table[i][j] << " ";}}cout << endl;}// 输出缺页标记cout << "是否缺页 ";for (int j = 0; j < 20; j++) {cout << (status[j] ? "\u221A " : "\u00D7 ");//unicode编码,前者代表true则不缺页是√标识,后者代表false是缺页×表示}cout << endl;cout << "FIFO 缺页率: " << fixed << setprecision(2) << (float)pageFaults / 20 * 100 << "%" << endl;cout << "运行时间: " << duration.count() << " 微秒" << endl;
}int main() {cout << "内存容量为 3 块:\n";fifo(3);cout << endl;cout << "内存容量为 4 块:\n";fifo(4);return 0;
}

朴素版算缺页率

#include <iostream>
#include <ctime>
#include <cstring>using namespace std;const int N = 1010;
int memory[N];//每次查找页面进行记录的滑动窗口
int table[5][20]; // 最终输出的表格状态
// 页访问顺序
int pages[20] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };// FIFO算法
void fifo(int n) {memset(memory, 0x3f, sizeof memory);bool status[20];  // 记录是否缺页int pageFaults = 0;       // 缺页次数int hh = 0, tt = -1;      // 队首和队尾指针clock_t start=clock(); // 获取开始时间for (int j = 0; j < 20; j++) {int page = pages[j];bool found = false;// 检查页面是否已在内存中for (int i = hh; i <= tt; i++) {if (memory[i] == page) {found = true;break;}}if (!found) {  // 缺页情况memory[++tt] = page; // 新页面加入队尾// 控制滑动窗口大小为 nif (tt - hh + 1 > n) {hh++; // 超过容量,队首出队}status[j] = false;  // 标记缺页pageFaults++;}else {status[j] = true;   // 标记命中}// 记录当前内存状态到表格for (int i = 0; i < n; i++) {//如果只写memory[hh]的话不就移动队首指针了吗,不可以,现在是赋值阶段,只需要控制负责赋值的滑动指针首先不能超过队尾指针,确保在滑动窗口范围内,//因为有可能这个滑动窗口不足n长,你就会多余赋值本来不能存在的页面号赋值成0x3f,其次需要满足当前检查是否缺页的一次记录memory,该位置是否有值if (i + hh <= tt && memory[i + hh] != 0x3f) {table[i][j] = memory[i + hh];}else {table[i][j] = -1; // 空位显示为 -1}}}clock_t end = clock(); // 获取结束时间// 输出结果表格cout << "主存块号 ";for (int j = 0; j < 20; j++) {cout << pages[j] << " ";}cout << endl;for (int i = 0; i < n; i++) {cout << "   " << i << "     ";for (int j = 0; j < 20; j++) {if (table[i][j] == -1) {cout << "  ";  // 空块显示为空格}else {cout << table[i][j] << " ";}}cout << endl;}// 输出缺页标记cout << "是否缺页 ";for (int j = 0; j < 20; j++) {cout << (status[j] ? "\u221A " : "\u00D7 ");//unicode编码,前者代表true则不缺页是√标识,后者代表false是缺页×表示}cout << endl;cout << "FIFO 缺页率: " << (float)pageFaults / 20 * 100 << "%" << endl;cout << "运行时间: " << (double)(end-start)/CLOCKS_PER_SEC << " 秒" << endl;}int main() {cout << "内存容量为 3 块:\n";fifo(3);cout << endl;cout << "内存容量为 4 块:\n";fifo(4);return 0;
}

FIFO,用链表实现

LRU,用计数器实现

#include <iostream>
#include <ctime>
#include <cstring>
#include <unordered_map>using namespace std;const int N = 1010;
int table[5][20]; // 最终输出的表格状态
unordered_map<int, int> m; // 键为page号,值为count值
int pages[20] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };void lru(int n) {memset(table, -1, sizeof table);m.clear();bool status[20]; // 记录是否缺页int pageFaults = 0; // 缺页次数clock_t start = clock(); // 获取开始时间for (int j = 0; j < 20; j++) {int page = pages[j];if (!m.count(page)) { // 没命中就要加入或者替换页面if (m.size() >= n) {// 找到count最大的页面进行替换int maxpage = -1, maxcounts = -1;for (auto p : m) {if (p.second > maxcounts) {maxpage = p.first;maxcounts = p.second;}}m.erase(maxpage);}m[page] = 0;//没命中且主存没满则直接加入页面pageFaults++;status[j] = false; // 标记缺页}else {status[j] = true; // 标记命中m[page] = 0;}// 更新所有页面的count值:命中则置0,没命中加入新页面——满足条件则不加1即可,不管加不加入新页面,其他没中的页面都是要count+1的for (auto& p : m) {if (p.first != page) {p.second += 1;}}// 更新当前主存块内存在的页面int i = 0;for (auto p : m) {if (i < n) {//用一个i去便利贮存块,而不用fortable[i][j] = p.first;i++;}}//一开始写错了:/*for (int i = 0; i < n; i++) {for (auto p : m) {table[i][j] = p.first;}}*/}clock_t end = clock(); // 获取结束时间// 输出结果表格cout << "主存块号 ";for (int j = 0; j < 20; j++) {cout << pages[j] << " ";}cout << endl;for (int i = 0; i < n; i++) {cout << "   " << i << "     ";for (int j = 0; j < 20; j++) {if (table[i][j] == -1) {cout << "  "; // 空块显示为空格}else {cout << table[i][j] << " ";}}cout << endl;}// 输出缺页标记cout << "是否缺页 ";for (int j = 0; j < 20; j++) {cout << (status[j] ? "\u221A " : "\u00D7 ");}cout << endl;cout << "LRU 缺页率: " << (float)(pageFaults) / 20 * 100 << "%" << endl;cout << "运行时间: " << (double)(end - start) / CLOCKS_PER_SEC << " 秒" << endl;
}int main() {cout << "内存容量为 3 块:\n";lru(3);cout << endl;cout << "内存容量为 4 块:\n";lru(4);return 0;
}

LRU,用堆栈实现

两个算法综合在一起看运行速率

#include <iostream>
#include <ctime>
#include <cstring>
#include <unordered_map>
#include <chrono> // 引入chrono库using namespace std;
using namespace std::chrono; // 使用chrono命名空间const int N = 1010;
int table[5][20]; // 最终输出的表格状态
unordered_map<int, int> m; // 键为page号,值为count值
int pages[20] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };
int memory[N];//每次查找页面进行记录的滑动窗口// FIFO算法
void fifo(int n) {memset(memory, 0x3f, sizeof memory);memset(table, -1, sizeof table);bool status[20];  // 记录是否缺页int pageFaults = 0;       // 缺页次数int hh = 0, tt = -1;      // 队首和队尾指针//clock_t start = clock(); // 获取开始时间// 获取开始时间auto start = high_resolution_clock::now();for (int j = 0; j < 20; j++) {int page = pages[j];bool found = false;// 检查页面是否已在内存中for (int i = hh; i <= tt; i++) {if (memory[i] == page) {found = true;break;}}if (!found) {  // 缺页情况memory[++tt] = page; // 新页面加入队尾// 控制滑动窗口大小为 nif (tt - hh + 1 > n) {hh++; // 超过容量,队首出队}status[j] = false;  // 标记缺页pageFaults++;}else {status[j] = true;   // 标记命中}// 记录当前内存状态到表格for (int i = 0; i < n; i++) {//如果只写memory[hh]的话不就移动队首指针了吗,不可以,现在是赋值阶段,只需要控制负责赋值的滑动指针首先不能超过队尾指针,确保在滑动窗口范围内,//因为有可能这个滑动窗口不足n长,你就会多余赋值本来不能存在的页面号赋值成0x3f,其次需要满足当前检查是否缺页的一次记录memory,该位置是否有值if (i + hh <= tt && memory[i + hh] != 0x3f) {table[i][j] = memory[i + hh];}else {table[i][j] = -1; // 空位显示为 -1}}}//clock_t end = clock(); // 获取结束时间// 获取结束时间auto stop = high_resolution_clock::now();auto duration = duration_cast<microseconds>(stop - start);// 输出结果表格cout << "主存块号 ";for (int j = 0; j < 20; j++) {cout << pages[j] << " ";}cout << endl;for (int i = 0; i < n; i++) {cout << "   " << i << "     ";for (int j = 0; j < 20; j++) {if (table[i][j] == -1) {cout << "  ";  // 空块显示为空格}else {cout << table[i][j] << " ";}}cout << endl;}// 输出缺页标记cout << "是否缺页 ";for (int j = 0; j < 20; j++) {cout << (status[j] ? "\u221A " : "\u00D7 ");//unicode编码,前者代表true则不缺页是√标识,后者代表false是缺页×表示}cout << endl;cout << "FIFO 缺页率: " << (float)pageFaults / 20 * 100 << "%" << endl;//cout << "运行时间: " << (double)(end - start) / CLOCKS_PER_SEC << " 秒" << endl;cout << "运行时间: " << duration.count() << " 微秒" << endl; // 输出运行时间}
void lru(int n) {memset(table, -1, sizeof table);m.clear();bool status[20]; // 记录是否缺页int pageFaults = 0; // 缺页次数//clock_t start = clock(); // 获取开始时间// 获取开始时间auto start = high_resolution_clock::now();for (int j = 0; j < 20; j++) {int page = pages[j];if (!m.count(page)) { // 没命中就要加入或者替换页面if (m.size() >= n) {// 找到count最大的页面进行替换int maxpage = -1, maxcounts = -1;for (auto p : m) {if (p.second > maxcounts) {maxpage = p.first;maxcounts = p.second;}}m.erase(maxpage);}m[page] = 0;//没命中且主存没满则直接加入页面pageFaults++;status[j] = false; // 标记缺页}else {status[j] = true; // 标记命中m[page] = 0;}// 更新所有页面的count值:命中则置0,没命中加入新页面——满足条件则不加1即可,不管加不加入新页面,其他没中的页面都是要count+1的for (auto& p : m) {if (p.first != page) {p.second += 1;}}// 更新当前主存块内存在的页面int i = 0;for (auto p : m) {if (i < n) {//用一个i去便利贮存块,而不用fortable[i][j] = p.first;i++;}}//一开始写错了:/*for (int i = 0; i < n; i++) {for (auto p : m) {table[i][j] = p.first;}}*/}//clock_t end = clock(); // 获取结束时间// 获取结束时间auto stop = high_resolution_clock::now();auto duration = duration_cast<microseconds>(stop - start);// 输出结果表格cout << "主存块号 ";for (int j = 0; j < 20; j++) {cout << pages[j] << " ";}cout << endl;for (int i = 0; i < n; i++) {cout << "   " << i << "     ";for (int j = 0; j < 20; j++) {if (table[i][j] == -1) {cout << "  "; // 空块显示为空格}else {cout << table[i][j] << " ";}}cout << endl;}// 输出缺页标记cout << "是否缺页 ";for (int j = 0; j < 20; j++) {cout << (status[j] ? "\u221A " : "\u00D7 ");}cout << endl;cout << "LRU 缺页率: " << (float)(pageFaults) / 20 * 100 << "%" << endl;//cout << "运行时间: " << (double)(end - start) / CLOCKS_PER_SEC << " 秒" << endl;cout << "运行时间: " << duration.count() << " 微秒" << endl; // 输出运行时间
}int main() {cout << "内存容量为 3 块:\n";fifo(3);cout << endl;lru(3);cout << endl;cout << "内存容量为 4 块:\n";fifo(4);cout << endl;lru(4);return 0;
}

1)主存块数越多的,不论哪个算法,运行时间都更长一些,用的时chrono精确时间微妙

但是同样的,运行每次的时间不定

2)主存块数越多的,不论哪个算法,缺页率都更低一些


http://www.ppmy.cn/embedded/139693.html

相关文章

基于微信小程序的河池旅游设计与实现

一、前言 随着移动互联网的快速发展&#xff0c;微信小程序以其便捷性、无需安装等优势受到广泛关注。河池拥有丰富的旅游资源&#xff0c;包括独特的自然风光&#xff08;如巴马长寿之乡的山水、宜州下枧河风光等&#xff09;、多彩的民族文化&#xff08;如壮族铜鼓文化、仫佬…

mysqldbcompare 使用及参数详解

限制 该工具将每行的主键读取到数据结构中&#xff0c;然后用于生成每行的校验和。主键和校验和随后被排序并比较&#xff0c;以检测哪些行存在差异。由于这种设计&#xff0c;工具在处理非常大的表&#xff08;许多行&#xff09;时可能会表现出较慢的性能&#xff0c;特别是…

Maven详解

文章目录 Maven详解一、引言二、Maven基础1、Maven安装与配置1.1、下载与安装1.2、配置环境变量1.3、验证安装 2、Maven项目结构 三、Maven依赖管理3.1、依赖配置3.2、依赖范围 四、Maven构建生命周期4.1、常用Maven命令 五、Maven私服5.1、Nexus安装与配置5.1.1、下载与安装Ne…

排序算法:直接插入排序,希尔排序,选择排序,快速排序,堆排序,归并排序

1.直接插入排序 基本思想&#xff1a;把待排序的数按照大小逐个插入到前面已经排序好的有序序列中&#xff0c;直到所有的都插入完为止&#xff0c;得到一个新的有序序列。 如图所示&#xff0c;当插入第i个&#xff08;i>1&#xff09;元素的时候&#xff0c;前面的arr[0]…

wps PPT debug

wps无法调整PPT单元格高度 https://zhidao.baidu.com/question/1801894280933920947.html wps如何自定义母版 可以直接右上角搜母版&#xff0c;然后进入“幻灯片母版”。进入后可以修改各个页版式。 原来好像没有添加占位符的功能&#xff0c;现在看已经有了。但是使用的时…

驰骋资讯高速:Spring Boot汽车新闻网站

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理汽车资讯网站的相关信息成为必然。开发合适…

独家原创 | SCI 1区 高创新预测模型!

往期精彩内容&#xff1a; 时序预测&#xff1a;LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较 全是干货 | 数据集、学习资料、建模资源分享&#xff01; EMD变体分解效果最好算法——CEEMDAN&#xff08;五&#xff09;-CSDN博客 拒绝信息泄露&#xff01;VMD滚动分…

Docker1:认识docker、在Linux中安装docker

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…