1.实验内容:模拟请求页式存储管理中硬件的地址转换和缺页中断,并用先进先出调度算法(FIFO)处理缺页中断;
2.要求:
① 指令序列的设定可以执行拟定,格式如表3;
② 在完成了FIFO换页策略后
③ 作业允许的页框数m在不同情况下的缺页中断率;
④ 程序运行时显示地址转变和页面调入调出过程。
3.步骤:
① 设计页表及其数据结构:
页号
标志:是否在主存;
页框号:设定页表在主存的位置;
修改标志:设定页面在主存中是否修改过;
磁盘上位置:设定页面在辅存中的位置;
例如:装入新页置换旧页时,若旧页在执行中没有被修改过,则不必将该页重写磁盘。因此,页表中增加是否修改过的标志,执行“存”指令和“写”指令时将对应的修改标志置成“1”表示修改过,否则为“0”表示未修改过。
表 1 页表格式
页号 | 标志 | 页框号 | 修改标志 | 在磁盘上位置 |
②设计一个地址转换程序半模拟硬件的地址转换和缺页中断。
当访问的页在主存时则形成绝对地址,但不去模拟指令的执行,可以输出转换后的绝对地址来表示一条指令已执行完成。当访问的页不在主存中时,则输出“*页号”来表示硬件产生了一次缺页中断。模拟地址转换流程见图1.1。
③ 设计FIFO页面调度程序;
FIFO页面调度算法总是先调出作业中最先进入主存中的哪一页。因此可以用一个数组来表示(或构成)页号队列。数据中每个元素是该作业已在主存中的页面号,假定分配给作业的页(框)数为m,且该作业开始的m页已装入主存,则数组可由m个元素构成。
P[0],P[1],P[2],…,P[m-1]
它们的初值为P[0]:=0,P[1]:=1,P[2]:=2,…,P[m-1]:=m-1
用一指针K指示当要调入新页时应调出的页在数组中的位置,K的初值为“0”,当产生缺页中断后,操作系统总是选择P[K]所指出的页面调出,然后执行。
④ 设计输入数据和输出格式;
如: 假定主存中页框大小为1024个字节,现有一个共7页的作业,其副本已在磁盘上。系统为该作业分配了4个页框,且该作业的第0页至第3页已装入内存,其作3页未主存,该作业的页表如下:
页号 | 标志 | 页框号 | 修改标志 | 在磁盘上位置 |
0 | 1 | 5 | 0 | 011 |
1 | 1 | 8 | 0 | 012 |
2 | 1 | 9 | 0 | 013 |
3 | 1 | 1 | 0 | 021 |
4 | 0 | 0 | 022 | |
5 | 0 | 0 | 023 | |
6 | 0 | 0 | 121 |
如果该作业依次执行的指令序列如附表3所示:
操作 | 页号 | 页内地址 | 操作 | 页号 | 页内地址 |
+ | 0 | 070 | 移位 | 4 | 053 |
- | 1 | 050 | + | 5 | 023 |
× | 2 | 015 | 存 | 1 | 037 |
存 | 3 | 021 | 取 | 2 | 078 |
取 | 0 | 056 | + | 4 | 001 |
- | 6 | 040 | 存 | 6 | 084 |
依次执行上述指令调试你所设计的程序(仅模拟指令的执行,不考虑序列中具体操作的执行)。
⑤ 编程上机,验证结果。
4.实验报告:
为进一步考察程序的执行,可自行确定若干组指令,运行程序,核对执行结果实验报告:
① 实验题目;
② 程序中所用的数据结构及说明;
③ 打印一份源程序并附上必要的说明;
④ 按照指令的执行序列,打印输出结果:绝对地址或调出、调入的页号。
P[K]:=要装入的新页页号
K:=(k+1)mod m
在实验中不必实际地启动磁盘执行调出一页和装入一页的工作,而用输出“OUT调出的页号”和“IN要装入的新页页号”来模拟一次调出和装入过程,模拟程序的流程图见附图1.1。
按流程控制过程如下:
提示:输入指令的页号和页内偏移和是否存指令
,若d为-1则结束,否则进入流程控制过程,得P1和d,查表在主存时绝对地址P1×1024+d
import java.util.ArrayList;
class Order
{
String operate;
int o_page;
int address;
public Order(String operate, int o_page, int address)
{
this.operate = operate;
this.o_page = o_page;
this.address = address;
}
}
class Page
{
int p_page;
int flag;
int frame;
int change_flag;
int place;
public Page(int p_page, int flag, int frame, int change_flag, int place)
{
this.p_page = p_page;
this.flag = flag;
this.frame = frame;
this.change_flag = change_flag;
this.place = place;
}
int getAddress(int x)
{
return frame * 1024 + x;
}
}
public class FIFO
{
public static void main(String[] args)
{
double num = 0;
int operationCount = 0;
int real_page, out_page, k = 0;
int[] p = {0, 1, 2, 3};
ArrayList<Page> page = new ArrayList<>();
page.add(new Page(0, 1, 5, 0, 11));
page.add(new Page(1, 1, 8, 0, 12));
page.add(new Page(2, 1, 9, 0, 13));
page.add(new Page(3, 1, 1, 0, 21));
page.add(new Page(4, 0, 0, 0, 22));
page.add(new Page(5, 0, 0, 0, 23));
page.add(new Page(6, 0, 0, 0, 121));
ArrayList<Order> order = new ArrayList<>();
order.add(new Order("+", 0, 70));
order.add(new Order("-", 1, 50));
order.add(new Order("×", 2, 15));
order.add(new Order("存", 3, 21));
order.add(new Order("取", 0, 56));
order.add(new Order("-", 6, 40));
order.add(new Order("移位", 4, 53));
order.add(new Order("+", 5, 23));
order.add(new Order("存", 1, 37));
order.add(new Order("取", 2, 78));
order.add(new Order("+", 4, 1));
order.add(new Order("存", 6, 84));
while (!order.isEmpty()) {
System.out.println("操作为 " + order.get(0).operate);
System.out.println("页号为 " + order.get(0).o_page);
real_page = order.get(0).o_page;
if (page.get(real_page).flag == 1)
{
if ("存".equals(order.get(0).operate))
{
page.get(real_page).change_flag = 1;
}
System.out.println("绝对地址是: " + page.get(real_page).getAddress(order.get(0).address));
}
else
{
System.out.println("*" + order.get(0).o_page);
num++;
out_page = p[k];
if (page.get(out_page).change_flag == 1)
{
System.out.println("OUT: " + out_page);
System.out.println("//该页已被修改过,需调出后重写磁盘,该页在磁盘中的位置为:" + page.get(out_page).place);
}
System.out.println("IN: " + real_page);
p[k] = real_page;
k = (k + 1) % 4;
page.get(real_page).flag = 1;
page.get(out_page).flag = 0;
page.get(real_page).change_flag = 0;
if ("存".equals(order.get(0).operate))
{
page.get(real_page).change_flag = 1;
}
page.get(real_page).frame = page.get(out_page).frame;
}
System.out.println("----------------------------");
order.remove(0);
operationCount++;
}
double fault_rate = num / operationCount;
System.out.println("当前数据下的FIFO算法缺页率为: " + fault_rate);
}
}
实验结果如下:(截图太长,此为作者粘贴复制的)
操作为 +
页号为 0
绝对地址是: 5190
----------------------------
操作为 -
页号为 1
绝对地址是: 8242
----------------------------
操作为 ×
页号为 2
绝对地址是: 9231
----------------------------
操作为 存
页号为 3
绝对地址是: 1045
----------------------------
操作为 取
页号为 0
绝对地址是: 5176
----------------------------
操作为 -
页号为 6
*6
IN: 6
----------------------------
操作为 移位
页号为 4
*4
IN: 4
----------------------------
操作为 +
页号为 5
*5
IN: 5
----------------------------
操作为 存
页号为 1
*1
OUT: 3
//该页已被修改过,需调出后重写磁盘,该页在磁盘中的位置为:21
IN: 1
----------------------------
操作为 取
页号为 2
*2
IN: 2
----------------------------
操作为 +
页号为 4
绝对地址是: 8193
----------------------------
操作为 存
页号为 6
*6
IN: 6
----------------------------
当前数据下的FIFO算法缺页率为: 0.5