操作系统页面置换算法实现

最简单的页面置换算法是先入先出(FIFO)法。这种算法的实质是,总是选择在主存中停留时间最长(即最老)的一页置换,即先进入内存的页,先退出内存。理由是:最早调入内存的页,其不再被使用的可能性比刚调入内存的可能性大。建立一个FIFO队列,收容所有在内存中的页。被置换页面总是在队列头上进行。当一个页面被放入内存时,就把它插在队尾上。 [1] 

这种算法只是在按线性顺序访问地址空间 [1]  时才是理想的,否则效率不高。因为那些常被访问的页,往往在主存中也停留得最久,结果它们因变“老”而不得不被置换出去。

FIFO的另一个缺点是,它有一种异常现象,即在增加存储块的情况下,反而使缺页中断率增加了。当然,导致这种异常现象的页面走向实际上是很少见的。

图3.1 FIFO页面置换算法流程

最久未使用算法(Least Recently Used,LRU)

LRU算法是与每个页面最后使用的时间有关的。当必须置换一个页面时,LRU算法选择过去一段时间里最久未被使用的页面。 [1] 

LRU算法是经常采用的页面置换算法,并被认为是相当好的,但是存在如何实现它的问题。LRU算法需要实际硬件的支持。其问题是怎么确定最后使用时间的顺序,对此有两种可行的办法: [1] 

1.计数器。最简单的情况是使每个页表项对应一个使用时间字段,并给CPU增加一个逻辑时钟或计数器。每次存储访问,该时钟都加1。每当访问一个页面时,时钟寄存器的内容就被复制到相应页表项的使用时间字段中。这样我们就可以始终保留着每个页面最后访问的“时间”。在置换页面时,选择该时间值最小的页面。这样做, [1]  不仅要查页表,而且当页表改变时(因CPU调度)要 [1]  维护这个页表中的时间,还要考虑到时钟值溢出的问题。

2.栈。用一个栈保留页号。每当访问一个页面时,就把它从栈中取出放在栈顶上。这样一来,栈顶总是放有目前使用最多的页,而栈底放着目前最少使用的页。由于要从栈的中间移走一项,所以要用具有头尾指针的双向链连起来。在最坏的情况下,移走一页并把它放在栈顶上需要改动6个指针。每次修改都要有开销,但需要置换哪个页面却可直接得到,用不着查找,因为尾指针指向栈底,其中有被置换页。 [1] 

因实现LRU算法必须有大量硬件支持,还需要一定的软件开销。所以实际实现的都是一种简单有效的LRU近似算法。 [1] 

图2.2 LRT页面置换算法流程图

//LRU算法

void import2(int j,int ele)

{

int i=0;

for(i=0;i<3;i++)

{

if(end[i][0]==NULL)

{

end[i][0] = ele;

end[i][1] = 0;

acsum(i);

return;

}

if(end[i][0]==ele)

{

sum++;

end[i][1] = 0;

acsum(i);

return;

}

}

int max=-1,flag=0;

for(i=0;i<3;i++)

{

if(end[i][1]>=max)

{

max=end[i][1];

flag=i;

}

 

}

end[flag][0]=ele;

end[flag][1]=0;

acsum(i);

return;

 

}

void acsum(int a)

{

int i;

for(i=0;i<3;i++)

{

if(end[i][0]!=NULL&&i!=a)

{

end[i][1]++;

}

}

}

//FIFO算法

void import(int j,int ele)

{

int i=0;

for(i=0;i<3;i++)

{

if(end[i][0]==NULL)

{

end[i][0] = ele;

end[i][1] = j;

return;

}

if(end[i][0]==ele)

{

sum++;

return;

}

}

int min=100,flag=0;

for(i=0;i<3;i++)

{

if(end[i][1]<=min)

{

min=end[i][1];

flag=i;

}

}

end[flag][0]=ele;

end[flag][1]=j;

return;

 

}

图3.3 FIFO算法结果

图3.4 LRU算法结果

 

四、实验体会

在进程运行过程中,若其访问的页面不在内存而需把它们调入内存,但内存以无空闲空间时,为了保证该进程能正常的运行,系统必须从内存中调出一页程序或数据送磁盘的兑换区中,但应将哪个页面调出,需根据一定的算法来确定。通常,把选择换成页面的算法称为页面置换算法。 

通过本次课程设计,我们对页面置换算法的了解更加的深刻。主要有以下置换算法: OPT(最佳置换算法)、FIFO(先进先出置换算法)、LRU(最近最久未使用算法)。每种算法都有各自的优缺点。

LRU算法FIFO算法在课上的时候听的还比较清楚明白,但是在实验中实际操作起来并不是那么的容易,在这次课程设计中,遇到了一些困难,例如怎么实现各种算法,如何进行函数调用及对数据的限制操作等,在遇到这些困难的时候,我们会去查阅资料,仔细看书,尝试用不同的方法解决,在各种方法中选择一种最好的方法,有的时候会碰到不知道如何实现的函数,我们会查看MSDN,这次是用的C++语言做的,每一步都是自己独立完成的。这次课程设计我最大的收获是学以致用,通过这次设计我们看到了自己学习的能力,我们相信在以后的学习中,会更加的努力上进。

最后,还非常感谢辛苦的操作系统老师,首先,因为他辛苦的为我们讲解操作系统这门课,让我们对操作系统有了一定的了解,为这次课程设计奠定了良好的基础,其次,还要感谢他认真指导我们的这次课程设计,给了我们这次总体运用自己能力的机会,我们坚信:只要功夫深,铁杵磨成针。

一、课程设计目的 通过请求页式管理方式中页面置换算法的模拟设计,了解虚拟存储技术的特点,掌握请 求页式存储管理中的页面置换算法。 容 二、课程设计内容 模拟实现 OPT(最佳置换)、FIFO 和 LRU 算法,并计算缺页率。 示 三、要求及提示 本题目必须单人完成。 1、首先用随机数生成函数产生一个“指令将要访问的地址序列”,然后将地址序列变换 成相应的页地址流(即页访问序列),再计算不同算法下的命中率。 2、通过随机数产生一个地址序列,共产生 400 条。其中 50%的地址访问是顺序执行的, 另外 50%就是非顺序执行。且地址在前半部地址空间和后半部地址空间均匀分布。具体产 生方法如下: 1) 在前半部地址空间,即[0,199]中随机选一数 m,记录到地址流数组中(这是 非顺序执行); 2) 接着“顺序执行一条指令”,即执行地址为 m+1 的指令,把 m+1 记录下来; 3) 在后半部地址空间,[200,399]中随机选一数 m’,作为新指令地址; 4) 顺序执行一条指令,其地址为 m’+1; 5) 重复步骤 1~4,直到产生 400 个指令地址。 3、将指令地址流变换成页地址(页号)流,简化假设为: 1) 页面大小为 1K(这里 K 只是表示一个单位,不必是 1024B); 2) 用户虚存容量为 40K; 3) 用户内存容量为 4 个页框到 40 个页框; 6 4) 用户虚存中,每 K 存放 10 条指令,所以那 400 条指令访问地址所对应的页地 址(页号)流为:指令访问地址为[0,9]的地址为第 0 页;指令访问地址为[10, 19]的地址为第 1 页;……。按这种方式,把 400 条指令组织进“40 页”,并 将“要访问的页号序列”记录到页地址流数组中。 4、循环运行,使用户内存容量从 4 页框到 40 页框。计算每个内存容量下不同页面置换 算法的命中率。输出结果可以为: 页框数 OPT 缺页率 FIFO 缺页率 LRU 缺页率 [4] OPT:0.5566 FIFO:0.4455 LRU:0.5500 [5] OPT:0.6644 FIFO:0.5544 LRU:0.5588 …… …… …… …… [39] OPT:0.9000 FIFO:0.9000 LRU:0.9000 [40] OPT:1.0000 FIFO:1.0000 LRU:1.0000 注 1:在某一次实验中,可能 FIFO 比 LRU 性能更好,但足够多次的实验表明 LRU 的平均性能比 FIFO 更好。 注 2:计算缺页率时,以页框填满之前和之后的总缺页次数计算。
### 最佳页面置换算法FIFO页面置换算法比较 最佳页面置换算法是一种理想的页面置换策略,用于评估其他实际可用算法的性能。此算法预测未来使用的页面并移除将来最长时间内不再访问的页面[^1]。 #### 最佳页面置换算法流程图描述 由于无法直接绘制图形,在这里通过文字来描绘最佳页面置换算法的工作原理: 1. **初始化** - 设置初始状态为空闲页面帧。 2. **请求处理** - 当进程发出新的页面请求时,检查是否存在空闲页面帧。 如果有,则分配给新请求;如果没有继续下一步。 3. **判断是否已存在** - 查看当前工作集中是否有相同编号的页面。 若存在则无需加载,标记为命中(/),结束本次操作; 否则进入下一流程。 4. **选择牺牲者** - 预测未来的引用情况,挑选出距离下次被访问时间最长的那个页面作为替换对象*。 5. **更新记录** - 将选定要淘汰的旧页面替换成新请求的页面, 并相应调整内部数据结构以反映最新变化。 6. **返回步骤2** 这种理想化的模型显然不可能实现于现实中因为其依赖对未来事件的知识,但是它提供了一个理论上的最优解标准用来对比其他的真正可行的方法。 #### FIFO页面置换算法流程图描述 对于FIFO页面置换算法而言,其实现方式较为直观简单: 1. **初始化** - 设定固定数量的页面框,并全部置为空闲状态。 2. **接收请求序列** - 接收一系列连续到来的页面访问指令列表。 3. **遍历每个请求** - 对每一个即将执行的操作做如下判定: - 如果所需页面已经在缓存中找到(即发生命中的情形),仅需增加计数器即可完成此次调用; - 反之如果未发现目标页面(意味着发生了缺失*),就需要进一步考虑如何安置这个新来的访客。 4. **实施置换动作** - 根据先进先出原则决定哪个是最老的条目应当被淘汰出局, 即总是选取最早加入队列的那一项进行覆盖写入新的内容。 5. **循环往复直至结束** - 不断重复上述过程直到所有的输入都得到了妥善处置为止。 ```mermaid graph TD; A[开始] --> B{有空闲页?}; B -- 是 --> C[分配新页]; B -- 否 --> D{查重?}; D -- 存在 --> E[命中/]; D -- 不存在 --> F[* 缺页 -> 找到最早的页]; F --> G[替换并载入新页]; H[结束] C,E,G --> H ``` 以上是对两种不同类型的页面置换机制的文字化解释以及简单的伪代码形式展示它们各自的运作逻辑。值得注意的是,虽然这两种方法都是为了管理有限资源而设计出来的解决方案之一,但在具体应用场景下的表现可能会有很大差异。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值