操作系统实验:页面置换算法之FIFO和LRU算法的实现c++

2 篇文章 0 订阅
2 篇文章 0 订阅
该程序实现了页面置换算法的模拟,包括FIFO和LRU两种策略。通过随机数生成页面走向,计算并比较了两种算法的缺页率,以评估内存管理对系统性能的影响。在主函数中,用户可以输入页面长度和内存块数量,程序会输出各自的缺页率。
摘要由CSDN通过智能技术生成

页面置换算法模拟程序


目的:

熟悉页面置换算法及其实现,引入计算机系统性能评价方法的概念。

内容:

编制页面置换算法的模拟程序。

要求:

(1) 用随机数方法产生页面走向,页面走向长度为L。
(2) 根据页面走向,分别采用FIFO和LRU算法进行页面置换,统计缺页率。
(3) 假定可用内存块和页表长度 (作业的页面数)分别为m和k,初始时,作业页面都不在内存。

随机数产生程序:

function random: real:
begin Seed: =125.0∗(seed+1.0)
Seed: =Seed−8192.0∗trunc (seed/8192)
random: = (Seed+0.5)/8192
end;

上述随机数发生函数产生的随机数为0.0~1.0,稍另变化就可得到0~n−1之间的随机数。
程序开始时,应对变量Seed (实型)赋初值。


FIFO和LRU大致思想

"""FIFO算法:
页面先进先出,如果队列中已经有相同的算法,那么就不入队列,如果没有,那么就代替最先进入内存块的页面
"""
"""LRU算法:
选择最近最久未使用的页面予以淘汰。该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间 t,当须淘汰一个页面时,选择现有页面中其 t 值最大的,即最近最少使用的页面予以淘汰。
"""

接下来是代码部分:

/// 生成随机数函数
// Page Replacement Algorithm build in 2021.06.05
// file name: seed.h
// Edit by @Michael Zhou
#pragma once
namespace rs
{
	auto RandInt(long long seed, const unsigned low = 0, unsigned high = 1) -> int;
}

随机函数函数体:

#include "seed.h"
#include <cmath>


auto rs::RandInt(const long long seed, const unsigned low, const unsigned high) -> int
{
	double seed_old = (1 + static_cast<double>(seed)) * static_cast<double>(125);
	double seed_new = seed_old - 8192.0 * trunc(seed_old / 8192);

	double random = (seed_new + 0.5) / 8192;

	int decLen = 0;

	while (random < 10e+6)
	{
		random *= 10;
	}
	random = static_cast<unsigned>(random) % high + static_cast<unsigned>(low);
	return static_cast<int>(random);
}

page replacement algorithm:

// Edit by @Michael Zhou

// #pragma once
#ifndef PAGE_REPLACEMENT_H
#define PAGE_REPLACEMENT_H

#include <vector>
#include <string>

class PageReplacement //NOLINT
{
protected:
	struct MemBlock
	{
		int info;
		int priority;
	};

public:
	int priority = 0;
	std::vector<MemBlock> m_memBlocks;
	std::vector<int> page_query;
	int m_nAlgorithm{};
	int m_nMemBlockLen;
	int m_nPageLen;

	int m_nLostPages;

	PageReplacement() = default;
	PageReplacement(int memoryBlock, int pageLength, int* lp);
	~PageReplacement() = default;
	friend std::ostream& operator <<(std::ostream& out, PageReplacement lru);
	auto GetPageLostRate(const std::string& algorithm) -> double;

	auto Clean()->void;
protected:
	static auto EncodeAlgorithm(const std::string& algorithm) -> int;
private:
	auto DoLruAlgorithm()->void;
	void DoFifoAlgorithm();

	int FindLeastPriorityIndex();
	int FindSameInfo(int index);
};

类方法:

#include "Page Replacement.h"
#include "PrExceptions.h"

#include <utility>
#include <iostream>
using namespace std;

PageReplacement::PageReplacement(const int memoryBlock, const int pageLength, int* lp): m_nLostPages(0)
{
	/// <summary>
	/// init page replacement algorithm.
	/// </summary>
	/// <param name="memoryBlock">refers to 'memery blocks'</param>
	/// <param name="pageLength">'page length'</param>
	/// <param name="lp">'page content'</param>
	/// <param name="algorithm">the algorithms Name</param>
	this->m_nMemBlockLen = memoryBlock;
	this->m_nPageLen = pageLength;
	this->page_query = vector<int>(lp, lp + pageLength);
	this->m_memBlocks.resize(memoryBlock, {-1, -1});
}

auto PageReplacement::GetPageLostRate(const string& algorithm) -> double
{
	/// <summary>
	/// get page lost rate.
	/// </summary>
	/// <param name="algorithm">method</param>
	/// <returns>rate</returns>
	m_nAlgorithm = EncodeAlgorithm(algorithm);
	if (m_nAlgorithm == 0)
	{
		Clean();
		DoFifoAlgorithm();
	}
	else if (m_nAlgorithm == 1)
	{
		Clean();
		DoLruAlgorithm();
	}
	double lostRage = static_cast<double>(m_nLostPages) / m_nPageLen;
#ifdef _DEBUG
	cout << "# from _Debug:\n\tlostRage: " << lostRage << endl;
#endif

	return lostRage;
}

auto PageReplacement::Clean() -> void
{
	m_nAlgorithm = -1;
	m_memBlocks = vector<MemBlock>(m_nMemBlockLen, {-1, -1});
	m_nLostPages = 0;
	priority = 0;
}

auto PageReplacement::EncodeAlgorithm(const std::string& algorithm) -> int
{
	int t = 0;
	if (algorithm == "FIFO")
	{
		t = 0;
	}
	else if (algorithm == "LRU")
	{
		t = 1;
	}
	else
	{
		cout << PrException::AlgorithmExceptions("\"" + algorithm + "\"" + " is not permitted!").What() << endl;
	}
	return t;
}

auto PageReplacement::DoLruAlgorithm() -> void
{
	for (int i = 0; i < static_cast<int>(page_query.size()); i ++, priority++)
	{
		int findSameInfoIndex = -1;
		if (i > 0)
		{
			findSameInfoIndex = FindSameInfo(i);
		}
		if (findSameInfoIndex == -1)
		{
			if (i < static_cast<int>(m_memBlocks.size()))
			{
				m_memBlocks[i].info = page_query[i];
				m_memBlocks[i].priority = priority;
				m_nLostPages++;
			}
			else
			{
				int lpi = FindLeastPriorityIndex();
				m_memBlocks[lpi].info = page_query[i];
				m_memBlocks[lpi].priority = priority;
				m_nLostPages++;
			}
		}
		else
		{
			m_memBlocks[FindSameInfo(i)].info = page_query[i];
			m_memBlocks[FindSameInfo(i)].priority = priority;
		}
	}
}

void PageReplacement::DoFifoAlgorithm()
{
	for (int i = 0; i < static_cast<int>(page_query.size()); i ++, priority++)
	{
		int findSameInfoIndex = -1;
		if (i > 0)
		{
			findSameInfoIndex = FindSameInfo(i);
		}
		if (findSameInfoIndex == -1)
		{
			if (i < static_cast<int>(m_memBlocks.size()))
			{
				m_memBlocks[i].info = page_query[i];
				m_memBlocks[i].priority = priority;
				m_nLostPages++;
			}
			else
			{
				int lpi = FindLeastPriorityIndex();
				m_memBlocks[lpi].info = page_query[i];
				m_memBlocks[lpi].priority = priority;
				m_nLostPages++;
			}
		}
		else
		{
		}
	}
}

int PageReplacement::FindLeastPriorityIndex()
{
	int min_index = 0;
	for (int j = 0; j < static_cast<int>(m_memBlocks.size()); j++)
	{
		if (m_memBlocks[j].priority < m_memBlocks[min_index].priority)
		{
			min_index = j;
		}
	}
	return min_index;
}

int PageReplacement::FindSameInfo(const int index)
{
	for (int i = 0; i < static_cast<int>(m_memBlocks.size()); i++)
	{
		if (page_query[index] == m_memBlocks[i].info)
		{
			return i;
		}
	}
	return -1;
}

ostream& operator<<(ostream& out, PageReplacement lru)
{
	return out;
}

异常处理:

// Page Replacement Algorithm build in 2021.06.05
// file name: PrExceptions.h
// Edit by @Michael Zhou

#pragma once
#include <stdexcept>
#include <iostream>

namespace PrException
{
	class AlgorithmExceptions final :
		public std::exception
	{
	protected:	
		std::string m_p;

	public:
		explicit AlgorithmExceptions(const std::string& c);

		//what()函数返回错误信息
		virtual std::string What();
	};
}
#include "PrExceptions.h"

PrException::AlgorithmExceptions::AlgorithmExceptions(const std::string& c)
{
	m_p = c;
}

std::string PrException::AlgorithmExceptions::What()
{
	std::cout << R"(The algorithm must be "FIFO"(First in first out) or "LRU"(Least recently used))" << std::endl;
	return m_p;
}

接下来是主函数部分:
main.cpp

// // 05
// // Edit by Michael
// //

#include <iostream>
#include <ctime>
#include <Windows.h>
#include <iomanip>

#include "seed.h"
#include "Page Replacement.h"

using namespace std;

int main() //NOLINT
{
	// ReSharper disable once CppInconsistentNaming
	int L;
	int m;

#ifdef _DEBUG
	m = 4;
	int debug_page_query[] = {4, 3, 2, 1, 4, 3, 5, 4, 3, 2, 1, 5};
	L = sizeof(debug_page_query) / sizeof(int);
#else
	cout << "Enter the Page Length:" << endl;
	cin >> L;
	cin.ignore();
	cout << "Enter the memory blocks: " << endl;
	cin >> m;
	cin.ignore();
#endif

	auto* lp = new int[L];

#ifndef _DEBUG
	auto start = clock();
	for (int i = 0; i < L; i ++)
	{
		*(lp + i) = rs::RandInt(static_cast<long long>(i), 0, 5);
	}
#endif

#ifdef _DEBUG
	for (int i = 0; i < L; i ++)
	{
		*(lp + i) = *(debug_page_query + i);
	}
#endif

	// undebug
	PageReplacement testLru(m, L, lp);

	double rateLru = testLru.GetPageLostRate("LRU");
	double rateFifo = testLru.GetPageLostRate("FIFO");


#ifndef _DEBUG
	cout.setf(ios::fixed);
	cout << setprecision(2) << endl;
	cout << "Page Lost Rate:" << endl;
	cout << "    FiFo: " << (rateFifo * 100) << "%" << endl;
	cout << "    LRU:  " << (rateLru * 100) << "%" << endl;
#endif

	system("pause");
	delete[] lp;
	return 0;
}

看完别忘了点赞呐!笔芯~
转载请注明出处

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值