当前位置: 首页 > news >正文

页面淘汰算法模拟实现与比较

1.实验目标

利用标准C 语言,编程设计与实现最佳淘汰算法、先进先出淘汰算法、最近最久未使用淘汰算法、简单 Clock 淘汰算法及改进型 Clock 淘汰算法,并随机发生页面访问序列开展有关算法的测试及性能比较。

2.算法描述

 1. 最佳淘汰算法(Optimal Replacement Algorithm):这种算法选择将来最久不会被访问的页面进行淘汰。实现这个算法需要预知未来的页面访问请求,因此在实际中无法实现,但是我们可以模拟访问序列来比较实现效果。

2. 先进先出淘汰算法(FIFO Replacement Algorithm):这种算法总是淘汰最早进入内存的页面。实现这个算法可以使用一个队列,新进入的页面放入队尾,需要淘汰页面时总是淘汰队头的页面。

3. 最近最久未使用淘汰算法(LRU Replacement Algorithm):这种算法淘汰最长时间未被访问的页面。实现这个算法可以使用一个链表,每次页面被访问时,将这个页面移动到链表头,需要淘汰页面时总是淘汰链表尾的页面。

4. 简单 Clock 淘汰算法(Clock Replacement Algorithm):这种算法将内存中的页面组织成一个环形链表,有一个指针指向最早进入的页面。每次需要淘汰页面时,检查指针指向的页面,如果这个页面最近被访问过,则将其标记清除,指针向前移动,否则淘汰这个页面。

5. 改进型 Clock 淘汰算法(Enhanced Clock Replacement Algorithm):这是 Clock 算法的改进版,增加了一个修改位用于记录页面是否被修改过。在选择淘汰的页面时,优先选择未被修改且最近未被访问的页面。

3.访问序列模拟 

1. 初始化进程逻辑地址空间页面总数 N、各逻辑页面的读写访问方式(是否支持写访问,即R、RW)、工作集起始页号s(s∈[0, N)) 、工作集中包含的页数 w,工作集移动速率 v(每处理 v 个页面访问,就将工作集起始页号递增即 s+1)以及一个取值区间为[0, 1]的值 t

2. 生成取值区间为[s, min(s+w, N-1)]的v 个随机数并添加保存到页面访问序列中,同时为每次页面访问分别生成一个取值区间为[0, 1]的随机数,若该随机数值大于 0.7 且对应所访问页面支持写访问则设定以写方式访问相应页面,否则以读方式访问对应页面

3. 生成取值区间为[0, 1]的一个随机数r,并比较 r 与t 的大小

4. 若r < t,则为s 生成一个新值(s∈[0, N)) ,否则s = (s + 1) mod N

5. 如果想继续加大页面访问序列的长度,返回第 2 步,否则结束

4.模拟测试思路 

基于相同的条件,系统均采用固定分配局部置换策略、相同的进程逻辑地址空间大小、分配给进程同样多的物理块、相同的页面访问序列、均预装入前三个页面,进行有关算法的测试,预计执行一百轮测试,以轮数为随机数种子,保证结果可以复现。

5.相关数据结构 

// 模拟页面
struct PAGE { int  pages[MAXLEN];int  usenum; // 分配的最大页框数int  visitlen; // 访问序列长度
} pinfo;// 模拟页表
struct MEM { int time; // 访问记录int r; // 访问位int rw; // 修改位int pages; // 页号
} minfo;MEM pagelist[MAXLEN]; // 分配页框
#include <iostream>
#include <thread>
#include <time.h>
using namespace std;const int MAXLEN = 1024; // 最大页面数
const int epoch = 100; // 测试次数
int lossnum; // 缺页次数统计
int now; // 当前访问的页面
int replace; // 页面替换指针
int lossflag; // 是否缺页
int full; // 已使用的页框数
int rate[5][epoch];
int times[5][epoch];struct PAGE {int  pages[MAXLEN];int  usenum; // 分配的最大页框数int  visitlen; // 访问序列长度
} pinfo;
struct MEM {int time; // 访问记录int r; // 访问位int rw; // 修改位int pages; // 页号
} minfo;
MEM pagelist[MAXLEN]; // 分配页框void pageinit() { // 初始化页面数据pinfo.usenum = 3;pinfo.visitlen = 256;for (int i = 0; i < MAXLEN; i++)pinfo.pages[i] = -1;
}void visitlist(int epoch) { // 随机生成访问序列int v = 16, w = 64, s = 128; // v为每个页面访问次数,w为每个页面访问的范围,s为页面访问的起始位置pageinit();srand(epoch); // 随机种子int t= rand() % 11; // 生成tfor(int i = 0, j =0; i < 10; i++) {for(j = i * v; j < (i + 1) * v; j++) { // 生成v个[s, s+w]的随机数if(j > pinfo.visitlen) // 生成数量不能超序列长度break;pinfo.pages[j]= (s + (rand() % w)) % MAXLEN; // 随机数存储到访问序列中}if(rand() % 11 < t) // 如果r < t,则为p生成一个新值s = rand() % MAXLEN;elses = (s + 1) % MAXLEN;}
}bool randBool() { // 读写随机数生成函数if(rand() % 11 > 7) return true;else return false;
}bool inram(int page) { // 查找是否在内存for(int i = 0; i < pinfo.usenum; i++) {pagelist[i].time++;  // 访问记录++}for(int i = 0; i < pinfo.usenum; i++) {if(pagelist[i].pages == page) {lossflag = 0; // 不缺页置为0pagelist[i].time = 0; // 访问记录置0if(randBool()) {pagelist[i].r = 1;pagelist[i].rw = 1;}elsepagelist[i].r = 1;return true;}}lossflag = 1; // 缺页置为1return false;
}void OPT() {// 最佳淘汰算法replace = 0, lossnum = 0, full = 0, lossflag = 0;for(int i = 0; i < pinfo.usenum; i++) // 刷新页框pagelist[i].pages = -1;for(now = 0; now < pinfo.visitlen; now++) {if(full < pinfo.usenum) {if(!inram(pinfo.pages[now])) { // 不在内存则装入页面pagelist[replace].pages = pinfo.pages[now];replace = (replace + 1) % pinfo.usenum;full++, lossnum++; }}else {if(!inram(pinfo.pages[now])) { // 不在内存则需置换int min, max = 0 ; // min为最近访问,max为最远访问for(int m = 0; m < pinfo.usenum ; m++) {min = MAXLEN;for(int n = now; n < pinfo.visitlen; n++) {if (pinfo.pages[n] == pagelist[m].pages) {min = n;break;}}if(max < min) {max = min;replace = m;}}pagelist[replace].pages = pinfo.pages[now];replace = (replace + 1) % pinfo.usenum;lossnum++;}}std::this_thread::sleep_for(10ms);}
}void FIFO(void) { // 先进先出淘汰算法replace = 0, lossnum = 0, full = 0, lossflag = 0;for(int i = 0; i < pinfo.usenum; i++)pagelist[i].pages = -1;for(now = 0; now < pinfo.visitlen; now++) {if(full < pinfo.usenum) { if(!inram(pinfo.pages[now])) {pagelist[replace].pages = pinfo.pages[now];replace = (replace + 1) % pinfo.usenum;full++, lossnum++;}}else {if(!inram(pinfo.pages[now])) {pagelist[replace].pages = pinfo.pages[now];replace = (replace + 1) % pinfo.usenum;lossnum++;}}std::this_thread::sleep_for(10ms);}
}void LRU(void) { // 最近最久未使用淘汰算法replace = 0, lossnum = 0, full = 0, lossflag = 0;for(int i = 0; i < pinfo.usenum; i++) {pagelist[i].pages = -1;pagelist[i].time = 0;} // 刷新页框for(now = 0; now < pinfo.visitlen; now++) {if(full < pinfo.usenum) {if(!inram(pinfo.pages[now])) {pagelist[replace].pages = pinfo.pages[now];replace = (replace + 1) % pinfo.usenum;full++, lossnum++;}}else {if(!inram(pinfo.pages[now])) {int max = 0; // 最久的访问记录for(int i = 1; i < pinfo.usenum; i++) {if(pagelist[i].time > pagelist[max].time) {max = i;}}replace = max;pagelist[replace].pages = pinfo.pages[now];pagelist[replace].time = 0;lossnum++;}}std::this_thread::sleep_for(10ms);}
}int replace0(int num) { // 简单Clock置换for(int i = 0; i < pinfo.usenum; i++) {if(pagelist[(i + num) % pinfo.usenum].r == 0 ) // 找到第一个访问位为0的页面return (i + num) % pinfo.usenum;pagelist[(i + num) % pinfo.usenum].r = 0; // 未找到则将所有访问位置0}for(int i = 0; i < pinfo.usenum; i++) {if(pagelist[(i + num) % pinfo.usenum].r == 0 )return (i + num) % pinfo.usenum;}return 0;
}int replace1(int num) { // 改进的clock置换for(int i = 0; i < pinfo.usenum; i++) {if (pagelist[(i + num) % pinfo.usenum].r == 0 && pagelist[(i + num) % pinfo.usenum].rw == 0) // 先找访问位和修改位都为0的页面return (i + num) % pinfo.usenum;}for(int i = 0; i < pinfo.usenum; i++) {if (pagelist[(i + num) % pinfo.usenum].r == 0 && pagelist[(i + num) % pinfo.usenum].rw == 1) // 再找访问位为0,修改位为1的页面return (i + num) % pinfo.usenum;pagelist[(i + num) % pinfo.usenum].r = 0; // 未找到则将所有访问位置0}for(int i = 0; i < pinfo.usenum; i++) {if (pagelist[(i + num) % pinfo.usenum].r == 0 && pagelist[(i + num) % pinfo.usenum].rw == 0) // 再找访问位和修改位都为0的页面return (i + num) % pinfo.usenum;}for(int i = 0; i < pinfo.usenum; i++) {if (pagelist[(i + num) % pinfo.usenum].r == 0 && pagelist[(i + num) % pinfo.usenum].rw == 1) // 最后找访问位为0,修改位为1的页面return (i + num) % pinfo.usenum;}return 0;
}void CLOCK(int choose) {int num = 0;replace = 0, lossnum = 0, full = 0, lossflag = 0;for(int i = 0; i < pinfo.usenum; i++) {pagelist[i].pages = -1;pagelist[i].rw = 0;pagelist[i].r = 0;pagelist[i].time = 0;}for(now = 0; now < pinfo.visitlen; now++) {if(full < pinfo.usenum) {if(!inram(pinfo.pages[now])) {pagelist[replace].pages = pinfo.pages[now];replace = (replace + 1) % pinfo.usenum;pagelist[replace].r = 1;full++, lossnum++;}}else {if(!inram(pinfo.pages[now])) {if(choose == 1)replace = replace1(num++); // choose=1,改进clock算法else if(choose == 0) // choose=0,简单clock算法replace = replace0(num++); pagelist[replace].pages = pinfo.pages[now];pagelist[replace].r = 1;lossnum++;}}std::this_thread::sleep_for(10ms);}
}void calculate(int i, int j, clock_t start) { // 计算缺页率和运行时间rate[i][j] = (double)(lossnum) * 100 / now;times[i][j] = (double)(clock() - start) / 1000;
}int main() {clock_t start;for(int i = 0; i < epoch; i++) {visitlist(i);start = clock();OPT();calculate(0, i, start);start = clock();FIFO();calculate(1, i, start);start = clock();LRU();calculate(2, i, start);start = clock();CLOCK(0);calculate(3, i, start);start = clock();CLOCK(1);calculate(4, i, start);}for(int i = 0; i < 5; i++) {if(i == 0) printf("OPT:    ");if(i == 1) printf("FIFO:   ");if(i == 2) printf("LRU:    ");if(i == 3) printf("CLOCK:  ");if(i == 4) printf("CLOCK+: ");int avrate = 0, avtime = 0;for(int j = 0; j < epoch; j++) {avrate += rate[i][j];avtime += times[i][j];}printf("Average replace rate = %.3lf%%  ", (double)(avrate) / epoch);printf("Average spend time: %.3lfs\n", (double)(avtime) / epoch);}return 0;
}

7.运行结果

相关文章:

页面淘汰算法模拟实现与比较

1.实验目标 利用标准C 语言&#xff0c;编程设计与实现最佳淘汰算法、先进先出淘汰算法、最近最久未使用淘汰算法、简单 Clock 淘汰算法及改进型 Clock 淘汰算法&#xff0c;并随机发生页面访问序列开展有关算法的测试及性能比较。 2.算法描述 1. 最佳淘汰算法&#xff08;Op…...

FPGA实现HDMI转LVDS视频输出,纯verilog代码驱动,提供4套工程源码和技术支持

目录 1、前言免责声明 2、目前我这里已有的图像处理方案3、本 LVDS 方案的特点4、详细设计方案设计原理框图视频源选择静态彩条IT6802解码芯片配置及采集ADV7611解码芯片配置及采集silicon9011解码芯片配置及采集纯verilog的HDMI 解码模块奇偶场分离并串转换LVDS驱动 5、vivado…...

JAVA-easyexcel多sheet页导入

今天给宝子带来一套多sheet页导入的模板&#xff0c;话不多说直接上代码 String localFilePath "file.xlsx";JSONObject jsonObject JSON.parseObject(file);String useFile jsonObject.getString("file");useFileuseFile.replace("\\\\",&qu…...

Java——比较器(一文搞懂比较器Comparable和Comparator)

基于Comparable的接口类基于Comparator的接口类 1、比较器的Comparable接口类 Comparable类的定义: public interface Comparable<T>{ public int compareTo(T o); }2、Comparable比较器的返回值&#xff1a; 此方法返回一个int类型的数据&#xff0c;但是此int的值…...

企业直播招聘抖音报白如何实现?怎么样才能报白成功?

现在每天几亿人都在使用抖音等短视频平台进行娱乐或者工作学习&#xff0c;也有很多商家和企业利用抖音等短视频平台进行盈利和企业宣传相关的服务&#xff0c;其中比较典型的就是通过抖音直播等功能为自身企业进行招聘。 但是通过抖音等短视频平台进行招聘时&#xff0c;很多…...

【考研数学】概率论与数理统计 —— 第七章 | 参数估计(2,参数估计量的评价、正态总体的区间估计)

文章目录 一、参数估计量的评价标准1.1 无偏性1.2 有效性1.3 一致性 二、一个正态总体参数的双侧区间估计2.1 对参数 μ \mu μ 的双侧区间估计 三、一个正态总体的单侧置信区间四、两个正态总体的双侧置信区间写在最后 一、参数估计量的评价标准 1.1 无偏性 设 X X X 为总…...

【设计模式】第10节:结构型模式之“组合模式”

一、简介 组合模式&#xff1a;将一组对象组织成树形结构&#xff0c;将单个对象和组合对象都看做树中的节点&#xff0c;以统一处理逻辑&#xff0c;并且它利用树形结构的特点&#xff0c;递归地处理每个子树&#xff0c;依次简化代码实现。使用组合模式的前提在于&#xff0…...

改进YOLOv3!IA-YOLO:恶劣天气下的目标检测

恶劣天气条件下从低质量图像中定位目标还是极具挑战性的任务。现有的方法要么难以平衡图像增强和目标检测任务&#xff0c;要么往往忽略有利于检测的潜在信息。本文提出了一种新的图像自适应YOLO (IA-YOLO)框架&#xff0c;可以对每张图像进行自适应增强&#xff0c;以提高检测…...

Vue路由跳转的几种方式

1.this. $router.push( ) 跳转到指定的URL&#xff0c;在history栈中添加一个记录&#xff0c;点击后退会返回上一个页面。 1. 不带参数// 字符串this.$router.push(/home)this.$router.push(/home/first)// 对象this.$router.push({path:/home})this.$router.push({ path: /…...

TiDB x 汉口银行丨分布式数据库应用实践

汉口银行是一家城市商业银行&#xff0c;近年来专注科技金融、民生金融等领域。在数据库国产化改造中&#xff0c;汉口银行引入了 TiDB 数据库&#xff0c;并将其应用在重要业务系统&#xff1a;头寸系统中&#xff0c;实现了一栈式的数据服务&#xff0c;同时满足了高并发、低…...

uci机器学习数据库简介

UCI&#xff08;University of California, Irvine&#xff09;机器学习数据库是经过精心整理的、用于研究和开发机器学习算法的数据集合。UCI机器学习数据库是一个公开的、广泛使用的数据集合&#xff0c;它由加州大学欧文分校的计算机科学系维护。该数据库中包含了许多数据集…...

多人协作使用git如何解决冲突?

什么情况会产生冲突 git merge XXX(合并分支时的冲突)&#xff1a; 当你尝试将一个分支的更改合并到另一个分支时&#xff0c;如果两个分支都修改了相同的文件的相同部分&#xff0c;Git 将无法自动解决冲突&#xff0c;因此会发生冲突。你需要手动解决这些冲突&#xff0c;然后…...

基于【逻辑回归】的评分卡模型金融借贷风控项目实战

背景知识&#xff1a; 在银行借贷过程中&#xff0c;评分卡是一种以分数形式来衡量一个客户的信用风险大小的手段。今天我们来复现一个评分A卡的模型。完整的模型开发所需流程包括&#xff1a;获取数据&#xff0c;数据清洗和特征工程&#xff0c;模型开发&#xff0c…...

企业拉美跨境出海面对时延情况怎么办?

随着全球化不断发展&#xff0c;中国企业也不断向海外拓展业务&#xff0c;开拓市场&#xff0c;增加收入来源&#xff0c;扩大自身品牌影响力。然而出海企业面临不同以往的困难和挑战&#xff0c;在其中不可避免面临的跨境网络时延问题&#xff0c;如何选择区域进行部署企业业…...

【vector题解】只出现一次的数字 | 电话号码的数字组合

只出现一次的数字 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 给你一个整数数组 nums&#xff0c;其中恰好有两个元素只出现一次&#xff0c;其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。 你必须设计并…...

VS2022 开发方式

使用 C# 在VS 2022 上开发时&#xff0c;发现有多种项目类型可以创建。这些类型放一起容易搞混&#xff0c;于是记录一下各种类型的区别。 这里主要介绍windows控制台程序、MFC程序、WPF程序、WinForm程序的特点。 创建哪种应用&#xff1f; 创建控制台应用 Windows控制台程序…...

【Python语言速回顾】——数据可视化基础

目录 引入 一、Matplotlib模块&#xff08;常用&#xff09; 1、绘图流程&常用图 ​编辑 2、绘制子图&添加标注 ​编辑 3、面向对象画图 4、Pylab模块应用 二、Seaborn模块&#xff08;常用&#xff09; 1、常用图 2、代码示例 ​编辑 ​编辑 ​编辑 ​…...

java实现pdf文件添加水印,下载到浏览器

java实现pdf文件添加水印&#xff0c;下载到浏览器 添加itextpdf依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.8</version> </dependency>文件下载到浏览器和指定路径 …...

代码随想录算法训练营第四十一天丨 动态规划part04

01背包理论基础 见连接&#xff1a;代码随想录 416. 分割等和子集 思路 01背包问题 背包问题&#xff0c;大家都知道&#xff0c;有N件物品和一个最多能背重量为W 的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品只能用一次&#xff0c;求解…...

PyCharm免费安装和新手使用教程

简介 PyCharm是一款由JetBrains公司开发的Python集成开发环境&#xff08;IDE&#xff09;。它提供了一系列强大的功能&#xff0c;包括自动代码完成、语法高亮、自动缩进、代码重构、调试器、测试工具、版本控制工具等&#xff0c;使开发者可以更加高效地开发Python应用程序。…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器

一、原理介绍 传统滑模观测器采用如下结构&#xff1a; 传统SMO中LPF会带来相位延迟和幅值衰减&#xff0c;并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF)&#xff0c;可以去除高次谐波&#xff0c;并且不用相位补偿就可以获得一个误差较小的转子位…...

WEB3全栈开发——面试专业技能点P7前端与链上集成

一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染&#xff08;SSR&#xff09;与静态网站生成&#xff08;SSG&#xff09; 框架&#xff0c;由 Vercel 开发。它简化了构建生产级 React 应用的过程&#xff0c;并内置了很多特性&#xff1a; ✅ 文件系…...