页面置换算法模拟程序
目的:
熟悉页面置换算法及其实现,引入计算机系统性能评价方法的概念。
内容:
编制页面置换算法的模拟程序。
要求:
(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;
}
看完别忘了点赞呐!笔芯~
转载请注明出处