【计算机操作系统】存储管理的 C++ 实现(附源码)

一、实验目的

  存储管理的主要功能之一是合理地分配空间。请求页式管理是一种常用的虚拟存储管理技术。本实验的目的是通过请求页式管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。因为源码中我对一些关键步骤的注释已经比较清晰了,所以在本文中不会再对每一个细节都进行分析,只分析整体的代码结构和所使用到的设计模式。

  博客内所有文章均为 原创,所有示意图均为 原创,若转载请附原文链接。

二、实验内容

2.1 实现多种页面置换算法并比较算法优劣

  • (1)通过计算不同算法的命中率比较算法的优劣。同时也考虑了用户内存容量对命中率的影响(命中率 = 1 - 页面失效次数 ÷ 页地址流长度)。页面失效次数为每次访问相应指令时,该指令所对应的页不在内存中的次数。在本实验中,假定页面大小为1k,用户虚存容量为32k,用户内存容量为4页到32页。

  • (2)produce_addstream 通过随机数产生一个指令序列,共320条指令。
    A、指令的地址按下述原则生成:
     1)50%的指令是顺序执行的
     2)25%的指令是均匀分布在前地址部分
     3)25%的指令是均匀分布在后地址部分
    B、具体的实施方法是:
     1)在[0,319]的指令地址之间随机选取一起点m;
     2)顺序执行一条指令,即执行地址为m+1的指令;
     3)在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m’;
     4)顺序执行一条指令,地址为m’+1的指令
     5)在后地址[m’+2,319]中随机选取一条指令并执行;
     6)重复上述步骤1)~5),直到执行320次指令
    C、将指令序列变换称为页地址流
     在用户虚存中,按每k存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为:
     第0条~第9条指令为第0页(对应虚存地址为[0,9]);
     第10条~第19条指令为第1页(对应虚存地址为[10,19]);
     。。。。。。
     第310条~第319条指令为第31页(对应虚存地址为[310,319]);
     按以上方式,用户指令可组成32页。

  • (3)计算并输出下述算法在不同内存容量下的命中率。
      1)最佳置换算法(OPT);
      2)先进先出算法(FIFO);
      3)最近最久未使用页面置换(LRU);
      4)最少使用页面淘汰算法(LFU)

三、流程图

3.1 算法流程

在这里插入图片描述

四、设计思想

4.1 设计思路

  该实验中需要实现四种页面置换算法,分别为 OPT、FIFO、LRU和LFU,通过分析发现这四种算法中都存在一种优先级的关系,只不过优先级的属性不同,比如在LRU算法中,优先级为最近一次访问距离现在的时间,即页面最近一次访问距离现在的时间越短其优先级越高,而对于LFU算法,优先级页面被访问的次数,即用户内存中页面被访问的次数越多,其优先级也就越高,越不容易被淘汰,而FIFO算法中的优先级就是进入用户空间的时间,时间越短优先级越高,OPT中的优先级就是页面下次被访问据当前的时间,时间越短优先级越高。
  当我们找到了这几种算法中的优先级关系后,通过分析可以发现优先级队列可以很好的满足这个需求,而对于LRU算法的实现其实最简单的方法是如果被访问的页面存在于用户空间中,那么就将其提升至队尾(队尾入页面,队头出页面),但是为了保证多个算法的统一性,还是决定采用相同的抽象算法来实现。
  而对于整体的代码结构设计,可以采用 模板方法设计模式 + 策略设计模式 的方法来进行实现,增强算法整体的灵活性、可扩展性和可维护性。

4.2 代码分析

  首先是Page结构体,该结构体保存了 OPT、LRU 和 LFU 算法所需的各项属性。

struct Page
{
   
	Page() : elapsed_time_since_last_visit(0), used_count(0) {
   }
	int virtual_memory_index;
	// OPT
	TimeSlice be_used_again_time_;
	// LRU
	TimeSlice elapsed_time_since_last_visit;
	// LFU
	int used_count;
};

  其次是 UserMemorySpace 类,该类是用户内存空间的抽象,提供了一个模板参数 PriorityCmp,用来指定优先级队列中的优先级关系定义,并且在它的属性中存在 page_index_array_ 数组和 memory_queue_优先级队列,其中前者是保存所有的虚拟页面信息,PageInfo 中持有 Page 的引用,同时记录该页面是否存在于用户空间优先级队列中,而后者的 memory_queue_ 就是物理用户内存空间,前者的存在主要是了便于对物理用户内存空间内页面的查找定位,而该类的功能总结起来就是提供了对物理用户内存空间的基础操作(确定一个页面是否存在于用户空间中,获取一个页面,插入一个页面等等)。

template<typename PriorityCmp>
class UserMemorySpace
{
   
public:
	struct PageInfo
	{
   
		bool in_user_memory = false;
		PagePtr page = new Page();
	};

	typedef PageInfo * PageInfoPtr;

	UserMemorySpace(int user_memory_size, int virtual_memory_size)
		: user_memory_size_(user_memory_size)
		, virtual_memory_size_(virtual_memory_size)
		, memory_queue_(new std::priority_queue<PagePtr, std::vector<PagePtr>, PriorityCmp>())
		, page_index_array_(new std::vector<PageInfoPtr>(virtual_memory_size));

	inline void initPageIndexArray();
	void push(int virtual_page_index);
	PagePtr pop();
	inline PageInfoPtr getPageInfo(int virtual_page_index);
	inline PagePtr getPage(int virtual_page_index);
	inline bool pageInUserMemory(int virtual_page_index);
	void freshPageOrder();
	std::vector<PagePtr> * getPagesInUserMemory();

private:
	int user_memory_size_;
	int virtual_memory_size_;
	// help find page in memory queue
	std::vector<PageInfoPtr> * page_index_array_;
	std::priority_queue<PagePtr, std::vector<PagePtr>, PriorityCmp> * memory_queue_;
};

  接下来是页面置换算法,这里采用了模板方法设计模式,其中PageReplacementAlgorithm为所有是算法的抽象基类,不提供具体实现,只规定算法所必须实现的方法,且其持有一个UserMemorySpace的引用。

// 页面置换算法基类
class PageReplacementAlgorithm;

// 最佳页面置换算法
class OPTPageReplacementAlgorithm : public PageReplacementAlgorithm;

// 先来先服务页面置换算法
class FIFOPageReplacementAlgorithm : public PageReplacementAlgorithm;

// LRU 页面置换算法
class LRUPageReplacementAlgorithm : public PageReplacementAlgorithm;

// LFU 页面置换算法
class LFUPageReplacementAlgorithm : public PageReplacementAlgorithm;

  最后两个模块类,PageReplacement是对页面置换逻辑的封装,主要用于聚合PageReplacementAlgorithm和UserMemorySpace,并设置相应的物理用户内存空间的大小,而PageReplacementWrapper是对PageReplacement的进一步封装,指引用户输入相应的数据(具体实现请见源码)。

template<typename PageReplacementAlgorithm, typename PriorityCmp>
class PageReplacement;

class PageReplacementWrapper;

五、代码实现

#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <cstdlib>
#include <ctime>
#include <unistd.h>
#include <iomanip>

class Util
{
   
public:
	static inline int getRandom(const int min_val, const int max_val, int match)
	{
   
		srand(time(0) + match);
		return ((max_val - min_val - 1) == 0) ? min_val : rand() % (max_val - min_val - 1) + min_val;
	}
};

typedef int TimeSlice;
int page_replacement_count = 0;
std::vector<double> * ratio = new std::vector<double>(28, 0);

struct Page
{
   
	Page() : elapsed_time_since_last_visit(0), used_count(0) {
   }
	int virtual_memory_index;
	// OPT
	TimeSlice be_used_again_time_;
	// LRU
	TimeSlice elapsed_time_since_last_visit;
	// LFU
	int used_count;
};

typedef Page * PagePtr;

template<typename PriorityCmp>
class UserMemorySpace
{
   
public:
	struct PageInfo
	{
   
		bool in_user_memory = false;
		PagePtr page = new Page();
	};

	typedef PageInfo * PageInfoPtr;

	UserMemorySpace(int user_memory_size, int virtual_memory_size)
		: user_memory_size_(user_memory_size)
		, virtual_memory_size_(virtual_memory_size)
		, memory_queue_(new std::priority_queue<PagePtr, std::vector<PagePtr>, PriorityCmp>())
		, page_index_array_(new std::vector<PageInfoPtr>(virtual_memory_size))
	{
   
		initPageIndexArray();
	}

	
【实验目的】 1. 通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解; 2. 熟悉虚存管理的各种页面淘汰算法; 3. 通过编写和调试地址转换过程的模拟程序以加强对地址转换过程的了解。 【实验准备】 1.虚拟存储器的管理方式  段式管理  页式管理  段页式管理 2.页面置换算法  先进先出置换算法  最近最久未使用置换算法  Clock置换算法  其他置换算法 【实验内容】 1. 实验题目 设计一个请求页式存储管理方案。并编写模拟程序实现之。产生一个需要访问的指令地址流。它是一系列需要访问的指令的地址。为不失一般性,你可以适当地(用人工指定地方法或用随机数产生器)生成这个序列,使得 50%的指令是顺序执行的。25%的指令均匀地散布在前地址部分,25%的地址是均匀地散布在后地址部分。为简单起见。页面淘汰算法采用 FIFO页面淘汰算法,并且在淘汰一页时,只将该页在页表中抹去。而不再判断它是否被改写过,也不将它写回到辅存。 2. 具体做法 产生一个需要访问的指令地址流;指令合适的页面尺寸(例如以 1K或2K为1页);指定内存页表的最大长度,并对页表进行初始化;每访问一个地址时,首先要计算该地址所在的页的页号,然后查页表,判断该页是否在主存——如果该页已在主存,则打印页表情况;如果该页不在主存且页表未满,则调入一页并打印页表情况;如果该页不足主存且页表已满,则按 FIFO页面淘汰算法淘汰一页后调入所需的页,打印页表情况;逐个地址访问,直到所有地址访问完毕。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值