存储管理的主要功能之一是合理地分配空间。请求页式管理是一种常用的虚拟存储管理技术。
这次的目的是通过请求页式管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。
要求如下
(1)
通过计算不同算法的命中率比较算法的优劣。同时也考虑了用户内存 容量对命中率的影响。 命中率 1 页面失效次数 页地址流长度 页面失效次数为每次访问相应指令时,该指令所对应的页不在内存中 的次数。 在本实验中,假定页面大小为 1k,用户虚存容量为 32k,用户内存容 量为 4 页到 32 页。 (2) produce_addstream 通过随机数产生一个指令序列,共 320 条指令。 A、 指令的地址按下述原则生成: 1) 50%的指令是顺序执行的 2)25%的指令是均匀分布在前地址部分 3) 25%的指令是均匀分布在后地址部分 10 B、 具体的实施方法是: 1) 在[0,319]的指令地址之间随机选取一起点 m; 2) 顺序执行一条指令,即执行地址为 m+1 的指令; 3) 在前地址[0,m+1]中随机选取一条指令并执行,该指令的地 址为 m’; 4) 顺序执行一条指令,地址为 m’+1 的指令 5) 在后地址[m’+2,319]中随机选取一条指令并执行; 6) 重复上述步骤 1)~5),直到执行 320 次指令 C、 将指令序列变换称为页地址流 在用户虚存中,按每 k 存放 10 条指令排列虚存地址,即 320 条指令在 虚存中的存放方式为: 第 0 条~第 9 条指令为第 0 页(对应虚存地址为[0,9]); 第 10 条~第 19 条指令为第 1 页(对应虚存地址为[10,19]); 。。。。。。 第 310 条~第 319 条指令为第 31 页(对应虚存地址为[310,319]); 按以上方式,用户指令可组成 32 页。 (3)计算并输出下属算法在不同内存容量下的命中率。 1)先进先出的算法(FIFO); 2)最近最少使用算法(LRU); 3)最佳淘汰算法(OPT); 4)最少访问页面算法(LFR);
下面给出Java代码的实现
import java.util.*; public class A { public static void mainString[] args) { Scanner sc = new ScannerSystem.in); System.out.println"Start memory management. "+"Producing address flow, wait for while, please. "); produce_addstream); forint a:stream) { System.out.printa+" "); } System.out.println" There are algorithms in the program 1、 Optimization algorithm " + "2、 Least recently used algorithm " + "3、 First in first out algorithm " + "4、 Least frequently used algorithm Select an algorithm number, please. "); int Num = sc.nextInt); switchNum) { case 3: FIFO3); break; case 2: LRU3); break; case 1: OPT3); break; case 4: LFU3); break; default: System.out.println"there is not the algorithm in the program"); break; } System.out.println"do you try again with anther algorithmy/n)"); forint i=2;i<32;i++) { System.out.println"---Msize="+i+"------"); FIFOi); LRUi); OPTi); LFUi); } } static List<Integer> stream; /** * @return 产生指令序列stream */ public static void produce_addstream){ stream=new ArrayList<>); do { int m = int)Math.random)*319));//起点 stream.addm+1);//执行m+1 int m2 = int)Math.random)*m+1))); stream.addm2);//执行m2 stream.addm2+1);//执行m2+1 int m3 = m2+2)+int)+Math.random)*319-m2-2)); stream.addm3);//执行[m2+2,319] }whilestream.size)<=320); } /** * 根据指令数找到页面 * @param zhiLing 所需指令 * @return 指令所在页面 */ public static int searchint zhiLing) { return zhiLing/10; } /** * 先进先出 * @param Msize 物理块数 */ public static void FIFOint Msize) { Queue<Integer> que = new LinkedList<>); Double C = 0.0;//未命中次数 forint i=0;i<stream.size);i++) { int zhiLing = stream.geti); int yeMian = searchzhiLing); ifque.containsyeMian)) { }else { C++; ifque.size)==Msize) { que.poll); } que.offeryeMian); } } C-=Msize; Double c = 1-double) C/320); System.out.println"FIFO: "+String.format"%.6f",c)+" Msize : "+Msize); } /** * 最近最久未使用算法 * @param Msize 物理块 */ public static void LRUint Msize) { Stack<Integer> stack = new Stack<>); Double C = 0.0;//未命中次数 forint i=0;i<stream.size);i++) { int zhiLing = stream.geti); int yeMian = searchzhiLing); ifstack.containsyeMian)) { stack.removeElementyeMian); stack.pushyeMian); }else { C++; ifstack.size)==Msize) { stack.removeElementstack.firstElement)); } stack.pushyeMian); } } C-=Msize; Double c = 1-double) C/320); System.out.println"LRU : "+String.format"%.6f",c)+" Msize : "+Msize); } /** * 最佳置换算法 * @param Msize 物理块 */ public static void OPTint Msize) { Double C = 0.0;//未命中次数 Set<Integer> set = new HashSet<>); forint i=0;i<stream.size);i++) { int zhiLing = stream.geti); int yeMian = searchzhiLing); ifset.containsyeMian)) { }else { C++; ifset.size)==Msize) { int max = -1;//最长时间不会使用的指令的页面 int[] temp = new int[32]; forint a:set) { forint j=i+1;j<stream.size);j++) { ifsearchstream.getj))==a) { temp[a]=j; break; } } } forint a:set) { ifmax==-1) max=a; iftemp[a]==0) { set.removea); break; } iftemp[a]>temp[max]) max=a; } ifset.size)==Msize) { set.removemax);//移除该页面 } } set.addyeMian); } } C-=Msize; Double c = 1-double) C/320); System.out.println"OPT : "+String.format"%.6f",c)+" Msize : "+Msize); } /** * 最少使用置换算法 * @param Msize */ public static void LFUint Msize) { Double C = 0.0;//未命中次数 Set<Integer> set = new HashSet<>); forint i=0;i<stream.size);i++) { int zhiLing = stream.geti); int yeMian = searchzhiLing); int[] temp = new int[32]; ifset.containsyeMian)) { }else { C++; ifset.size)==Msize) { int Min = -1; forint a:set) { forint j=i-1;j>=0;j--) { ifsearchstream.getj))==a) { temp[a]=j; break; } } } forint a:set) { ifMin==-1) { Min=a; continue; } iftemp[a]<temp[Min]) { Min=a; } } set.removeMin);//移除该页面 } set.addyeMian); temp[yeMian]++; } } C-=Msize; Double c = 1-double) C/320); System.out.println"LFU : "+String.format"%.6f",c)+" Msize : "+Msize); } }
(1) 通过计算不同算法的命中率比较算法的优劣。同时也考虑了用户内存
容量对命中率的影响。
命中率 =1– |
页面失效次数 |
|
页地址流长度 |
|
|
|
|
页面失效次数为每次访问相应指令时,该指令所对应的页不在内存中
的次数。
在本实验中,假定页面大小为 1k,用户虚存容量为 32k,用户内存容
量为 4页到 32页。
(2) produce_addstream 通过随机数产生一个指令序列,共 320 条指令。
A、指令的地址按下述原则生成:
1) 50%的指令是顺序执行的
2)25%的指令是均匀分布在前地址部分
3) 25%的指令是均匀分布在后地址部分
10
1) 在[0,319]的指令地址之间随机选取一起点 m;
2) 顺序执行一条指令,即执行地址为
m+1的指令;
3) 在前地址[0,m+1]中随机选取一条指令并执行,该指令的地
址为 m’;
4) 顺序执行一条指令,地址为 m’+1的指令
5) 在后地址[m’+2,319]中随机选取一条指令并执行;
6) 重复上述步骤 1)~5),直到执行 320次指令
C、 将指令序列变换称为页地址流
在用户虚存中,按每 k存放 10条指令排列虚存地址,即 320条指令在
虚存中的存放方式为:
第 0条~第 9条指令为第 0页(对应虚存地址为[0,9]);
第10
条~第
19 条指令为第 1 页(对应虚存地址为[10,19]);
。。。。。。
第310
条~第
319 条指令为第 31 页(对应虚存地址为[310,319]);
按以上方式,用户指令可组成 32页。
(3)计算并输出下属算法在不同内存容量下的命中率。
1)先进先出的算法(FIFO);
2)最近最少使用算法(LRU);
3)最佳淘汰算法(OPT);
4)最少访问页面算法(LFR);