操作系统课程设计Word格式文档下载.docx
《操作系统课程设计Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计Word格式文档下载.docx(33页珍藏版)》请在冰豆网上搜索。
c)编写磁盘调度算法本身
五、设计原理:
1、页面淘汰算法原理:
1.1、页面淘汰算法定义与简介:
在进程运行过程中,若其要访问的页面不在内存而需把它们调入内存,但内存已经无空闲空间时,为了保证该进程能正常运行,系统必须从内存中调出一页程序或数据送磁盘的对换区中。
但应将哪个页面调出,须根据一定的算法来确定。
通常,把选择换出页面的算法称为页面淘汰算法或者页面置换算法(Page-ReplacementAlgorithms)。
置换算法的好坏,将直接影响到系统的性能。
一个好的页面置换算法,应具有较低的页面更换频率。
从理论上讲,应将那些以后不会再访问的页面换出,或把那些在较长时间内不会再访问的页面调出。
目前存在着许多页面置换算法,它们都试图更接近于理论上的目标。
1.2、先进先出(FIFO)页面置换算法
这是最早出现的置换算法。
该算法总是淘汰最先进入内存的页面,即选择在内存中驻留实践最久的页面予以淘汰。
该算法实现简单,只需把一个进程调入内存的页面,按先后次序链接成一个队列,并设置一个指针,称为替换指针,使它总是指向最老的页面。
但该算法与进程实际运行的规律不相适应,因为在进程中,有些页面经常被访问,比如含有全局变量、常用函数、例程等地页面,FIFO算法并不能保证这些页面不被淘汰。
具体实现流程图如下:
注:
在FIFO算法中,无论有无发生缺页或者置换,都需要对每个在内存中的页面的time值进行增加操作,以保持最先进入的那个页面的time值是最大的;
一个新进来的页面,其time值设置为0。
算法也可以通过队列结构来实现,利用队列的先进先出(FIFO)特性完成,无需设置time字段。
1.2.1、数据结构介绍:
1.2.2、算法源程序:
(见附录)。
1.3、最佳置换法(OPT)背景与简介:
它是由Belady于1966年提出的一种理论上的算法。
其所选择的被淘汰页面,将是以后永不使用的或许是在最长(未来)时间内不再被访问的页面。
采用最佳置换算法,通常可保证获得最低的缺页率。
但由于人目前还无法预知一个进程在内存的若干个页面中,哪一个页面是未来最长时间内不再被访问的,因而该算法是无法实现的,但可以利用此算法来评价其它算法。
具体流程图如下:
distance用于记录内存物理块集合中每个页面距离再次被使用的页面跨度,缺省值为INT_MAX,如果某个页面在后续指令集合中不再出现,则用最大值INT_MAX缺省取代;
如果页面再次被使用,则两次使用所跨的页面数,为页面跨度。
用最大页面跨度表示以后永不使用或未来最长时间内不再被访问。
1.3.1、数据结构介绍:
1.3.2、算法源程序:
(见附录)
1.4、最近最久未使用(LRU)页面置换算法:
最近最久未使用(LRU)置换算法,是根据页面调入内存后的使用情况进行决策的。
由于无法预测各页面将来的使用情况,只能利用“最近的过去”作为“最近的将来”的近似,因此,LRU置换算法是选择最近最久未使用的页面予以淘汰。
该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间time,,当须淘汰一个页面时,选择现有页面中其time值最大的,即最近最久未使用的页面予以淘汰。
在LRU算法中,无论是否发生缺页或者置换,除了命中(刚刚被访问过的页面)页面time值清零之外,其它所有内存中的页面的time值都加一,以保证最近刚刚被访问的页面的time值最小,相应time值最大的页面就是最近最久没有被访问的页面。
1.4.1、数据结构介绍:
1.4.2、算法源程序:
2、磁盘调度主要思想
设备的动态分配算法与进程调度相似,也是基于一定的分配策略的。
常用的分配策略有先请求先分配、优先级高者先分配等策略。
在多道程序系统中,低效率通常是由于磁盘类旋转设备使用不当造成的。
操作系统中,对磁盘的访问要求来自多方面,常常需要排队。
这时,对众多的访问要求按一定的次序响应,会直接影响磁盘的工作效率,进而影响系统的性能。
访问磁盘的时间因子由3部分构成,它们是查找(查找磁道)时间、等待(旋转等待扇区)时间和数据传输时间,其中查找时间是决定因素。
因此,磁盘调度算法先考虑优化查找策略,需要时再优化旋转等待策略。
平均寻道长度(L)为所有磁道所需移动距离之和除以总的所需访问的磁道数(N),即:
L=(M1+M2+……+Mi+……+MN)/N其中Mi为所需访问的磁道号所需移动的磁道数。
启动磁盘执行输入输出操作时,要把移动臂移动到指定的柱面,再等待指定扇区的旋转到磁头位置下,然后让指定的磁头进行读写,完成信息传送。
因此,执行一次输入输出所花的时间有:
A、寻找时间——磁头在移动臂带动下移动到指定柱面所花的时间。
B、延迟时间——指定扇区旋转到磁头下所需的时间。
C、传送时间——由磁头进程读写完成信息传送的时间。
其中传送信息所花的时间,是在硬件设计就固定的。
而寻找时间和延迟时间是与信息在磁盘上的位置有关。
为了减少移动臂进行移动花费的时间,每个文件的信息不是按盘面上的磁道顺序存放满一个盘面后,再放到下一个盘面上。
而是按柱面存放,同一柱面上的各磁道被放满信息后,再放到下一个柱面上。
所以各磁盘的编号按柱面顺序(从0号柱面开始),每个柱面按磁道顺序,每个磁道又按扇区顺序进行排序。
2.1、先来先服务(FCFS,FirstComeFirstServed)
这是一种最简单的磁盘调度算法。
它是根据进程请求访问磁盘的先后次序进行调度。
此算法的优点是公平、简单,且每个进程的请求都能依次地得到处理,不会出现某一进程的请求长期得不到满足的情况。
但此算法由于未对寻道进行优化,致使平均寻道时间可能较长。
2.2、SCAN算法
该算法不仅考虑到欲访问的磁道与当前磁道间的距离,更优先考虑的时磁头当前的移动方向。
例如,当磁头正在自里向外移动时,SCAN算法所考虑的下一个访问对象,应是其欲访问的磁道既在当前磁道之外,又是距离最近的。
这样的自里向外地访问,直至再无更外的磁道需要访问时,才将磁臂换向为自外向里移动。
这时,同样也是每次选择这样的进程来调度,即要访问的磁道在当前位置内距离最近者,这样,磁头又逐步地从外向里移动,直至再无更里面的磁道要访问,从而避免了出现“饥饿”现象。
由于在这种算法种磁头移动的规律颇似电梯的运行,因而又常称之为电梯调度算法。
2.3、CSCAN算法
单向扫描调度算法(CSCAN)是SCAN进行了改进。
扫描调度算法(SCAN)存在这样的问题:
当磁头刚从里向外移动过某一磁道时,恰有一进程请求访问此磁道,这是该进程必须等待,待磁头从里向外,然后再从外向里扫描完所有要访问的磁道后,才处理该进程的请求,致使该进程的请求被严重地推迟。
为了减少这种延迟,CSCAN算法规定磁头只做单向移动。
[1]例如,磁头只自里向外移动,当磁头移到最外的被访问磁道时,磁头立即返回到最里的欲访磁道,即将最小磁道号紧接着最大磁道号构成循环,进行扫描。
2.4、最短寻道时间优先(ShortestSeekTimeFirst,SSTF)
该算法选择这样的进程,其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短,但这种调度算法却不能保证平均寻道时间最短。
SSTF算法的平均每次磁头移动距离,明显低于FCFS的距离。
SSTF较之FCFS有更好的寻道性能,故过去一度被广泛采用过。
2.5、程序流程图:
(可见附录图,此图为截图,不清晰)
2.5、各个算法的比较:
从100号磁道开始(第一栏为磁道顺序,第二栏为移动距离)
FCFS
SSTF
SCAN
CSCAN
55
45
90
10
150
50
58
3
30
160
39
19
184
24
18
21
16
94
166
72
38
1
32
20
70
132
112
146
平均长度:
55.3
27.5
27.8
35.8
六、数据收集与统计分析
小组采用随机函数生成足够大的数据量,并且采用Matlab数学统计分析软件进行绘图与分析,探索算法之间变量与因变量的关系。
Matlab源代码附表。
1、磁盘调度算法分析
数据内容分别存储在“disk队列”与“disk移动距离”纯文本文件中。
我们以数列长度为横坐标(x),移动距离为纵坐标(y),采取matlab作图工具分析得下图:
根据上图,可以很明显地看出FSFC算法是平均总移动距离最长的,它的Y轴差等值为2000,而其它三个图像为500。
现在,我们假定它们存在线性的关系。
对四种算法做出线性拟合。
假设方程为:
。
其中Y为总移动距离,X为队列长度,那么其斜率
就可以抽象为它线性范围内的平均移动长度。
在FCFS算法中,可得斜率为165.4,置信区间为[162.3,168.5];
在SCAN算法中,可得斜率为44.0,置信区间为[42.3,45.7];
在CSACN算法中,可得斜率为56.9,置信区间为[55.1,58.8];
在SSFT算法中,可得斜率为42.2,置信区间为[40.7.43.7]。
从上述直观的斜率数据可以显然得出,SSFT算法和SCAN算法似乎是最优的。
但是从全队列的平均等待时间来看,CSCAN算法是为了解决SCAN算法长久的等待时间而设定的,它消除了一部分页面长期等待的障碍。
FCFS算法是最古老的算法,当然它等待时间是最少的,移动距离也是不可调和的缺陷。
具体的队列等待时间,会在附表中给出分析。
2、页面置换算法数据分析
a)小组从定内存容量为基础;
b)以队列长度为自变量;
c)以置换次数为因变量。
2.1、当队列长度最大为10时:
FIFO、LRU、OPT、拟合的一次函数为:
=
*0.7261+0.4504;
*0.7242+0.4588;
*0.6799+0.5793。
2.2、当队列长度最大为20时:
*0.8593+0.1831;
*0.8578+0.1910
*0.7652+0.5825
2.2、当队列长度的最大值为50时
*0.9406+0.1381
*0.9398+0.1595
*0.8655+0.5429
以下还有100、500分析,便不再给出上图,在下表中给出系数:
2.4、综合分析
0.7261
0.7242
0.6799
0.8593
0.8578
0.7652
0.9406
0.9398
0.8655
100
0.9681
0.9683
0.9230
500
0.9940
0.9835
数据总结:
在页面存在随机调度的情况下,从纵向可以看出当队列越长时,置换的次数就越多,这是合乎常理的;
从横向角度可以得出OPT算法是理论上最优的,而FIFO算法在数据规模不大的情况下略高于LRU算法,一旦队列数量足够大就越接近LRU算法。
七、设计总结:
从上个学期的操作系统理论课到现在的课程设计,是一个从理论到实践的过程,是我们消化理论运用到实际的过程。
从周一到周二我们用C++通过面向对象的形式完成了操作系统的页面淘汰算法和磁盘调度算法的模拟运行。
周三小组通过软件进行了较为完善的数据分析,并生成了图表,清晰明了地阐述了各种算法的优缺点。
周四小组搜集很多资料做了较为完善的课程设计报告。
通过这一周的实践,小组密切配合,培养了团队合作精神,培养了我们的实际动手能力和理论联系实践的能力,认真细致的完成了此次课程设计,收获很大。
附表:
DISK.cpp磁盘调度算法源文件:
#include<
cstdio>
cstdlib>
queue>
algorithm>
ctime>
cstring>
vector>
iostream>
fstream>
usingnamespacestd;
/************************************************************************/
/*Author:
ZuoLingxuan,ChenYuxi;
Adress:
WenzhouUniversiy*/
/*Date:
2012-9-11;
DesignofOS,FCFS,SCAN,SSCAN,SRT*/
//注:
SCAN和SSCAN算法默认为向上循环移动
ofstreamout1("
disk队列.txt"
),out2("
disk移动距离.txt"
);
#defineMAXLEN20
#defineMAXDISK500
classDISK{
public:
vector<
int>
que;
//磁道队列向量
intstart,npos,n;
//磁道起点,磁道当前位置
intdist;
//磁针移动距离
DISK(){
que.clear();
n=0;
}
voidgetinfo(){
cout<
<
"
起始磁道为:
"
start<
endl;
磁道队列为:
for(vector<
:
iteratorit=que.begin();
it!
=que.end();
it++){
cout<
*it<
;
}
voidFCFSrunning(){
***************FCFS算法:
******************************************************"
dist=0;
npos=start;
getinfo();
vector<
磁盘调度的路径为:
npos<
-->
while(it!
=que.end())
{
dist+=abs(npos-*it);
npos=*it;
it++;
结束!
移动距离为:
dist<
平均寻道长度:
double(dist/n)<
out2<
double(dist*1.0/n)<
voidCSCANrunning(){
***************CSCAN算法:
*******************************************************"
iteratorit,cit;
cque(que),way;
sort(cque.begin(),cque.end());
for(cit=cque.begin();
cit!
=cque.end()&
&
*cit<
start;
cit++)
way.push_back(*cit);
it=cit;
=cque.end())
it=way.begin();
=way.end())
*******************************************************************************"
voidSCANrunning(){
cout<
***************SCAN算法:
way.push_back(*cit);
reverse_iteratorit2=way.rbegin();
while(it2!
=way.rend())
dist+=abs(npos-*it2);
npos=*it2;
it2++;
booloperator()(inti,intj){return(i>
j);
}//内部比较函数
voidSSTFrunning(){
***************SSFT算法:
********************************************************"
way.clear();
for(it=cque.begin();
it<
cque.end()&
*it<
it++)
//找出当前磁道所处范围
way.push_back(*it);
sort(way.begin(),way.end(),*this);
cit=way.begin();
while(it<
cque.end()||cit<
way.end()){
intmax=-1;
if(it<
(max<
0||max>
abs(*it-npos))