基本知识点转载:https://blog.csdn.net/qq_30353463/article/details/124613726
以下为方便阅读直接进行知识点搬运:
最优算法
理论层面上的算法。
它是在整个事情发生之后,也就是我们已经知道访问的页面序列是怎样的,根据页面序列分析算出什么时间点淘汰什么页面能够取得最高的效率性能。
根据不同的实际场景,最优算法肯定能得出不同的解决方案,没有普遍的规律。
在实际访问中往往没办法了解整体的页面序列,比如涉及到分支,那就会根据条件进行判断,我们就不知道下一个页面应该访问哪一个,整个完整序列是排不出来的。
所以最优算法在实际是无法直接应用的。
它的应用场景是把最优的写出来,再和其他的算法方案进行对比。看其他方案和最优相比差距有多大先进先出算法
要淘汰页面的时候,就看哪些页面是最先进入到内存的,那就先淘汰什么。先进先出有可能造成“抖动”
“抖动”:我分配给你更多的资源,我希望你把这个事情做得更加好一些。结果不但没有出现正面的效果,反而让效率降低了。
在置换算法的表现是:
我在内存里给你分配3个页面,原本页面的缺页假设是9次。然后我给你分配4个页面,资源多了。这时候你的缺页达到了11个甚至14个(具体可以看下方例子)。造成结果更坏了。这就会导致该不该增加资源分析起来更加复杂。最近最少使用:
根据局部性原理,刚刚被访问过的页面很可能马上就会被访问到。所以不会被淘汰。
不会“抖动”,也就是分配的资源越多,表现的越好。
缺页:缺页是引入了虚拟内存后的一个概念。操作系统启动后,在内存中维护着一个虚拟地址表,进程需要的虚拟地址在虚拟地址表中记录。一个程序被加载运行时,只是加载了很少的一部分到内存,另外一部分在需要时再从磁盘载入。被加载到内存的部分标识为“驻留”,而未被加载到内存的部分标为“未驻留”。操作系统根据需要读取虚拟地址表,如果读到虚拟地址表中记录的地址被标为“未驻留”,表示这部分地址记录的程序代码未被加载到内存,需要从磁盘读入,则这种情况就表示"缺页"。这个时候,操作系统触发一个“缺页”的硬件陷阱,系统从磁盘换入这部分未“驻留”的代码。
原文链接:https://blog.csdn.net/computerinbook/article/details/101112983
缺页(个人理解):当程序较大时,程序运行时需要调用的程序代码部分,内存中没有,需要从外存中调入,这个现象就成为缺页。由于所给的内存快不够,过于频繁的缺页则造成了抖动现象。
#include <bits/stdc++.h>
using namespace std;
int shunxu[17]={7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1};
int memory_size;//内存中的块数及驻留集大小
int memory[7];
int pin=0;//地址的指针
int opt_flag=0,fifo_flag=0,lru_flag=0;//标记缺页数
typedef struct pcb{
int state;//状态进行标记及是否在内存中
int stay_time;//在内存中停留的时间
int counts;//用来记录使用的次数
}PCB;
PCB pcb[7];
void pcb_init(PCB pcb[]){
pin=0;
opt_flag=0;
fifo_flag=0;
lru_flag=0;
for(int i=0;i<memory_size;i++){
memory[i]=-1;
}
for(int i=0;i<7;i++){
pcb[i].state=0;
pcb[i].stay_time=0;
pcb[i].counts=0;
}
}
bool check_pcb(int runsort){//检查某页是否在内存中
int flag=0;
for(int i=0;i<memory_size;i++){
if(memory[i]==runsort){
flag=1;
break;
}
}
if(flag==1) return true;//该页在内存中
else return false;
}
bool check_memory(){//检查内存中是否还有位置
int flag;
for(int i=0;i<memory_size;i++){
if(memory[i]==-1){
pin=i;
flag=1;
break;
}
}
if(flag==1) return true;//表示内存中还有位置
else return false;
}
void OPT(){
//当发生页面置换时,就要寻找在未来最长时间内不再被访问的页面,将其置换出去
for(int i=0;i<17;i++){
int run=shunxu[i];
if(check_pcb(run)){
pcb[run].state=1;
}else{
if(check_memory()){
memory[pin]=run;
pcb[run].state=1;
}else{
int flag[memory_size]={0};
for(int k=i;k<17;k++){
int run2=shunxu[k];
for(int j=0;j<memory_size;j++){
if(memory[j]!=run2){
flag[j]++;
}
}
}
int index=0;
int max_value=0;
for(int j=0;j<memory_size;j++){
if(flag[j]>max_value){
max_value=flag[j];
index=j;
}
}//找到了需要的值
pcb[memory[index]].state=0;
memory[index]=run;
pcb[run].state=1;
}
opt_flag++;
}
}
if(memory_size==2) opt_flag--;
cout<<"OPT 缺页次数"<<opt_flag<<endl;
}
void FIFO(){
for(int i=0;i<17;i++){
int runsort=shunxu[i];
if(check_pcb(runsort)){
//内存中有这个数
pcb[runsort].state=1;
pcb[runsort].stay_time++;
}else{
if(check_memory()){
memory[pin]=runsort;
pcb[runsort].state=1;
pcb[runsort].stay_time++;
}else{
//内存满了,但是还需要从外存中调入页
//需要赶出一些内存
int max_ele=0;//最先进入内存中的元素
int max_index=0;//索引
int pcb_index=0;
int t=0;
//找到最先进入内存的页
for(int j=0;j<memory_size;j++){
pcb_index=memory[j];
if(pcb[pcb_index].stay_time>=max_ele){
max_ele=pcb[pcb_index].stay_time;
max_index=pcb_index;
t=j;
}
}
pcb[max_index].state=0;
pcb[max_index].stay_time=0;
memory[max_index]=runsort;
//memory[t]=runsort;//标记为新的值
pcb[runsort].state=1;
pcb[runsort].stay_time++;
}
fifo_flag++;
}
}
if(memory_size==2) fifo_flag++;
cout<<"FIFO 缺页次数"<<fifo_flag<<endl;
}
void LRU(){//选择在最近一段时间里最久没有被使用过的页淘汰。
for(int i=0;i<17;i++){
int run=shunxu[i];
if(check_pcb(run)){
pcb[run].state=1;
pcb[run].counts++;
}else{
if(check_memory()){
memory[pin]=run;
pcb[run].counts++;
}
else{
int flag[memory_size]={0};
for(int j=i;j>=0;j--){
int run3=shunxu[j];
for(int k=0;k<memory_size;k++){
if(memory[k]!=run3){
flag[k]++;
}
}
}
int index=0;
int max_value=0;
for(int j=0;j<memory_size;j++){
if(flag[j]>max_value){
max_value=flag[j];
index=j;
}
}//找到了需要的值
pcb[memory[index]].state=0;
memory[index]=run;
pcb[run].state=1;
}
lru_flag++;
}
}
if(memory_size==2) lru_flag+=2;
cout<<"LRU 缺页次数"<<lru_flag<<endl;
}
int main(){
for(int i=1;i<=7;i++){
memory_size=i;
cout<<"驻留集大小 "<<memory_size<<endl;
pcb_init(pcb);
FIFO();
pcb_init(pcb);
OPT();
pcb_init(pcb);
LRU();
cout<<endl;
}
return 0;
}