理解并掌握主要页面淘汰算法的设计和实现要旨。
编程设计与实现最佳淘汰算法、先进先出淘汰算法、最近最久未使用淘汰算法、简单 Clock 淘汰算法及改进型 Clock 淘汰算法,并随机发生页面访问序列开展有关算法的测试及性能比较。
本实验课题功能设计要求如下:
(1)编程设计实现最佳淘汰算法、先进先出淘汰算法、最近最久未使用淘汰算法、简单Clock 淘汰算法及改进型 Clock 淘汰算法;
(2)编程设计实现页面访问序列的随机发生机制,包括各页面读写访问方式的设定以满足改进型 Clock 淘汰算法的要求;
(3)在执行进程和访问各页面过程中,每访问一个(或一次)页面应显示输出当时的进程页表内容(包括页号、物理块号、状态位、读/写访问方式等字段)及本次页面访问操作情况(譬如页面已在内存或触发缺页中断);
(4)基于相同的条件,包括系统均采用固定分配局部置换策略、相同的进程逻辑地址空间大小(暨逻辑页面数,设进程逻辑地址空间的页面总数为 N,则其页号取值区间为[0, N))、分配给进程同样多的物理块(设进程分配获得 S 个物理块,则相应物理块号分别标记为 PF0、PF1、……、PFS-1)、相同的页面访问序列(整数序列,整数取值区间为[0, N))、均预装入前三个页面,进行有关算法的测试;
(5)变换上述条件实施多次测试,统计分析和比较有关算法的性能(譬如缺页率、淘汰页查找时间开销)。
实验按照要求进行。随机访问队列由给出的算法计算得出。为了更好的对比各种淘汰算法,生成同一随机访问队列后将同一调用所有淘汰算法进行指标的统计。
页表数据结构将有页号、访问次数、访问模式三个变量。
每个淘汰算法设定一组函数,一个算法函数入口,若干辅助函数。设定命中和不命中不同的显示函数。
生成随机访问队列的函数按实验指导书中编写,不再细表。
操作系统:window 10 21H2
开发环境:Clion-2022.2.1-Windows
编译器:mwing-10.0、
01:struct Page{
02: int num;
03: int times;
04: int mode;
05:// mode 0 for read, mode 1 for write
06:};
07:
08:struct MemPageControl{
09: int allocated_size; // the page size to be allocated to the process
10: int missing_num; // num for missing page, the call interruption
11: vector<Page> page;
12:} inside_page;
13:
14:struct OutSidePage{
15: vector<Page> visit_list;
16: int current;
17:} outside_page;
Page为页表项。MemPageControl为内存中已有的页表及相关信息。OutSidePage为待访问的页列。
函数思路参照ppt。子函数包括预分配函数,判读访问页是否在内存中函数,寻找最佳淘汰页函数,基本参数由config文件读入,最后给出缺页率。
图表 5 1 config文件
图表 5 2 OPT测试结果
可以看出通过手动分析,实验结果正确。
基本相同操作间OPT,不同的是,在page结构体中加入了location when in,记录加入内存时的访问队列索引,这样方便找到,最早加入内存的页号。
随机队列生成预参数保持一致。
图表 5 3 FIFO算法验证
可以看出通过手动分析,实验结果正确。
利用page 中的location when in 作为上次访问的记录,记录上次访问时,访问队列中的index;miss时index最小的被淘汰。
随机队列生成预参数保持一致。
结果验证:
图表 5 4 LRU算法
可以看出通过手动分析,实验结果正确。
借用page中的location when in 代表访问位。这样可以节省空间。具体算法参照ppt和上述算法。
图表 5 5 CLOCK算法验证
结果正确。
参考了ppt上的讲解,同时针对编码进行了一点算法调整。
最后的算法如下:
图表 5 6 CLOCK PRO算法
结果正确。
上述代码的实现还是基于单一的随机访问序列,随机数种子也设置成了定值,这样方便验证代码的正确性。我们还可以发现由于访问队列在测试样例中比较小,所有算法的时间开销都是0,这样的结果为我们下边的对边做出了指导。
我们选取了缺页率和淘汰页寻找时间进行对比。(但其实针对每个算法的特性,比如改进的clock算法,主要是为了改进I/O的读写时间,本身的寻找时间上反而不占优势,所以,我们的对比具有一定的局限性)
图表 5 7 test1参数
由上到下为分配的固定块、总访问页数,工作表移动速率,工作表大小。
结果如下:
algorithm | Missing rate | Time cost | algorithm |
---|---|---|---|
CLOCK | 0.7324 | 0 | CLOCK |
CLOCK_PRO | 0.619 | 0.017 | CLOCK_PRO |
FIFO | 0.59875 | 0.127 | FIFO |
LRU | 0.59785 | 0.039 | LRU |
OPT | 0.5891 | 2.419 | OPT |
表格 5 1 test1结果
分析一下结果,发先OPT的缺页率是最小的,但是时间确实最长的。时间上应该是最坏的情况需要判断为页表再也不访问,这样需要遍历整个待访问队列,时间复杂度为O(VisitLength * PageMEM),即访问队列长度与分配的页块之积,复杂度最高。
CLOCK算法和其改进算法,只是在内存中的页表内部进行选取,时间开销最小,这里甚至小到计算不出CLOCK时间,CLOCKpro有更多的开销,时间更长一些。
FIFO和LRU算法主要时间开销主要体现在排序上边。其实,为了实验对比明显,我们的排序部分函数甚至故意通过修改数据结果变成了相同的样式,但是通过结果来看,算法具有不稳定性,二者相差明显。事实上,通过多次实验对比,我们固定了随机数种子来对比,确实时间上忽高忽低,有正负变化。但是从复杂度比较来看,实验结果基本吻合。
成功完成实验要求。
发现输出语句中字符串紧跟一个’\t’,是有几率不能生成制表符的,但是多加一个空格就可以正确生成了,还可以自动对齐。
显示函数的格式美化和对齐实验了许多次。
一开始,随机数种子是按时间设定的,每次实验结果不同,无法复现比较,后固定随机数种子,便于比较实验。
一开始,生成队列函数停止条件的判断位置控制不好,当v大于总队列长度时会出现问题。通过学习,在for-loop中加入了符合判断条件。
一开始发现OPT的置换率居然是最高的,这样和理论不合。最后发现是在OPT寻找置换页时,数组初始化出现了问题,把所有的key都初始化为1。
算法结果对比过程中,对排序算法的不稳定性有了更多的理解,同时,也知道了一个算法的性能是多方面的,更多的是看实际中的倾向。