改进型Clock算法

来源:互联网 发布:淘宝外围会场有用吗 编辑:程序博客网 时间:2024/06/07 09:12

算法过程:

改进型的Clock算法需要综合考虑某一内存页面的访问位和修改位来判断是否置换该页面。在实际编写算法过程中,同样可以用一个等长的整型数组来标识每个内存块的修改状态。访问位A和修改位M可以组成一下四种类型的页面。

1类(A =0, M = 0):表示该页面最近既未被访问,又未被修改,是最佳淘汰页。

2类(A =0, M = 1):表示该页面最近未被访问,但已被修改,并不是很好的淘汰页。

3类(A =1, M = 0):表示该页面最近已被访问,但未被修改,该页有可能再被访问。

4类(A =1, M = 1):表示该页最近已被访问且被修改,该页可能再被访问。

      执行步骤如下:

从指针所指示的当前位置开始,扫描循环队列,寻找第一类页面,将所遇到的第一个页面作为所选中的淘汰页。在第一次扫描期间不改变访问位A.

如果第一步失败,即查找一周后未遇到第一类页面,则开始第二轮扫描,寻找第二类页面,将所遇到的第一个这类页面作为淘汰页。在第二轮扫描期间,将所有扫描过的页面的访问位都置0.

如果第二步也失败,亦即未找到第二类页面,则将指针返回到开始位置,并将所有访问位复0.返回第一步。流程如下:


代码示例:

#ifndef PAGEREPLACEMENT_H#define PAGEREPLACEMENT_H#include <vector>class PageReplacement{public:PageReplacement();~PageReplacement();void run();void clockBetter();private:void addInfo(const std::vector<int>& modified) const;private:int pages;// 虚拟内存的尺寸Pint firstPageFramePos;// 工作面的起始位置pint pageFrames;// 工作面中包含的页数eint rateM;// 工作面移动率mstd::vector<int> seqVec;// 序列号std::vector<int> mem;// 内存块};#endif// PAGEREPLACEMENT_H

#include "PageReplacement.h"#include <iostream>#include <cstdlib>#include <list>PageReplacement::PageReplacement(): mem(3, -1){this->run();}PageReplacement::~PageReplacement(){}void PageReplacement::run(){std::cout << "请输入虚拟内存尺寸P:";std::cin >> pages;std::cout << "请输入工作面的起始位置p:";std::cin >> firstPageFramePos;std::cout << "请输入工作面中包含的页数e:";std::cin >> pageFrames;std::cout << "请输入工作面移动率m:";std::cin >> rateM;std::cout << "请输入在0和1之间的值t:";std::cin >> t;for (int i = 0; i < rateM; ++i){int randomNum = (rand() % pageFrames) + firstPageFramePos;seqVec.push_back(randomNum);}std::cout << "序列号:";for (int i = 0; i < seqVec.size(); ++i){std::cout << seqVec.at(i) << " ";}std::cout << std::endl;}void PageReplacement::clockBetter(){int nLack = 0;// 缺页数std::list<int> seqList(seqVec.begin(), seqVec.end());int nTotal = seqList.size();std::vector<int> visited(mem.size(), 0);std::vector<int> modified(mem.size(), 0);int cursor = 0;// 时钟指针while (!seqList.empty()){int head = *seqList.begin();// 取队头页面seqList.pop_front();int p;// 遍历内存块,找与队头页面相等的内存块for (p = 0; p < mem.size(); ++p){if (mem.at(p) == head)// 如果找到, 将其访问位置置1,clock指针循环下移,修改位可能同时被改动{visited[p] = 1;modified[p] = rand() % 2;cursor = p;cursor = (cursor + 1) % visited.size();this->addInfo(modified);break;}}if (p == mem.size())// 如果没有找到相等的内存块{bool loop = false;// 标识是否继续找被置换的页面++nLack;// 缺页率加1// 先找第一类页面,即访问位和修改位都为0do{bool firstClass = false;for (int i = 0; i < mem.size(); ++i){if (visited[i] == 0 && modified[i] == 0){mem[i] = head;// 置换页面visited[i] = 1;cursor = i;modified[cursor] = rand() % 2;// 修改位可能同时被改动cursor = (cursor + 1) % visited.size();// clock 指针循环下移firstClass = true;break;}}if (firstClass)//找到了第一类页面{this->addInfo(modified);break;}bool secondClass = false;// 如果没找到第一类页面// 开始找第二类页面,即访问位为0, 修改位为1for (int i = 0; i < mem.size(); ++i){mem[i] = head;// 置换页面visited[i] = 1;cursor = i;modified[cursor] = rand() % 2;cursor = (cursor + 1) % visited.size();// clock 指针循环下移secondClass = true;break;}if (secondClass)// 找到第二页面{this->addInfo(modified);break;}loop = true;// 两类都没找到,重新找第一类}while (loop);}}// 显示缺页率std::cout << "缺页率: " << (double)nLack/nTotal * 100 << "%" << std::endl;}void PageReplacement::addInfo(const std::vector<int>& modified) const{for (int i = 0; i < modified.size(); ++i){if (modified.at(i) == 1){ std::cout << mem.at(i) << "@    ";}else{ std::cout << mem.at(i) << "    ";}}std::cout << std::endl;}



0 0
原创粉丝点击