当前位置:   article > 正文

南京邮电大学操作系统实验三:虚拟内存页面置换算法_3、页面置换算法 (1)使用数组存储一组页面请求,页面请求的数量要50个以上,访问的

3、页面置换算法 (1)使用数组存储一组页面请求,页面请求的数量要50个以上,访问的

实验内容

使用数组存储一组页面请求,页面请求的数量要50个以上,访问的页面号可以用随机数生成(0~20):

(1)设置为分配给进程的页框数(假定是5),使用LRU算法,模拟完成全部的页面请求,最后输出总共发生了多少次缺页;重新设置页框为10,模拟过程,完成输出,观察页框数量对缺页中断率的影响;

(2)在相同页框的情况下,使用FIFO算法模拟全部的页面请求,以此来比对FIFOLRU之间的差别。

FIFO算法:先进先出算法,优先淘汰最早进入内存的页面,亦即在内存中驻留时间最久的页面。

LRU算法:最近最少使用页面替换算法,利用局部性原理,根据一个作业在执行过程中过去的页面访问历史来推测未来的行为。它认为过去一段时间里不曾被访问过的页面,在最近的将来可能也不会再被访问。所以,这种算法的实质是:当需要淘汰一个页面时,总是选择在最近一段时间内最久不用的页面予以淘汰。

具体代码如下:

  1. #include<iostream>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<iomanip>
  5. using namespace std;
  6. int GetDistance(int currentPageID,int page);//按照页面编号获取在物理块内的页面最久未使用的时间
  7. class BLOCK
  8. {
  9. public:
  10. int blockNum; //物理块总数
  11. int pageNum; //物理块中的页面数量
  12. int *pageID; //页面号(大小为blockNum)
  13. int *stayTime; //页面在物理块中的停留时间(与物理块ID对应)
  14. BLOCK(int num)
  15. {
  16. int i;
  17. pageNum=0;
  18. blockNum=num;
  19. pageID=new int[num];
  20. stayTime=new int[num];
  21. for(i=0;i<num;i++)
  22. {
  23. pageID[i]=-1; //初始化每个物理块中没有放置,页面号表示为-1
  24. stayTime[i]=0; //初始化停留时间为0
  25. }
  26. }
  27. void Init()
  28. {
  29. int i;
  30. int num=blockNum;
  31. pageNum=0;
  32. pageID=new int[num];
  33. stayTime=new int[num];
  34. for(i=0;i<num;i++)
  35. {
  36. pageID[i]=-1; //初始化每个物理块中没有放置,页面号表示为-1
  37. stayTime[i]=0; //初始化停留时间为0
  38. }
  39. }
  40. void ShowPage()
  41. {
  42. int i;
  43. for(i=0;i<blockNum;i++)
  44. cout<<"Page["<<i<<"]: "<<pageID[i]<<endl;
  45. }
  46. void ShowStayTime()
  47. {
  48. int i;
  49. for(i=0;i<blockNum;i++)
  50. cout<<"Stay["<<i<<"]: "<<stayTime[i]<<endl;
  51. }
  52. int GetLongestStay() //获取在物理块中停留时间最长的页面所在物理块号
  53. {
  54. int i;
  55. int max_pos=0;
  56. for(i=0;i<pageNum;i++)
  57. if(stayTime[max_pos]<stayTime[i])
  58. max_pos=i;
  59. return max_pos;
  60. }
  61. int GetRencentNotUse(int currentPageID) //获取在物理块中最近最久未使用的页面编号
  62. {
  63. //默认currentPageID一定大于等于BLOCKNUM
  64. int i;
  65. int DestID=0;
  66. for(i=0;i<blockNum;i++)
  67. {
  68. if(GetDistance(currentPageID,pageID[i])>GetDistance(currentPageID,pageID[DestID]))
  69. DestID=i;
  70. }
  71. return DestID;
  72. }
  73. }; //物理块数据结构定义
  74. //-----------------------全局变量-------------------------
  75. int BLOCKNUM; //物理块数
  76. int *PVS; //PageVisitSequence页面访问序列
  77. int PVS_NUM; //页面访问序列长度
  78. int **replaceTable; //页面置换表格(维度:BLOCKNUM*PVS_NUM)
  79. int *replaceArray; //页面置换标志数组(大小为访问页面的次数,存储每次访问是否进行页面置换)
  80. int *lackArray; //缺页中断标志数组(大小为访问页面的次数,存储每次访问是否存在缺页中断)
  81. //-----------------------函数声明-------------------------
  82. void showMenu(); //菜单显示
  83. int InputAndInit(); //数据输入和变量初始化
  84. void ReplaceFIFO(BLOCK block); //FIFO页面置换算法
  85. int FindPage(int pageID,BLOCK block); //页面查找(按照页面编号在物理块中查找页面是否存在)
  86. void ShowReplaceTable(); //置换表格输出
  87. void ReplaceLRU(BLOCK block); //LRU页面置换算法
  88. void InfoDisplay(); //初始化信息显示
  89. int GetReplaceTimes(); //获取页面置换总次数
  90. int GetLackTimes(); //获取缺页中断总次数
  91. //-----------------------函数定义-------------------------
  92. int main()
  93. {
  94. int select;
  95. int i;
  96. cout<<"------请按提示输入算法模拟需要的数据------"<<endl;
  97. InputAndInit();
  98. BLOCK block(BLOCKNUM); //定义物理块
  99. cout<<"信息初始化完成!"<<endl<<endl;
  100. showMenu();
  101. cout<<"------请输入要进行的操作------"<<endl;
  102. cin>>select;
  103. while(1)
  104. {
  105. switch(select)
  106. {
  107. case 1:
  108. InfoDisplay();
  109. cout<<endl;
  110. break;
  111. case 2:
  112. ReplaceFIFO(block);
  113. cout<<"|==> FIFO页面调度算法正在执行"<<endl;
  114. ShowReplaceTable();
  115. cout<<"页面置换次数为:"<<GetReplaceTimes()<<endl;
  116. cout<<"缺页中断次数为:"<<GetLackTimes()<<endl;
  117. cout<<"缺页率为:" << double(GetLackTimes()) / 50 * 100.00 << "%" << endl;
  118. cout<<endl;
  119. cout<<endl;
  120. break;
  121. case 3:
  122. ReplaceLRU(block);
  123. cout<<"|==> LRU页面调度算法正在执行"<<endl;
  124. ShowReplaceTable();
  125. cout<<"页面置换次数为:"<<GetReplaceTimes()<<endl;
  126. cout<<"缺页中断次数为:"<<GetLackTimes()<<endl;
  127. cout<<"缺页率为:" << double(GetLackTimes()) / 50 * 100.00 << "%" << endl;
  128. cout<<endl;
  129. cout<<endl;
  130. break;
  131. case 0:
  132. cout<<"欢迎下次使用"<<endl;
  133. return 0;
  134. default:
  135. cout<<"输入有误,请重新输入!"<<endl;
  136. cout<<endl;
  137. break;
  138. }
  139. //------防止页面置换和缺页次数计算错误-------------
  140. for(i=0;i<PVS_NUM;i++)
  141. {
  142. replaceArray[i]=0; //页面置换标志数组初始化为0
  143. lackArray[i]=0; //缺页中断标志数组初始化为0
  144. }
  145. showMenu();
  146. cout<<"请输入要进行的操作(退出请输入0):"<<endl;
  147. cin>>select;
  148. }
  149. delete[] PVS;
  150. delete[] replaceArray;
  151. delete[] lackArray;
  152. for(i=0;i<BLOCKNUM;i++)
  153. delete[] replaceTable[i];
  154. delete[] replaceTable;
  155. return 0;
  156. }
  157. //----------------------FIFO页面置换算法--------------------------
  158. void ReplaceFIFO(BLOCK block) //FIFO页面置换算法
  159. {
  160. int i,j;
  161. for(i=0;i<BLOCKNUM;i++)
  162. for(j=0;j<PVS_NUM;j++)
  163. replaceTable[i][j]=0;
  164. block.Init();
  165. int replacePosition; //待置换位置
  166. for(i=0;i<PVS_NUM;i++) //依次对页面访问序列的每一个页面PVS[i]进行操作
  167. {
  168. for(j=0;j<block.pageNum;j++)
  169. block.stayTime[j]++; //每循环一次,物理块(0~pageNum)停留时间自增
  170. if(block.pageNum<block.blockNum)
  171. {
  172. if(!FindPage(PVS[i],block)) //若页面PVS[i]不存在
  173. {
  174. lackArray[i]=1; //由于访问页面不存在造成页面中断
  175. block.pageID[block.pageNum]=PVS[i];
  176. block.pageNum++;
  177. }
  178. }
  179. else //FIFO算法(置换停留时间最长的页面所在物理块位置)
  180. {
  181. if(!FindPage(PVS[i],block)) //若页面PVS[i]不存在
  182. {
  183. replaceArray[i]=1; //由于访问页面不存在且无空闲物理块造成页面置换
  184. lackArray[i]=1; //由于访问页面不存在造成页面中断
  185. replacePosition=block.GetLongestStay();
  186. block.pageID[replacePosition]=PVS[i]; //选择停留时间最长的页面置换
  187. block.stayTime[replacePosition]=0; //置换后,该页面所在物理位置停留时间清零
  188. }
  189. }
  190. for(j=0;j<BLOCKNUM;j++)
  191. replaceTable[j][i]=block.pageID[j]; //将访问一次页面后的结果存入数组中(replaceTable)
  192. }
  193. }
  194. int FindPage(int pageID,BLOCK block) //页面查找(按照页面编号在以存放页面的物理块(长度为pageNum)中查找页面是否存在)
  195. {
  196. int i=0;
  197. for(i=0;i<block.pageNum;i++)
  198. if(block.pageID[i]==pageID)
  199. break;
  200. return !(i==block.pageNum); //若页面存在,则返回1,否则返回0
  201. }
  202. //----------------------LRU页面置换算法--------------------------
  203. void ReplaceLRU(BLOCK block) //LRU页面置换算法
  204. {
  205. int i,j;
  206. for(i=0;i<BLOCKNUM;i++)
  207. for(j=0;j<PVS_NUM;j++)
  208. replaceTable[i][j]=0;
  209. block.Init();
  210. int replacePosition; //待置换位置
  211. for(i=0;i<PVS_NUM;i++) //依次对页面访问序列的每一个页面PVS[i]进行操作
  212. {
  213. for(j=0;j<block.pageNum;j++)
  214. block.stayTime[j]++; //每循环一次,物理块(0~pageNum)停留时间自增
  215. if(block.pageNum<block.blockNum)
  216. {
  217. if(!FindPage(PVS[i],block)) //若页面PVS[i]不存在
  218. {
  219. lackArray[i]=1; //由于访问页面不存在造成页面中断
  220. block.pageID[block.pageNum]=PVS[i];
  221. block.pageNum++;
  222. }
  223. }
  224. else //FIFO算法(置换停留时间最长的页面所在物理块位置)
  225. {
  226. // TODO:若页面已存在的情况(上述三条语句应该是页面不存在的情况,应加上if(页面在物理块中不存在)的判断) By_2018.06.15_16:11
  227. if(!FindPage(PVS[i],block)) //若页面PVS[i]不存在
  228. {
  229. replaceArray[i]=1; //由于访问页面不存在且无空闲物理块造成页面置换
  230. lackArray[i]=1; //由于访问页面不存在造成页面中断
  231. replacePosition=block.GetRencentNotUse(i);
  232. block.pageID[replacePosition]=PVS[i]; //选择停留时间最长的页面置换
  233. block.stayTime[replacePosition]=0; //置换后,该页面所在物理位置停留时间清零
  234. }
  235. }
  236. for(j=0;j<BLOCKNUM;j++)
  237. replaceTable[j][i]=block.pageID[j]; //将访问一次页面后的结果存入数组中(replaceTable)
  238. }
  239. }
  240. //----------------------OTHRES--------------------------
  241. void showMenu() //菜单显示
  242. {
  243. cout<<"\t\t|----------------------------MENU-------------------------------|"<<endl;
  244. cout<<"\t\t| 1. 初始化信息显示 |"<<endl;
  245. cout<<"\t\t| 2. FIFO页面置换算法 |"<<endl;
  246. cout<<"\t\t| 3. LRU页面置换算法 |"<<endl;
  247. cout<<"\t\t| 0. 退出程序 |"<<endl;
  248. cout<<"\t\t|---------------------------------------------------------------|"<<endl;
  249. }
  250. int InputAndInit() //数据输入和变量初始化
  251. {
  252. int i=0;
  253. int j=0;
  254. int count = 0;
  255. int PVS_char[100];
  256. cout << "调入的页面按如下顺序(以0为结束标志):"<<endl;
  257. for(i=0;i<50;i++)
  258. {
  259. PVS_char[i]=rand()%20+1;
  260. cout<<PVS_char[i]<<" ";
  261. count++;
  262. }
  263. cin>>PVS_char[50];
  264. getchar();
  265. cout<<endl;
  266. cout<<"请输入物理块数:";
  267. cin>>BLOCKNUM;
  268. while(PVS_char[50]!=0)
  269. {
  270. i++;
  271. cin>>PVS_char[i];
  272. getchar();
  273. }
  274. PVS_NUM=i;
  275. PVS=new int[PVS_NUM];
  276. for(i=0;i<PVS_NUM;i++)
  277. PVS[i]=PVS_char[i];
  278. replaceArray=new int[PVS_NUM];
  279. lackArray=new int[PVS_NUM];
  280. for(i=0;i<PVS_NUM;i++)
  281. {
  282. replaceArray[i]=0; //页面置换标志数组初始化为0
  283. lackArray[i]=0; //缺页中断标志数组初始化为0
  284. }
  285. replaceTable=new int*[BLOCKNUM]; //页面置换表初始化
  286. for(i=0;i<BLOCKNUM;i++)
  287. replaceTable[i]=new int[PVS_NUM];
  288. return count;
  289. }
  290. void ShowReplaceTable() //置换表格输出
  291. {
  292. int i,j;
  293. cout<<"页面置换过程如下图所示"<<endl<<endl;
  294. cout<<"页面置换过程 "<<endl;
  295. for(i=0;i<BLOCKNUM;i++)
  296. {
  297. for(j=0;j<PVS_NUM;j++)
  298. {
  299. if(replaceTable[i][j]!=-1)
  300. cout<<"|"<<setw(2)<<replaceTable[i][j];
  301. else cout<<"|"<<setw(2)<<" "; //-1时代表该物理块无页面,不输出
  302. }
  303. cout<<"|"<<endl;
  304. }
  305. cout<<"页面置换标志 "<<endl;
  306. for(i=0;i<PVS_NUM;i++)
  307. cout<<" "<<setw(2)<<replaceArray[i];
  308. cout<<endl;
  309. cout<<"页面中断标志 "<<endl;
  310. cout.fill(' ');
  311. for(i=0;i<PVS_NUM;i++)
  312. cout<<" "<<setw(2)<<lackArray[i];
  313. cout<<endl<<endl;
  314. }
  315. int GetDistance(int currentPageID,int page) //按照页面编号获取在物理块内的页面最久未使用的时间(
  316. {
  317. int distance=0;
  318. int i;
  319. for(i=currentPageID-1;i>=0;i--)
  320. if(PVS[i]!=page)
  321. distance++;
  322. else break;
  323. return distance;
  324. }
  325. void InfoDisplay() //初始化信息显示
  326. {
  327. int i;
  328. cout<<"本页面置换模拟算法中: "<<endl;
  329. cout<<"物理块数为: "<<BLOCKNUM<<endl;
  330. cout<<"页面访问序列为:";
  331. for(i=0;i<PVS_NUM;i++)
  332. cout<<PVS[i]<<" ";
  333. cout<<endl;
  334. }
  335. int GetReplaceTimes() //获取页面置换总次数
  336. {
  337. int sum=0;
  338. int i;
  339. for(i=0;i<PVS_NUM;i++)
  340. sum+=replaceArray[i];
  341. return sum;
  342. }
  343. int GetLackTimes() //获取页面中断总次数
  344. {
  345. int sum=0;
  346. int i;
  347. for(i=0;i<PVS_NUM;i++)
  348. sum+=lackArray[i];
  349. return sum;
  350. }

运行结果如下:

页框数为5时,FIFO算法缺页率为72%LRU算法缺页率为76%

页框为3,FIFO算法缺页率为88%,LRU算法缺页率为88%。

 页框为4 FIFO算法缺页率为82%,LRU算法缺页率为86%。

 页框为6, FIFO算法缺页率为72%,LRU算法缺页率为76%。

 页框数为9, FIFO算法缺页率为66%,LRU算法缺页率为62%。

 页框数为10FIFO算法缺页率为56%,LRU算法缺页率为52%。

 根据上述结果可知,影响缺页中断率的因素有:①分配给作业的主存块数;②页面大小;③程序编制方法;④页面调度算法选用的不同。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/163443
推荐阅读
相关标签
  

闽ICP备14008679号