【OS实验四】存储管理(仿真实验)

实验目的:

通过模拟实现请求页式存储管理的几种基本页面置换算法,了解虚拟存储技术的特点,掌握虚拟存储请求页式存储管理中几种基本页面置换算法的基本思想和实现过程,并比较它们的效率。
实验仪器及材料:
微型计算机、红帽子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

Code:
  1. #ifndef _VIR_PAGE_H_   
  2. #define _VIR_PAGE_H_   
  3.   
  4.     class Vir_Page   
  5.     {   
  6.     public:   
  7.         Vir_Page(unsigned int vpn,int rpn,unsigned int c)   
  8.         :vir_page_no(vpn),real_page_no(rpn),count(c){}   
  9.            
  10.         Vir_Page(){}   
  11.            
  12.         bool operator <(const Vir_Page &rvp) const  
  13.         {   
  14.             return count < rvp.count;   
  15.         }   
  16.            
  17.         void set_Vir_Page_No(unsigned int vpn)   
  18.         {   
  19.             vir_page_no = vpn;   
  20.         }   
  21.            
  22.         unsigned int get_Vir_Page_No() const  
  23.         {   
  24.             return vir_page_no;   
  25.         }   
  26.            
  27.         void set_Real_Page_No(int rpn)   
  28.         {   
  29.             real_page_no = rpn;   
  30.         }   
  31.            
  32.         int get_Real_Page_No() const    
  33.         {   
  34.             return real_page_no;   
  35.         }   
  36.            
  37.         void set_Count(unsigned int c)   
  38.         {   
  39.             count = c;   
  40.         }   
  41.            
  42.         unsigned int get_Count() const  
  43.         {   
  44.             return count;   
  45.         }   
  46.            
  47.     private:   
  48.         unsigned int vir_page_no;   
  49.         int real_page_no;   
  50.         unsigned int count;   
  51.     };   
  52.   
  53. #endif   
  54.   

Real_Page.h

Code:
  1. #ifndef _REAL_PAGE_H_   
  2. #define _REAL_PAGE_H_   
  3.   
  4.     class Real_Page   
  5.     {   
  6.     public:   
  7.         Real_Page(unsigned int vpn,unsigned int rpn)   
  8.         :vir_page_no(vpn),real_page_no(rpn){}   
  9.            
  10.         Real_Page(){}   
  11.            
  12.         Real_Page& operator=(const Real_Page &rp)   
  13.         {   
  14.             this->vir_page_no = rp.vir_page_no;   
  15.             this->real_page_no = rp.real_page_no;   
  16.             return *this;   
  17.         }   
  18.            
  19.         void set_Vir_Page_No(unsigned int vpn)   
  20.         {   
  21.             vir_page_no = vpn;   
  22.         }   
  23.            
  24.         unsigned int get_Vir_Page_No() const  
  25.         {   
  26.             return vir_page_no;   
  27.         }   
  28.            
  29.         void set_Real_Page_No(unsigned int rpn)   
  30.         {   
  31.             real_page_no = rpn;   
  32.         }   
  33.            
  34.         unsigned int get_Real_Page_No() const  
  35.         {   
  36.             return real_page_no;   
  37.         }   
  38.            
  39.            
  40.     private:   
  41.         unsigned int vir_page_no;   
  42.         unsigned int real_page_no;   
  43.     };   
  44.   
  45. #endif   

Memory_Manager.h

Code:
  1. #ifndef _MEMORY_MANAGER_H_   
  2. #define _MEMORY_MANAGER_H_   
  3.   
  4. #include <vector>   
  5. #include <deque>   
  6. #include <queue>   
  7. #include "Vir_Page.h"   
  8. #include "Real_Page.h"   
  9.   
  10.     using std::vector;   
  11.     using std::queue;   
  12.     using std::deque;   
  13.   
  14.     class Memory_Manager   
  15.     {   
  16.     public:   
  17.         Memory_Manager();   
  18.         void FIFO(unsigned int real_page_num);   
  19.         void LSU(unsigned int real_page_num);   
  20.     private:   
  21.         void init(unsigned int real_page_num);   
  22.         static const unsigned int instruc_num;   
  23.         vector<unsigned int> instruc;   
  24.         vector<unsigned int> page;   
  25.         vector<unsigned int> offset;   
  26.         vector<Vir_Page> page_table;   
  27.         queue<Real_Page> free_real_page_table;   
  28.         deque<Real_Page> busy_real_page_table;         
  29.     };   
  30. #endif   
  31.   

Memory_Manager.cpp

Code:
  1. #include <iostream>   
  2. #include "Memory_Manager.h"   
  3. #include <algorithm>   
  4.   
  5. using std::cout;   
  6. using std::endl;   
  7.   
  8. const unsigned int Memory_Manager::instruc_num = 320;   
  9.   
  10. Memory_Manager::Memory_Manager()   
  11. :instruc(instruc_num),page(instruc_num),offset(instruc_num)   
  12. {   
  13.     unsigned int r;   
  14.     srand(2000);   
  15.     vector<unsigned int>::iterator i_it = instruc.begin();   
  16.     vector<unsigned int>::iterator p_it = page.begin();   
  17.     vector<unsigned int>::iterator o_it = offset.begin();   
  18.     r = rand() % instruc_num;   
  19.     for(;i_it != instruc.end();)   
  20.     {   
  21.         *i_it++ = r;   
  22.         *p_it++ = r / 10;   
  23.         *o_it++ = r % 10;   
  24.         r = *(i_it - 1);   
  25.         *i_it++ = r;   
  26.         *p_it++ = r / 10;   
  27.         *o_it++ = r % 10;   
  28.         r = rand() % *(i_it - 1);   
  29.         *i_it++ = r;   
  30.         *p_it++ = r / 10;   
  31.         *o_it++ = r % 10;   
  32.         r = *(i_it - 1);   
  33.         *i_it++ = r;   
  34.         *p_it++ = r / 10;   
  35.         *o_it++ = r % 10;   
  36.         r = *(i_it - 1) + (rand() % (instruc_num - *(i_it - 1)));   
  37.     }   
  38. }   
  39.   
  40. void Memory_Manager::init(unsigned int real_page_num)   
  41. {   
  42.     unsigned int i;   
  43.     unsigned int vir_page_num = (instruc_num % 10) ? instruc_num / 10 + 1 : instruc_num / 10;   
  44.        
  45.     if(!page_table.empty())   
  46.     {   
  47.         page_table.clear();   
  48.     }   
  49.        
  50.     for(i = 0;i < vir_page_num;i++)   
  51.     {   
  52.         page_table.push_back(Vir_Page(i,-1,0));   
  53.     }   
  54.        
  55.     while(!free_real_page_table.empty())   
  56.     {   
  57.         free_real_page_table.pop();   
  58.     }   
  59.        
  60.     for(i = 0;i < real_page_num;i++)   
  61.     {   
  62.         free_real_page_table.push(Real_Page(0,i));   
  63.     }   
  64.        
  65.     if(!busy_real_page_table.empty())   
  66.     {   
  67.         busy_real_page_table.clear();   
  68.     }   
  69. }   
  70.   
  71. void Memory_Manager::FIFO(unsigned int real_page_num)   
  72. {   
  73.     unsigned int i,page_fault_counter = 0;   
  74.     Vir_Page vp;   
  75.     Real_Page rp;   
  76.        
  77.     init(real_page_num);   
  78.        
  79.     for(i = 0;i < instruc_num;i++)   
  80.     {   
  81.         vp = page_table.at(page.at(i));   
  82.         if(vp.get_Real_Page_No() == -1)   
  83.         {   
  84.             page_fault_counter++;   
  85.             if(free_real_page_table.empty())   
  86.             {   
  87.                 rp = busy_real_page_table.at(0);   
  88.                 busy_real_page_table.pop_front();   
  89.                 page_table.at(rp.get_Vir_Page_No()).set_Real_Page_No(-1);   
  90.                 free_real_page_table.push(rp);   
  91.             }   
  92.             rp = free_real_page_table.front();   
  93.             free_real_page_table.pop();   
  94.             rp.set_Vir_Page_No(vp.get_Vir_Page_No());   
  95.             busy_real_page_table.push_back(rp);   
  96.             page_table.at(page.at(i)).set_Real_Page_No(rp.get_Real_Page_No());   
  97.         }   
  98.     }   
  99.        
  100.     cout<<"FIFO:%"<<static_cast<double>(page_fault_counter) / instruc_num<<endl;   
  101. }   
  102.   
  103. void Memory_Manager::LSU(unsigned int real_page_num)   
  104. {   
  105.     unsigned int i,page_fault_counter = 0;   
  106.     Vir_Page vp;   
  107.     Real_Page rp;   
  108.     vector<Vir_Page>::iterator vp_it,tmp_it;   
  109.     deque<Real_Page>::iterator rp_it;   
  110.        
  111.     init(real_page_num);   
  112.        
  113.     for(i = 0;i < instruc_num;i++)   
  114.     {   
  115.         vp = page_table.at(page.at(i));   
  116.         if(vp.get_Real_Page_No() == -1)   
  117.         {   
  118.             page_fault_counter++;   
  119.             if(free_real_page_table.empty())   
  120.             {   
  121.                 vector<Vir_Page> tmp(page_table);   
  122.                 sort(tmp.begin(),tmp.end());   
  123.                 tmp_it = tmp.begin();   
  124.                 while((tmp_it->get_Real_Page_No() == -1) && (tmp_it != tmp.end()))   
  125.                 {   
  126.                     tmp_it++;   
  127.                 }   
  128.                    
  129.                 rp_it = busy_real_page_table.begin();   
  130.                 while((rp_it->get_Real_Page_No() != tmp_it->get_Real_Page_No()) && (rp_it != busy_real_page_table.end()))   
  131.                 {   
  132.                     rp_it++;   
  133.                 }   
  134.                 page_table.at(rp_it->get_Vir_Page_No()).set_Real_Page_No(-1);   
  135.                 free_real_page_table.push(Real_Page(0,rp_it->get_Real_Page_No()));   
  136.                 busy_real_page_table.erase(rp_it);   
  137.             }   
  138.             rp = free_real_page_table.front();   
  139.             free_real_page_table.pop();   
  140.             rp.set_Vir_Page_No(vp.get_Vir_Page_No());   
  141.             busy_real_page_table.push_back(rp);   
  142.             page_table.at(page.at(i)).set_Real_Page_No(rp.get_Real_Page_No());   
  143.             page_table.at(page.at(i)).set_Count(1);   
  144.         }   
  145.         else  
  146.         {   
  147.             page_table.at(page.at(i)).set_Count(page_table.at(page.at(i)).get_Count() + 1);   
  148.         }   
  149.     }   
  150.        
  151.     cout<<"LSU:%"<<static_cast<double>(page_fault_counter) / instruc_num<<endl;   
  152. }   
  153.    

main.cpp

Code:
  1. #include <iostream>   
  2. #include "Memory_Manager.h"   
  3. #include "Vir_Page.h"   
  4.   
  5. using std::cout;   
  6. using std::endl;   
  7.   
  8. int main()   
  9. {   
  10.     Memory_Manager mm;   
  11.     int i;   
  12.     for(i = 4;i <= 32;i++)   
  13.     {   
  14.         cout<<"Real Page Number:"<<i<<endl;   
  15.         mm.FIFO(i);   
  16.         mm.LSU(i);   
  17.     }   
  18.        
  19.     return 0;   
  20. }   

    没有注释,呵呵,很不好的习惯,我是知道的。

    部分运行结果:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值