一、目的和要求
- 目的
存储管理的主要功能之一是合理地分配主存空间。请求页式管理是一种常用的虚拟存储管理技术。
本实验的目的是通过请求页式存储管理中页面置换算法的模拟设计,来了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。
- 要求
模拟页式虚拟存储管理中硬件的地址转换和缺页中断的处理过程,并用先进先出调度算法(FIFO)处理缺页中断。
二、提示
- 为了装入一个页面而必须调出一页时,如果被选中调出的页面在执行中没有修改过,则不必把该页重新写到磁盘上(因磁盘上已有副本)。因此,在页表中可以增加是否修改过的标志,当执行“存”指令、“写”指令时把对应页的修改标志置成“1”,表示该页修改过,否则为“0”,表示该页未修改过。页表格式如表3-1所示。
表3-1 页表格式
页 号 | 标 志 | 主存块号 | 修改标志 | 磁盘上的位置 |
- 设计一个地址转换程序来模拟硬件的地址转换和缺页中断处理过程。当访问的页在主存时则形成绝对地址,但不去模拟指令的执行,可用输出转换后的绝对地址来表示一条指令已完成。当访问的页不在主存时则输出“*该页页号”来表示硬件产生了一次缺页中断。模拟地址转换的程序流程如图3-1所示。
- 编制一个FIFO页面调度程序。FIFO页面调度算法总是先调出作业中最先进入主存的那一页,因此,可以用一个数组来构成页号队列。数组中每个元素是该作业已在主存的页面号,假定分配给作业的主存块数为m,且该作业开始的m页已装入主存,则数组可由m个元素组成:
P[0],P[1],…,P[m-1]
它们的初值为
P[0]∶=0,P[1]∶=1,…,P[m-1]∶= m-1
用一指针k指示当要装入新页时应调出的页在数组的位置,k的初值为“0”。
当产生缺页中断后,操作系统总是选择P[k]所指出的页面调出,然后执行
P[k]∶=要装入的新页页号
k∶=(k+1)mod m
在实验中不必实际地启动磁盘执行调出一页和装入一页的工作,而用输出“OUT调出的页号”和“IN要装入的新页页号”来模拟一次调出和装入的过程。模拟程序的流程见图3-1。
- 假定主存的每块长度为1024个字节,现有一个共7页的作业,其副本已在磁盘上。系统为该作业分配了4块主存块,且该作业的第0页至第3页已经装入主存,其余3页尚未装入主存,该作业的页表见表3-2所示。
表3-2 作业的页表
页号 | 标志 | 主存块号 | 修改标志 | 在磁盘上的位置 |
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-3所示。
表3-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 |
依次执行上述的指令序列来调试你所设计的程序(仅模拟指令的执行,不必考虑指令序列中具体操作的执行)
- 为了检查程序的正确性,可自行确定若干组指令序列,运行设计的程序,核对执行结果。
#include<iostream>
#include<queue>
#include<map>
using namespace std;
#define PAGE_NUM 7
#define BLOCK_NUM 4
struct PageTable{
int id;
int flag;
int mainMemory;
int isModefy;
int diskPos;
}pageTable[PAGE_NUM];
int mainBlock[BLOCK_NUM]={5,8,9,1};
int order[BLOCK_NUM];
int page[BLOCK_NUM];
void printInfo()
{
cout<<"页号\t\t\t标志\t\t\t主存块号\t\t修改标志\t\t磁盘位置"<<endl;
for(int i=0;i<PAGE_NUM;i++){
cout<<pageTable[i].id<<"\t\t\t"<<pageTable[i].flag
<<"\t\t\t"<<pageTable[i].mainMemory<<"\t\t\t"<<pageTable[i].isModefy<<"\t\t\t"<<pageTable[i].diskPos<<endl;
}
}
void init(){
for(int i=0;i<BLOCK_NUM;i++){
order[i] = i;
page[i] = i;
}
for(int i=0;i<PAGE_NUM;i++){
// freopen("in.txt","r",stdin);
cin>>pageTable[i].id>>pageTable[i].flag>>pageTable[i].mainMemory>>pageTable[i].isModefy>>pageTable[i].diskPos;
}
}
int isHit(int pageId){
for(int i=0;i<BLOCK_NUM;i++){
if(pageTable[i].flag == 1){
cout<<"命中"<<endl;
return i;
}
}
return -1;
}
void fifo(int pageId){
cout<<"调出页"<<pageTable[page[order[0]]].id<<"释放主存块"<<mainBlock[page[order[0]]]<<endl;
pageTable[page[order[0]]].flag = 0;
pageTable[page[order[0]]].isModefy = 0;
pageTable[page[order[0]]].flag = 0;
pageTable[page[order[0]]].mainMemory = -1;
if(pageTable[page[order[0]]].isModefy == 1){
cout<<"该调出页已经被修改,需要重新写出"<<endl;
}
int t = order[0];
for(int i=1;i<BLOCK_NUM;i++){
order[i-1] = order[i];
}
order[BLOCK_NUM-1] = t;
// 调入
page[order[BLOCK_NUM-1]] = pageId;
pageTable[pageId].flag = 1;
pageTable[pageId].mainMemory = mainBlock[order[BLOCK_NUM-1]];
}
void execute(){
char op;
while(cin>>op&&op!='#'){
int pageId;
int pageAddress;
cin>>pageId>>pageAddress;
if(pageId >= PAGE_NUM){
cout<<"页号大于页数,请重新输入"<<endl;
continue;
}
if(pageTable[pageId].flag == 1){
cout<<"经地址变换后,该指令的形式为"<<endl<<endl;
cout<<"操作数"<<"\t"<<"页号"<<"\t"<<"绝对地址"<<endl;
cout<<op<<"\t"<<pageId<<"\t"<<pageAddress+pageTable[pageId].diskPos<<endl<<endl;
if(op == 'd' || op == 'w'){
pageTable[pageId].isModefy = 1;
}
}else{
fifo(pageId);
}
printInfo();
}
}
int main()
{
init();
execute();
return 0;
}
For this problem ,just simulate the process of page managament.The requirement of this experiment is FIFO,which means that the page will be transfered out is which is transfered in fristly.
The datastructure is a page table ,which comprise some kinds of information.
struct PageTable{
int id;
int flag;
int mainMemory;
int isModefy;
int diskPos;
}pageTable[PAGE_NUM];
id -->the id of page.
flag -->identify wether the page is in mainMemory
mainMemory -->if flag == 1,then mainMemory show the block number,else display -1;
isModefy --> a flag that show the state whether the page has been modefied.
diskPos-->show the position where page in the disk(not memory);
See function init();
just init the infomation,input
function isHit();
when user input a instruction ,like + 0 70.
this function will judge wether the block 0 is in mainmemory.If so ,return a value 1,else return 0(false);
function printInfo();
just print the information of current state ,display all infomation.
function fifo();
this is the core function of this procedure.This function will be called when that function isHit() return a value 0,Which means there is no free block so that OS must transter out a block.
Red circle is my logic design,I use three arrays to realize the process.
mainBlock stroge the block bumber .
page stroge the page number ,which in the main memory.
due to the algorithm fifo,we should confirm the order of page.So I add a array name order to point the opder of page .
It may be a little difficult to comprehense other's producure.But ,come on.