先进先出算法(FIFO)——页面置换
原创
最近操作系统实习,写了先进先出算法(FIFO)的代码来实现页面置换。
题目阐述如下:
设计四:页面置换
设计目的:
加深对请求页式存储管理实现原理的理解,掌握页面置换算法。
设计内容:
设计一个程序,有一个虚拟存储区和内存工作区,实现下述三种算法中的任意两种,计算访问命中率
(命中率=1-页面失效次数/页地址流长度)。附加要求:能够显示页面置换过程。算法包括:先进先出的
算法(FIFO)、最少使用算法(LRU)、最近未使用算法(NUR)该系统页地址流长度为320,页面失效
次数为每次访问相应指令时,该指令对应的页不在内存的次数。 程序首先用srand()和rand()函数分别进
行初始化、随机数定义和产生指令序列,然后将指令序列变换成相应的页地址流,并针对不同的算法计算
出相应的命中率。通过随机数产生一个指令序列。共320条指令,指令的地址按下述原则生成:
(1)50%的指令是顺序执行的。
(2)25%的指令是均匀分布在前地址部分。
(3)25%的指令是均匀分布在后地址部分。
具体的实施方法如下:
在【0,319】的指令地址之间随机选取一起点m。
顺序执行一条指令,即执行地址为m+1的指令。
在前地址【0,m+1】中随机选取一条指令并执行,该指令的地址为m’。
顺序执行一条指令,其地址为m’+1。
在后地址【m’+2,319】中随机选取一条指令并执行。
重复步骤(1)-(5),直到320次指令。
将指令序列变换为页地址流。
设:
页面大小为1KB。
用户内存容量4页到32页。(动态变化)
用户虚存容量为32KB。(32页)
在用户虚存中,按每K存放10条指令虚存地址,即320条指令在虚存中的存放方式为:
第0条~9条指令为第0页(对应虚存地址为【0,9】)。
第10条~19条指令为第1页(对应虚存地址为【10,19】)。
……
第310条~319条指令为第31页(对应虚拟地址为【310,319】)。
按以上方式,用户指令可组成32页。
计算每种算法在不同内存容量下的命中率。
分页管理是这样的,将内存和作业分成大小相等的页块,作业中的每个页块在不需要被使用时存放在外存中(虚拟存储区),
当需要使用时将其从外存调入内存页块中;根据题意,在外存中的页面顺序存储着指令,需要执行哪一条指令就找到其对应的
页面,若页面已在内存则无需再操作,否则此页面缺页,需要将其调入内存,当内存块未满时,只需要直接将其插入内存块中
若内存块已满,则需要调用先进先出算法淘汰出一个页面(将其调回外存),再将此页面调入。
首先通过 rand 函数和 srand 函数产生320条指令,计算每条指令对应的页面很简单,只需要将指令/10即可;得到页地址流后
(页地址流存放在数组中),从头到尾访问一遍页地址流,每访问一个页面就判断其是否已经在内存中,在无需操作,不在则
将其(使用FIFO)调入内存。
FIFO:在页面缺页并且内存块不足时,只需要将内存块中原先的页面依次淘汰即可。
假设页地址流为:1 2 3 5 4 3 8 11 12 6(内存块大小为 3 )
1 2 3 进入内存
5 2 3 1被调出
5 4 3 2被调出
5 4 3 命中
5 4 8 3被调出(形成一个循环)
11 4 8 5被调出
11 12 8 4被调出
11 12 6 8被调出(形成一个循环)
只要为内存块编号(不是为页面编号),用一个变量(初值为1)作为指针,此变量指向的内存块,就是被FIFO选中需要调出的
内存块,调出后变量+1,当变量大于内存块数时,再将其置为1(循环)。
- #include<stdio.h>
- #include<time.h>
- #include<stdlib.h>
- #define max_page 10 //内存页面数
- int Page[]={}; //虚拟存储区,存储320条指令,32个页面
- int Page_flu[]={}; //存储320个页地址流
- int count=; //计算随机产生的指令条数
- double lack_page=; //记录缺页数
- int count_page=max_page; //计算队列空页面个数
- int circle=; //在队列中循环指向被调出的进程
- struct Memo{ //用结构体存储内存页面块
- int num; //给每个页面编号,方便将其从队列中找到并调出
- int a;
- struct Memo *next;
- };
- int Judge_Page(int value){ //输入指令,返回指令对面的页面号
- return value/;
- }
- int scan_queen(struct Memo *hear,int value){ //value代表页面号,扫描队列,缺页返回0,否则返回1
- struct Memo *move;
- move=hear->next;
- while(move!=NULL){
- if(move->a==value){
- return ;
- }
- move=move->next;
- }
- return ;
- }
- void print(struct Memo *hear){ //输出内存页面
- struct Memo *move;
- move=hear->next;
- while(move!=NULL){
- printf("%d ",move->a);
- move=move->next;
- }
- printf("\n");
- }
- void insert(struct Memo *hear,int value,int ZL){ //将页面value调入内存,ZL为对应指令
- if(count_page>=){ //内存页面空间充足
- struct Memo *move;
- move=hear->next;
- while(move->a!=-){
- move=move->next;
- }
- move->a=value; //将页面调入
- count_page--;
- printf("页面 %d 被调入————对应指令为: %d \n",value,ZL);
- }
- else{ //内存空间不足,调出最先进入的页面后,将页面value后调入
- struct Memo *move;
- move=hear->next;
- while(move->num!=circle){ //circle存储的是需要调出的页面编号
- move=move->next;
- }
- printf("页面 %d 被调出,页面 %d 被调入————指令为: %d \n",move->a,value,ZL);
- move->a=value; //将页面调入
- circle++;
- if(circle==max_page+){ //当circle>max_page+1时,最先进入的页面为队列首页面
- circle=;
- }
- }
- print(hear); //调入后输出内存队列
- }
- void FIFO(struct Memo *hear){
- int i=;
- for(i=;i<=;i++){ //循环扫描页面
- if( scan_queen(hear,Page_flu[i])==){ //判断是否缺页
- lack_page++;
- insert(hear,Page_flu[i],Page[i]); //缺页将页面调入内存
- }
- else{ //不缺页
- printf("指令 %d 对应页面 %d 已在内存\n",Page[i],Page_flu[i]);
- }
- //不缺页无需操作
- }
- }
- void Pro_Page(){ //形成页地址流函数
- int m=; //在[0,319]的指令地址之间随机选取一起点m
- m=rand()%;
- Page[count]=m;
- count++;
- if(count==){
- return;
- }
- int m_=; //在前地址[0,m+1]中随机选取一条指令并执行
- m_=rand()%(m+);
- Page[count]=m_;
- count++;
- if(count==){
- return;
- }
- Page[count]=m_+;
- count++;
- if(count==){
- return;
- }
- int m__=;
- m__=(m_+)+rand()%( -(m_+)+ ); //在后地址[m_+2,319]的指令地址之间随机选取一条指令并执行
- Page[count]=m__;
- count++;
- if(count==){
- return;
- }
- Pro_Page();
- }
- void Flu(){ //将指令转换为页地址流
- int i=;
- for(i=;i<=;i++){
- Page_flu[i]=Judge_Page( Page[i] );
- }
- }
- int main(){
- struct Memo Stu[max_page+];
- struct Memo *hear;
- hear=&Stu[];
- //*************************************
- int i=;
- for(i=;i<=max_page;i++){ //形成内存页面队列
- if(i==max_page){
- Stu[i].a=-;
- Stu[i].next=NULL;
- Stu[i].num=i;
- break;
- }
- Stu[i].next=&Stu[i+];
- Stu[i].a=-;
- Stu[i].num=i;
- }
- //*************************************
- srand(time()); //放在Pro_Page函数外面
- Pro_Page(); //形成页地址流
- Flu(); //形成页地址流
- /*
- printf("页地址流:\n");
- for(i=0;i<=319;i++){ //输出页地址流
- printf("%d ",Page[i]);
- if(i%3==0 && i!=0){
- printf("\n");
- }
- }
- printf("\n");
- */
- //*************************************
- FIFO(hear);
- printf("缺页次数为: %0.0lf\n",lack_page);
- printf("命中率为:%lf\n",-lack_page/);
- return ;
- }
(运行结果部分截图)
11:33:47
2018-05-19
先进先出算法(FIFO)——页面置换的更多相关文章
- 缓存算法(页面置换算法)-FIFO、LFU、LRU
在前一篇文章中通过leetcode的一道题目了解了LRU算法的具体设计思路,下面继续来探讨一下另外两种常见的Cache算法:FIFO.LFU 1.FIFO算法 FIFO(First in First ...
- FIFO页面置换算法
本文以序列长度20的{ 7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1};以及页面4:为例: #include <stdio.h> #define Init ...
- 操作系统页面置换算法(opt,lru,fifo,clock)实现
选择调出页面的算法就称为页面置换算法.好的页面置换算法应有较低的页面更换频率,也就是说,应将以后不会再访问或者以后较长时间内不会再访问的页面先调出. 常见的置换算法有以下四种(以下来自操作系统课本). ...
- 页面置换算法 - FIFO、LFU、LRU
缓存算法(页面置换算法)-FIFO. LFU. LRU 在前一篇文章中通过leetcode的一道题目了解了LRU算法的具体设计思路,下面继续来探讨一下另外两种常见的Cache算法:FIFO. LFU ...
- [Operate System & Algorithm] 页面置换算法
页面置换算法是什么?我们看一下百度百科对页面置换算法给出的定义:在地址映射过程中,若在页面中发现所要访问的页面不在内存中,则产生缺页中断.当发生缺页中断时,如果操作系统内存中没有空闲页面,则操作系统必 ...
- 页面置换算 - FIFO、LFU、LRU
缓存算法(页面置换算法)-FIFO.LFU.LRU 在前一篇文章中通过leetcode的一道题目了解了LRU算法的具体设计思路,下面继续来探讨一下另外两种常见的Cache算法:FIFO.LFU 1 ...
- OS_页面置换算法:C++实现
一.实验目的: 通过模拟实现请求页式存储管理的几种基本页面置换算法,了解虚拟存储技术的特点,掌握虚拟存储请求页式存储管理中几种页面置换算法的基本思想和实现过程,并比较它们的效率. 二.实验内容: 本实 ...
- 操作系统 页面置换算法LRU和FIFO
LRU(Least Recently Used)最少使用页面置换算法,顾名思义,就是替换掉最少使用的页面. FIFO(first in first out,先进先出)页面置换算法,这是的最早出现的置换 ...
- (待续)C#语言中的动态数组(ArrayList)模拟常用页面置换算法(FIFO、LRU、Optimal)
目录 00 简介 01 算法概述 02 公用方法与变量解释 03 先进先出置换算法(FIFO) 04 最近最久未使用(LRU)算法 05 最佳置换算法(OPT) 00 简介 页面置换算法主要是记录内存 ...
随机推荐
- hbase shell基础和常用命令详解
HBase是Google Bigtable的开源实现,它利用Hadoop HDFS作为其文件存储系统,利用Hadoop MapReduce来处理HBase中的海量数据,利用Zookeeper作为协同服 ...
- SQL insert语句中插入带有特殊符号
1.插入数据库字符串中海油单引号,需要转义处理,例如插入“I‘m OK!” SQL语句: INSERT INTO tableTest(FileTXT) VALUES('I''m OK!') 2.如果S ...
- 二进制安装mariaDB
1.获取二进制安装包 获取二进制格式MariaDB安装包,可去官网下载. 因为是实验环境,所以选择了最新版. mariadb-10.2.12-linux-x86_64.tar.gz 2.解压 解压到 ...
- 初始python(三)
1. 循环 if, while, forbreak : 结束整个循环continue :跳出当前这次循环,但不结束整个循环else :结束整个循环后才执行,不能与break合用,但可以与continu ...
- Angular4 @HostBinding @HostListener
host属性 @Component({ selector: 'jhi-project', templateUrl: './project.html', styleUrls: [], host: { ' ...
- swift动态库与use_frameworks
使用Dynamic 的优势: 模块化,相对于Static Library,Framework可以将模块中的函数代码外的资源文件打包在一起. 共享可执行文件 iOS 有沙箱机制,不能跨App间共享共态库 ...
- git回滚线上代码
由于之前自己推代码的时候操作失误,push代码的时候没有push到线上的dev分支,而是push到了线上master分支(主要是因为没有在命令后写分支名,直接推到默认master分支上了),覆 ...
- nordic对苹果性能测试
环境: app采用nrf connect或lightblue均可: nordic从端采用nrf52840开发板pca10056: 说明与规定: (1)鉴于手机app无法主动连续快速发送多包数据,故只测 ...
- LayIM.AspNetCore Middleware 开发日记(五)Init接口实现细节
前言 “一旦开始了就要坚持下去“.为什么本文的第一句话是这么一句话呢,因为我经常就是开头轰轰烈烈,结果越来越枯燥,就不想做下去了.但是版图就放弃又那么不甘心,继续加油吧. 吐槽完毕,进入正题.在上一篇 ...
- git地址
登录地址:https://git.oschina.net/signup API地址:http://git.oschina.net/progit/