实验目的:
通过模拟实现请求页式存储管理的几种基本页面置换算法,了解虚拟存储技术的特点,掌握虚拟存储请求页式存储管理中几种基本页面置换算法的基本思想和实现过程,并比较它们的效率。
实验仪器及材料:
微型计算机、红帽子Linux系统
任务:虚拟存储技术中,
FIFO
和LFU两种换页算法的模拟实现和效率比较
程序说明
本程序由以下三大部分组成:
(1)
一共
320
条指令顺序存储,即数字
0~319
是这
320
条指令的顺序的逻辑地址。通过随机数产生一个指令访问序列
(
实际上是指令的逻辑地址序列
)
。指令的访问序列按下述原则生成:
A
:
50%
的指令是顺序执行的
B
:
25%
的指令要实现向前跳转,均匀分布在前地址部分
C
:
25%
的指令要实现向后跳转,均匀分布在后地址部分
具体的实施方法是:
A
:在
[0
,
319]
的指令地址之间随机选取一起点
m
,执行指令
m
B
:顺序执行下一条指令,即执行地址为
m+1
的指令
C
:在前地址
[0
,
m+1]
中随机选取一条指令并执行,该指令的地址为
m’
D
:顺序执行下一条指令,其地址为
m’+1
E
:在后地址
[m’+2
,
319]
中随机选取一条指令
m
并执行
F
:重复步骤
B-E
,直到执行完
320
条指令
(2)
将每条指令的逻辑地址变换为页号和页内偏移地址
在用户的逻辑地址空间中,按每页存放
10
条指令
排列逻辑地址,即
320
条指令在逻辑地址空间中的存放方式为:
第
0
条
-
第
9
条指令为第
0
页(对应逻辑地址为
[0
,
9]
)
第
10
条
-
第
19
条指令为第
1
页(对应逻辑地址为
[10
,
19]
)
………………………………
第
310
条
-
第
319
条指令为第
31
页(对应逻辑地址为
[310
,
319]
)
即:每条指令的逻辑地址中,最低位是页内偏移量,高位是页号。
按以上方式,用户指令可组成
32
页;
用户虚存容量为
32
块,即可以运行
32
页长度的作业;
用户实际分到的内存容量
4
块
~32
块。
(3)
分别使用
FIFO
算法和
LFU
算法,计算机给用户进程的这
32
页分配
4
,
5
,
…
,
32
个页面
(
内存块
)
时其缺页率。
Vir_Page.h
- #ifndef _VIR_PAGE_H_
- #define _VIR_PAGE_H_
- class Vir_Page
- {
- public:
- Vir_Page(unsigned int vpn,int rpn,unsigned int c)
- :vir_page_no(vpn),real_page_no(rpn),count(c){}
- Vir_Page(){}
- bool operator <(const Vir_Page &rvp) const
- {
- return count < rvp.count;
- }
- void set_Vir_Page_No(unsigned int vpn)
- {
- vir_page_no = vpn;
- }
- unsigned int get_Vir_Page_No() const
- {
- return vir_page_no;
- }
- void set_Real_Page_No(int rpn)
- {
- real_page_no = rpn;
- }
- int get_Real_Page_No() const
- {
- return real_page_no;
- }
- void set_Count(unsigned int c)
- {
- count = c;
- }
- unsigned int get_Count() const
- {
- return count;
- }
- private:
- unsigned int vir_page_no;
- int real_page_no;
- unsigned int count;
- };
- #endif
Real_Page.h
- #ifndef _REAL_PAGE_H_
- #define _REAL_PAGE_H_
- class Real_Page
- {
- public:
- Real_Page(unsigned int vpn,unsigned int rpn)
- :vir_page_no(vpn),real_page_no(rpn){}
- Real_Page(){}
- Real_Page& operator=(const Real_Page &rp)
- {
- this->vir_page_no = rp.vir_page_no;
- this->real_page_no = rp.real_page_no;
- return *this;
- }
- void set_Vir_Page_No(unsigned int vpn)
- {
- vir_page_no = vpn;
- }
- unsigned int get_Vir_Page_No() const
- {
- return vir_page_no;
- }
- void set_Real_Page_No(unsigned int rpn)
- {
- real_page_no = rpn;
- }
- unsigned int get_Real_Page_No() const
- {
- return real_page_no;
- }
- private:
- unsigned int vir_page_no;
- unsigned int real_page_no;
- };
- #endif
Memory_Manager.h
- #ifndef _MEMORY_MANAGER_H_
- #define _MEMORY_MANAGER_H_
- #include <vector>
- #include <deque>
- #include <queue>
- #include "Vir_Page.h"
- #include "Real_Page.h"
- using std::vector;
- using std::queue;
- using std::deque;
- class Memory_Manager
- {
- public:
- Memory_Manager();
- void FIFO(unsigned int real_page_num);
- void LSU(unsigned int real_page_num);
- private:
- void init(unsigned int real_page_num);
- static const unsigned int instruc_num;
- vector<unsigned int> instruc;
- vector<unsigned int> page;
- vector<unsigned int> offset;
- vector<Vir_Page> page_table;
- queue<Real_Page> free_real_page_table;
- deque<Real_Page> busy_real_page_table;
- };
- #endif
Memory_Manager.cpp
- #include <iostream>
- #include "Memory_Manager.h"
- #include <algorithm>
- using std::cout;
- using std::endl;
- const unsigned int Memory_Manager::instruc_num = 320;
- Memory_Manager::Memory_Manager()
- :instruc(instruc_num),page(instruc_num),offset(instruc_num)
- {
- unsigned int r;
- srand(2000);
- vector<unsigned int>::iterator i_it = instruc.begin();
- vector<unsigned int>::iterator p_it = page.begin();
- vector<unsigned int>::iterator o_it = offset.begin();
- r = rand() % instruc_num;
- for(;i_it != instruc.end();)
- {
- *i_it++ = r;
- *p_it++ = r / 10;
- *o_it++ = r % 10;
- r = *(i_it - 1);
- *i_it++ = r;
- *p_it++ = r / 10;
- *o_it++ = r % 10;
- r = rand() % *(i_it - 1);
- *i_it++ = r;
- *p_it++ = r / 10;
- *o_it++ = r % 10;
- r = *(i_it - 1);
- *i_it++ = r;
- *p_it++ = r / 10;
- *o_it++ = r % 10;
- r = *(i_it - 1) + (rand() % (instruc_num - *(i_it - 1)));
- }
- }
- void Memory_Manager::init(unsigned int real_page_num)
- {
- unsigned int i;
- unsigned int vir_page_num = (instruc_num % 10) ? instruc_num / 10 + 1 : instruc_num / 10;
- if(!page_table.empty())
- {
- page_table.clear();
- }
- for(i = 0;i < vir_page_num;i++)
- {
- page_table.push_back(Vir_Page(i,-1,0));
- }
- while(!free_real_page_table.empty())
- {
- free_real_page_table.pop();
- }
- for(i = 0;i < real_page_num;i++)
- {
- free_real_page_table.push(Real_Page(0,i));
- }
- if(!busy_real_page_table.empty())
- {
- busy_real_page_table.clear();
- }
- }
- void Memory_Manager::FIFO(unsigned int real_page_num)
- {
- unsigned int i,page_fault_counter = 0;
- Vir_Page vp;
- Real_Page rp;
- init(real_page_num);
- for(i = 0;i < instruc_num;i++)
- {
- vp = page_table.at(page.at(i));
- if(vp.get_Real_Page_No() == -1)
- {
- page_fault_counter++;
- if(free_real_page_table.empty())
- {
- rp = busy_real_page_table.at(0);
- busy_real_page_table.pop_front();
- page_table.at(rp.get_Vir_Page_No()).set_Real_Page_No(-1);
- free_real_page_table.push(rp);
- }
- rp = free_real_page_table.front();
- free_real_page_table.pop();
- rp.set_Vir_Page_No(vp.get_Vir_Page_No());
- busy_real_page_table.push_back(rp);
- page_table.at(page.at(i)).set_Real_Page_No(rp.get_Real_Page_No());
- }
- }
- cout<<"FIFO:%"<<static_cast<double>(page_fault_counter) / instruc_num<<endl;
- }
- void Memory_Manager::LSU(unsigned int real_page_num)
- {
- unsigned int i,page_fault_counter = 0;
- Vir_Page vp;
- Real_Page rp;
- vector<Vir_Page>::iterator vp_it,tmp_it;
- deque<Real_Page>::iterator rp_it;
- init(real_page_num);
- for(i = 0;i < instruc_num;i++)
- {
- vp = page_table.at(page.at(i));
- if(vp.get_Real_Page_No() == -1)
- {
- page_fault_counter++;
- if(free_real_page_table.empty())
- {
- vector<Vir_Page> tmp(page_table);
- sort(tmp.begin(),tmp.end());
- tmp_it = tmp.begin();
- while((tmp_it->get_Real_Page_No() == -1) && (tmp_it != tmp.end()))
- {
- tmp_it++;
- }
- rp_it = busy_real_page_table.begin();
- while((rp_it->get_Real_Page_No() != tmp_it->get_Real_Page_No()) && (rp_it != busy_real_page_table.end()))
- {
- rp_it++;
- }
- page_table.at(rp_it->get_Vir_Page_No()).set_Real_Page_No(-1);
- free_real_page_table.push(Real_Page(0,rp_it->get_Real_Page_No()));
- busy_real_page_table.erase(rp_it);
- }
- rp = free_real_page_table.front();
- free_real_page_table.pop();
- rp.set_Vir_Page_No(vp.get_Vir_Page_No());
- busy_real_page_table.push_back(rp);
- page_table.at(page.at(i)).set_Real_Page_No(rp.get_Real_Page_No());
- page_table.at(page.at(i)).set_Count(1);
- }
- else
- {
- page_table.at(page.at(i)).set_Count(page_table.at(page.at(i)).get_Count() + 1);
- }
- }
- cout<<"LSU:%"<<static_cast<double>(page_fault_counter) / instruc_num<<endl;
- }
main.cpp
- #include <iostream>
- #include "Memory_Manager.h"
- #include "Vir_Page.h"
- using std::cout;
- using std::endl;
- int main()
- {
- Memory_Manager mm;
- int i;
- for(i = 4;i <= 32;i++)
- {
- cout<<"Real Page Number:"<<i<<endl;
- mm.FIFO(i);
- mm.LSU(i);
- }
- return 0;
- }
没有注释,呵呵,很不好的习惯,我是知道的。
部分运行结果: