目录
目标
通过请求页式管理中页面置换算法模拟设计,计算并输出下属算法在不同内存容量下的命中率,比较算法优劣。
1)先进先出的算法(FIFO);
2)最近最少使用算法(LRU);
具体设计:
要求
a、 终端先显示:
Start memory management.
Producing address flow, wait for while, please.
b、 地址流、地址页号流生成后,终端显示:
There are algorithms in the program
1、 Optimization algorithm
2、 Least recently used algorithm
Select an algorithm number, please.
用户输入适当淘汰算法的号码,并按回车,若是第一次选择,输出相应的
地址页号流。然后输出该算法分别计算的用户内存从 2k~32k 时的命中率,
若输入的号码不再 1~2 中,则显示:
there is not the algorithm in the program,并重复 b。
c、 输出结果后,终端显示 “do you try again with anther algorithm(y/n)”。若键
入 y 则重复 b,否则结束
分析
使指令的地址按下述原则生成:
1) 50%的指令是顺序执行的
2)25%的指令是均匀分布在前地址部分
3)25%的指令是均匀分布在后地址部分
解决方案:
1) 在[0,319]的指令地址之间随机选取一起点 m;
2) 顺序执行一条指令,即执行地址为 m+1 的指令;
3) 在前地址[0,m]中随机选取一条指令并执行,该指令的地址为 m’;
4)顺序执行一条指令,地址为 m’+1 的指令
5) 在后地址[m’+2,319]中随机选取一条指令并执行;
6) 重复上述步骤 1)~5),直到执行 320 次指令
public void commandSequence() {
Random rand=new Random();
int i=0;
while(i<320) {
int m=rand.nextInt(320);
num[i++]=m+1;
int m1=rand.nextInt(m+1);
num[i++]=m1;
num[i++]=m1+1;
if(m1<317) {
int m2=rand.nextInt(317-m1)+m1+2;
num[i++]=m2;}
}
FIFO
该算法先淘汰的是最先进入内存的页面,考虑把进入内存的页面按进入时间先后次序链接成队列, 如果即将访问的数据在物理块中,跳过; 如果不在物理块中,顺序添到物理块中,缺页数+1;如果物理块满了,替换最先进的队头,缺页数+1;
public void FIFO(int msize) {
/*
* 如果即将访问的数据在物理块中,跳过; 如果不在物理块中,添到物理块中,缺页数+1;如果物理块满了,替换最先进的,缺页数+1;
*/
LinkedList<Integer> list = new LinkedList<Integer>();
//commandSequence();
int misspage = 0;// 缺页数
//int page[]=new int[32];
for (int i = 0; i < page.length; i++) {
if (list.contains(page[i])) {
continue;
} else {
if (list.size() !=msize) {
list.addLast(page[i]);
misspage++;
} else {
list.removeFirst();
list.addLast(page[i]);
misspage++;
}
}
}
double targetpage=1.0-(misspage/10*1.0/32);
System.out.println("内存空间(物理块)为" + msize + "时\n,缺页数为:" +misspage + "\n命中率为:" +targetpage + "\n");
}
LRU
它淘汰的是最近最久未被访问的页面,还是先把他们先链接起来,如果即将要访问的数据在物理块内,标记其已存在的序列下标,删除它再在末尾重新添加;如果将要访问的数据不在物理块内,添加到物理块,缺页数+1;如果满了,替换最久未访问的头,缺页数+1;
public void LRU(int msize) {
/*
* 如果即将要访问的数据在物理块内,标记其已存在的序列下标,删除它再在末尾重新添加
* 如果将要访问的数据不在物理块内,添加到物理块,缺页数+1;如果满了,替换最久未访问的
*/
int misspage = 0;
LinkedList<Integer> list = new LinkedList<Integer>();
for (int i = 0; i < page.length; i++) {
if (list.contains(page[i])) {
int flag = list.indexOf(page[i]);// 标记序列下标
list.remove(flag);
list.addLast(page[i]);
} else {
if (list.size() != msize) {
list.addLast(page[i]);
misspage++;
} else {
list.removeFirst();
list.addLast(page[i]);
misspage++;
}
}
}
double targetpage=1.0-(misspage*1.0/10/32);
System.out.println("内存空间(物理块)为" + msize + "时\n,缺页数为:" + misspage + "\n命中率为:" +targetpage+ "\n");
}
代码实现
package com.as.storage;
import java.util.InputMismatchException;
import java.util.LinkedList;
import java.util.Random;
import java.util.Scanner;
public class Manage {
int num[] = new int[320];// 指令序列
int page[] = new int[320];// 对应的页码
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int choice = 0;
System.out.println("Start memory management \n Producing address flow ,wait for while,please.\n");
Manage my = new Manage();
my.commandSequence();
while (true) {
System.out.println(
"There are algorithms in the program\n1、First in first out algorithm\n2、Least recently used algorithm\nSelect an algotithm number,please.(0-exit)\n");
try {
choice = sc.nextInt();
} catch (InputMismatchException e) {
System.out.println("输入数据格式有误,请重新输入!");
sc.nextInt();
continue;
}
switch (choice) {
case 1:
for (int msize = 4; msize <= 32; msize++) {
my.FIFO(msize);
}
break;
case 2:
for (int msize = 4; msize <= 32; msize++) {
my.LRU(msize);
}
break;
default:
System.out.println("there is not the algorithm in the program,please select the number again(1-4)");
break;
}
System.out.println("do you try again with another algorithm(y/n)?");
String cho;
try{
cho=sc.next().toLowerCase();
}catch (InputMismatchException e) {
System.out.println("输入数据格式有误,请重新输入!");
sc.nextInt();
continue;
}
if(cho.equals("n")) {
sc.close();break;
}else if(cho.equals("y")) {sc.nextLine();}
else {System.out.println("无效输入,请输入y/n!!!");}
}
}
public void commandSequence() {
Random rand=new Random();
int i=0;
while(i<320) {
int m=rand.nextInt(320);
num[i++]=m+1;
int m1=rand.nextInt(m+1);
num[i++]=m1;
num[i++]=m1+1;
if(m1<317) {
int m2=rand.nextInt(317-m1)+m1+2;
num[i++]=m2;}
}
System.out.println("***************生成320个随机数据*****************");
for (int j = 0; j < 320; j++) {
System.out.print(num[j] + "\t");
if ((j+1)% 10 == 0) {
System.out.println();
}
}
System.out.println("*********************对应的页码数************************");
for (int k = 0; k < 320; k++) {
page[k] = num[k] / 10;
System.out.print(page[k] + "\t");
if ((k+1) % 10 == 0) {
System.out.println();
}
}
}
/**
* 先进先出
*/
public void FIFO(int msize) {
/*
* 如果即将访问的数据在物理块中,跳过; 如果不在物理块中,添到物理块中,缺页数+1;如果物理块满了,替换最先进的,缺页数+1;
*/
LinkedList<Integer> list = new LinkedList<Integer>();
//commandSequence();
int misspage = 0;// 缺页数
//int page[]=new int[32];
for (int i = 0; i < page.length; i++) {
if (list.contains(page[i])) {
continue;
} else {
if (list.size() !=msize) {
list.addLast(page[i]);
misspage++;
} else {
list.removeFirst();
list.addLast(page[i]);
misspage++;
}
}
}
double targetpage=1.0-(misspage/10*1.0/32);
System.out.println("内存空间(物理块)为" + msize + "时\n,缺页数为:" +misspage + "\n命中率为:" +targetpage + "\n");
}
/**
* 最近最少使用
*/
public void LRU(int msize) {
/*
* 如果即将要访问的数据在物理块内,标记其已存在的序列下标,删除它再在末尾重新添加
* 如果将要访问的数据不在物理块内,添加到物理块,缺页数+1;如果满了,替换最久未访问的
*/
int misspage = 0;
LinkedList<Integer> list = new LinkedList<Integer>();
for (int i = 0; i < page.length; i++) {
if (list.contains(page[i])) {
int flag = list.indexOf(page[i]);// 标记序列下标
list.remove(flag);
list.addLast(page[i]);
} else {
if (list.size() != msize) {
list.addLast(page[i]);
misspage++;
} else {
list.removeFirst();
list.addLast(page[i]);
misspage++;
}
}
}
double targetpage=1.0-(misspage*1.0/10/32);
System.out.println("内存空间(物理块)为" + msize + "时\n,缺页数为:" + misspage + "\n命中率为:" +targetpage+ "\n");
}
}
运行结果
算法命中率比较
当用户的内存容量(物理块大小)增加时,命中率也随之增加,到内存容量32的时候,基本在90%的命中率。
比较下来内存容量在20左右以下的时候,FIFO命中率大多更高些,以上的话,LRU更高些;