在请求分页系统中,为什么有时要IO互锁

在请求分页系统中,为什么有时要IO互锁,第1张

3.请求分页系统(1)请求分页对页表的扩充在请求分页系统中所使用的主要数据结构仍然是页表。它对页式系统中的页表机制进行了扩充但其基本作用是实现由用户地址空间到物理内存空间的映射。由于只将应用程序的一部分装入内存,还有一部分仍在磁盘上,故需在页表中增加若干项,供 *** 作系统实现虚拟存储器功能时参考。常见的系统中,一般对页表的表项进行如下扩充:除了页号对应的物理块号,还增加了状态位、修改位、外存地址和访问字段等。·状态位,用于指示该页是否已经调入了内存。该位一般由 *** 作系统软件来管理,每当 *** 作系统把一页调人物理内存中时,置位。相反,当 *** 作系统把该页从物理内存调出时,复位。CPU对内存进行引用时,根据该位判断要访问的页是否在内存中,若不在内存之中,则产生缺页中断。·修改位,表示该页调入内存后是否被修改过。当CPU以写的方式访问页面时,对该页表项中的修改位置位。该位也可由 *** 作系统软件来修改,例如,当 *** 作系统将修改过页面保存在磁盘上后,可将该位复位。·外存地址,用于指出该页在外存上的地址,供调人该页时使用。·访问宇段,用于记录本页在一定时间内被访问的次数,或最近已经有多长时间未被访问。提供给相应的置换算法在选择换出页面时参考。(2)对缺页中断的支持在请求分页系统中,CPU硬件一定要提供对缺页中断的支持,根据页表项中的状态位判断是否产生缺页中断。缺页中断是一个比较特殊的中断,这主要体现在如下两点:·在指令的执行期间产生和处理缺页信号。通常的CPU外部中断,是在每条指令执行完毕后检查是否有中断请求到达。而缺页中断,是在一条指令的执行期间,发现要访问的指令和数据不在内存时产生和处理的。·一条指令可以产生多个缺页中断。例如,一条双 *** 作数的指令,每个 *** 作数都不在内存中,这条指令执行时,将产生两个中断。CPU提供的硬件支持,还要体现在当从中断处理程序返回时,能够正确执行产生缺页中断的指令。(3)页面调度策略虚拟存储器系统通常定义三种策略来规定如何(或何时)进行页面调度:调入策略、置页策略和置换策略。(4)置换算法(replacementalgorithm)决定在需要调入页面时,选择内存中哪个物理页面被置换。置换算法的出发点应该是,把未来不再使用的或短期内较少使用的页面调出。而未来的实际情况是不确定的,通常只能在局部性原理指导下依据过去的统计数据进行预测。常用的算法有以下几种:·最佳算法(optimal,OPT)。选择“未来不再使用的”或“在离当前最远位置上出现的”页面被置换。这是一种理想情况,是实际执行中无法预知的,因而不能实现,只能用作性能评价的依据。·最近最久未使用算法(LeastRecentlyUsed,LRU)。选择内存中最久未使用的页面被置换,这是局部性原理的合理近似,性能接近最佳算法。但由于需要记录页面使用时间的先后关系,硬件开销太大。LRU可用如下的硬件机构帮助实现:一个特殊的栈:把被访问的页面移到栈顶,于是栈底的是最久未使用页面。每个页面设立移位寄存器:被访问时左边最高位置1,定期右移并且最高位补0,于是寄存器数值最小的是最久未使用页面。·先进先出算法(FIFO)。选择装入最早的页面置换。可以通过链表来表示各页的装入时间先后。FIFO的性能较差,因为较早调入的页往往是经常被访问的页,这些页在FIFO算法下被反复调入和调出,并且有Belady现象。所谓Belady现象是指:采用FIFO算法时,如果对—个进程未分配它所要求的全部页面,有时就会出现分配的页面数增多但缺页率反而提高的异常现象。Belady现象可形式化地描述为:一个进程户要访问M个页,OS分配舻个内存页面给进程P;对一个访问序列S,发生缺页次数为PE(占,N)。当N增大时,PE(S,N)时而增大时而减小。Belady现象的原因是FIFO算法的置换特征与进程访问内存的动态特征是矛盾的,即被置换的页面并不是进程不会访问的。·时钟(clock)算法。也称最近未使用算法(NotRecentlyUsed,NRU),它是LRU和FIFO的折中。每页有一个使用标志位(usebit),若该页被访问则置userbit=l,这是由CPU的硬件自动完成的。置换时采用一个指针,从当前指针位置开始按地址先后检查各页,寻找usebit=0的面作为被置换页。指针经过的userbit=l的页都修改userbit=O,这个修改的过程是 *** 作系统完成的,最后指针停留在被置换页的下一个页。·最不常用算法(LeastFrequentlyUsed,LFU)。选择到当前时间为止被访问次数最少的页面被置换。每页设置访问计数器,每当页面被访问时,该页面的访问计数器加1。发生缺页中断时,淘汰计数值最小的页面,并将所有计数清零。·页面缓冲算法(pagebuffering)。它是对FIFO算法的发展,通过建立置换页面的缓冲,这样就有机会找回刚被置换的页面,从而减少系统I/0的开销。页面缓冲算法用FIFO算法选择被置换页,把被置换的页面放人两个链表之一。即是如果页面未被修改,就将其归人到空闲页面链表的末尾,否则将其归人到已修改页面链表。空闲页面和已修改页面,仍停留在内存中一段时间,如果这些页面被再次访问,只需较小开销,被访问的页面就可以返还作为进程的内存页。需要调入新的物理页面时,将新页面内容读人到空闲页面链表的第一项所指的页面,然后将第一项删除。当已修改页面达到一定数目后,再将它们一起调出到外存,然后将它们归人空闲页面链表。这样能大大减少I/O *** 作的次数。

传统存储管理

特征

时间局部性:如果执行了程序中的某条指令,那么不久后这条指令很有可能再次执行;如果某个数据被访问过,不久之后该数据很可能再次被访问(因为程序中存在大量循环)

空间局部性:一旦程序访问了某个存储单元,在不久之后,其附近的存储单元很有可能被访问(因为很多数据在内存中是连续存放的,并且程序的指令也是顺序地在内存中存放的

寄存器

高速缓存

内存

外存(如磁盘、磁带等)

越往上容量越小,访问速度越快,成本越高

越往下容量越大,访问速度越慢,成本越低

高速缓存技术的思想:将近期会频繁访问到的数据放到更高速的存储器中,暂时用不到的数据放在更低速存储器中

快表机构就是将近期常访问的页表项副本放到更高速的cache中

基于局部性原理,在程序装入时,可以将程序中很快就会用到的部分装入内存,暂时用不到的部分留在外存,就可以让程序开始执行

在程序执行过程中,当所访问的信息不在内存时,由 *** 作系统负责将所需信息从外存调入内存,然后继续执行程序

若内存空间不够,由 *** 作系统将内存中暂时用不到的信息换出到外存

因此,在 *** 作系统的管理下,在用户看来似乎有一个比实际内存大得多的内存,这就是虚拟内存

*** 作系统虚拟性的一个体现,实际的物理内存大小没有变,只是在逻辑上进行了扩充

虚拟内存的最大容量是由计算机的地址结构(CPU寻址范围)确定的

虚拟内存的实际容量 = min(内存外存容量之和,CPU寻址范围)

虚拟内存有以下三个主要特征

虚拟内存技术,允许一个作业多次调入内存。如果采用连续分配方式,会不方便实现。因此,虚拟内存的实现需要建立在离散分配的内存管理方式基础上

传统的非连续分配存储管理

基本分页存储管理

基本分段存储管理

基本段页式存储管理

虚拟内存的实现

请求分页存储管理

请求分段存储管理

请求段页式存储管理

主要区别:在程序执行过程中,当所访问的信息不在内存时,由 *** 作系统负责将所需信息从外存调入内存,然后继续执行程序。若内存空间不够,由 *** 作系统负责将内存中暂时用不到的信息换出到外存

*** 作系统要提供请求调页/段功能、页面/段置换功能

请求分页存储管理和基本分页存储管理的主要区别

页表机制

页表项:内存块号、状态位、访问字段、修改位、外存地址,页号时隐含的

内存块号是页面在内存中对应的页框号,如果状态位为0,则内存块号为无

状态位表示是否已被调入内存

访问字段记录最近被访问过几次,或者上次访问时间,由此 *** 作系统能够提供置换算法

修改位记录页面被调入内存后是否被修改过,如果没有,就不需要浪费时间写回外存

外存地址是页面在外存中的存放位置

缺页中断机构

在请求分页系统中,每当要访问的页面不在内存时,便会产生一个缺页中断,然后由 *** 作系统的缺页中断处理程序处理中断(内中断)

此时缺页的进程阻塞,放入阻塞队列,调页完成后再将其唤醒,放回就绪队列

如果内存中有空闲块,则为进程分配一个空闲块,将所缺页面装入该块,并修改页表中相应的页表项

如果内存中没有空闲块,则由页面置换算法选择一个页面淘汰,若该页面在内存期间被修改过,则要将其写回外存,为修改过的页面不用写回外存

一条指令再执行期间可能产生多次缺页中断(copy A to B)

新增的步骤

页面的换入、换出需要磁盘IO,会有较大的开销,因此好的页面置换算法应该追求更少的缺页率

缺页中断≠页面置换

发生缺页中断会发生调页,只有内存块满了才发生页面置换

最佳置换算法OPT:每次淘汰以后永不使用或最长时间内不再被访问的页面

理想化的算法,很难实现

先进先出算法FIFO:每次淘汰最先进入内存的页面

实现:把调入内存的页面根据调入的先后顺序排成队列,页面置换时换出队头页面,新调入的页面排到队尾

优点:实现简单

缺点1:belady异常,为进程分配的物理块数增大时,缺页次数不减反增的异常现象。只有FIFO会产生belady异常。

缺点2:算法与进程实际运行时的规律不适应,因为先调入的页面有可能最经常被访问,因此算法性能差

最近最久未使用置换算法LRU:淘汰最近最久未使用的页面

实现方法:赋予每个页面对应的页表项中,用访问字段记录该页面自上次被访问以来所经历的时间t

优点:性能最接近OPT

缺点:实现困难、开销大

时钟置换算法CLOCK/NRU

简单NRU:为每一个页表项设置一个访问位,再将内存中的页面都通过连接指针连成一个循环队列,当某页被访问时,访问位为1,只需检查页的访问位。如果为0,就将该页换出,否则将其改为0,暂不换出,继续向后扫描,若第一轮扫描都是1,将这也页面的访问位改为0后,进行第二轮扫描,第二轮扫描中一定会有访问位为0的页面,将其换出。因此最多经过两轮扫描

改进NRU:如果淘汰的页面没有被修改过,就不需要执行IO *** 作,只有淘汰的页面被修改过时,才需要写回外存。因此,同时考虑最近有无访问和有无修改,在其他条件相同时,优先淘汰没有修改过的页面,避免IO *** 作

第一轮:找到第一个访问位和修改位都为0的页面进行替换,如果没有找到进行下一轮扫描

第二轮:查找第一个访问位为0,修改位为1的页面进行替换,本轮将所有被扫描过的访问位设置为0,如果没有进行下一轮扫描

第三轮:查找0,0替换否则下一轮

第四轮:查找0,1替换

最多会进行四轮扫描

驻留集:请求分页管理中给进程分配的物理块的集合

在采用了虚拟存储技术的系统中,驻留集大小一般小于进程的总大小

驻留集太小,导致缺页频繁,系统要花大量时间处理缺页,实际用于进程推进的时间很少

驻留集太大,会导致多道程序并发度下降,资源利用率降低

固定分配: *** 作系统为每个进程分配一组固定数目的物理块,在进程运行期间不再改变

可变分配:先为每个进程分配一定数目的物理块,在进程运行期间,可根据情况作适当的增加或减少

局部置换:发生缺页时只能选进程自己的物理地址块进行置换

全局置换:可以将 *** 作系统保留的空闲物理块分配给缺页进程,也可以将别的进程持有的物理块置换到外存,再分配给缺页进程

不存在固定分配全局置换的策略,因为全局置换意味着一个进程拥有的物理块数量必然改变

其他三种组合存在

固定分配局部置换:系统为每个进程分配一定数量的物理块,在整个运行期间都不改变。若进程在运行中发生缺页,并且需要进行页面置换,则只能从该进程在内存中的页面中选出一页换出,然后再调入需要的页面

缺点:很难在刚开始就确定应为每个进程分配多少个物理地址块才算合理(采用这种策略的系统可以根据进程大小、优先级、或是根据程序员给出的参数来确定为一个进程分配的内存块数

可变分配全局置换:刚开始会为进程分配一定数量的物理块。 *** 作系统会保持一个空闲物理块队列,当某进程发生缺页时,从空闲物理块中取出一块分给该进程;若无空闲物理块,则选择一个未锁定的页面换出到外存,再将该物理块分配给缺页的进程。采用这种策略时,只要某进程发生缺页,都将获得新的物理块,仅当空闲物理块用完时,系统才选择一个未锁定的页面调出。被选择调出的页面可能是系统中任何一个进程的页面,因此这个被选中的进程拥有的物理块会减少,缺页率会增加

只要缺页就给该进程分配新的物理块

可变分配局部置换:刚开始会为每个进程分配一定数量的物理块,当某进程发生缺页时,只允许从该进程自己的物理块中选出一个进行页面置换。如果进程在运行过程中频繁缺页,系统会为该进程多分配几个物理块,直至该进程缺页率趋于适当程度;反之,如果缺页率太低,就是当减少分配给该进程的内存块数

要根据发生缺页的频率来动态增加或减少进程的物理块

何时调入页面

从何处调入页面

对换区:读写速度更快,采用连续分配方式

文件区:读写速度更慢,采用离散分配方式

抖动/颠簸现象:刚刚换出的页面马上要换入内存,刚刚换入的页面马上要换出外存,这种频繁的页面调度行为称为抖动/颠簸

主要原因是进程频繁访问的页面数目高于可用的物理块数(分配给进程的物理块不够)

为进程分配物理块太少会使进程发生抖动现象,为进程分配的物理块太多会降低系统的并发度降低某些资源的利用率。因此提出了“工作集”的概念

工作集:在某段时间间隔里,进程实际访问页面的集合

驻留集:请求分页存储管理中给进程分配的内存块的集合

驻留集不能小于工作集,否则进程运行过程中将频繁缺页

#include<iostreamh>

#include<stdlibh>

#include<iomaniph>

#include"windowsh"

#include"osh"

#define n 64//实验中假定主存的长度

#define m 4//实验中假定每个作业分得主存块块数

int p[m];//定义页

struct

{

short int lnumber;//页号

short int flag;//表示该页是否在主存,“1”表示在主存,“0”表示不在主存

short int pnumber;//该页所在主存块的块号

short int write;//该页是否被修改过,“1”表示修改过,“0”表示没有修改过

short int dnumber;//该页存放在磁盘上的位置,即磁盘块号

short int times;//被访问的次数,用于LRU算法

}page[n];//定义页表

//各个函数的实现如下:

computer::computer()

{

int i;

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

{

page[i]lnumber = i;

page[i]flag = 0;

page[i]pnumber = 10000;//用10000表示为空

page[i]write = 0;

page[i]dnumber = i;

page[i]times = 0;

}//初始化页表

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

{

page[i]pnumber = i;

}

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

{

p[i] = i;

page[i]flag = 1;

}//初始化页

}

void computer::showpagelist()

{

int i;

cout<<"页号"<<"\t"<<"是否在主存中"<<"\t"<<"块 号"<<"\t"<<"是否被修改过"<<"\t"<<"磁盘块号"<<"\t"<<"访问次数"<<endl;

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

{

cout<<page[i]lnumber<<"\t"<<page[i]flag<<" "<<page[i]pnumber<<"\t"<<page[i]write<<" "<<page[i]dnumber<<" \t"<<page[i]times<<endl;

}

}

void computer::showpage()

{

int i;

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

{

cout<<"\t"<<p[i];

}

cout<<endl;

}

void computer::transformation()

{

unsigned logicAddress,logicNumber,innerAddress,physicsAddress,physicsNumber;

int i,head=0,fail = 0;

int method,temppage=0;

short int times = 10000;

cout<<"请输入一个逻辑地址(四位十六进制数):";

cin>>hex>>logicAddress;//读入逻辑地址

logicNumber = logicAddress >> 10;//得到页号

cout<<"页号为:"<<logicNumber<<endl;

innerAddress = logicAddress & 0x03ff;//得到页内地址

cout<<"页内地址为:"<<innerAddress<<endl;

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

{

if(logicNumber==(unsigned)page[i]lnumber)

{

if(page[i]flag == 1)

{

cout<<"请求的页面在主存中!"<<endl;

page[i]times++;

physicsNumber = page[i]pnumber;//由页号得到块号

cout<<"请求的主存块号为:"<<physicsNumber<<endl;

physicsAddress = physicsNumber << 10 |innerAddress;//得到物理地址

cout<<"请求的物理地址为:"<<physicsAddress<<endl;//输出物理地址

break;

}

else

{

cout<<"请求的页面不在主存中! 将进行缺页中断处理!"<<endl<<"请选择算法!"<<endl;

cout<<"1先进先出"<<endl<<"2最近最少用"<<endl<<"请选择置换算法:";

cin>>method;

if(method == 1) //采用先进先出算法

{

cout<<"采用先进先出算法!"<<endl;

fail = p[head];

cout<<"第"<<fail<<"页将被替换!"<<endl;

p[head] = logicNumber;

head = (head+1) % m;

if(page[fail]write == 1)

cout<<"第"<<fail<<"页曾被修改过!"<<endl;

page[fail]flag = 0;

page[logicNumber]flag = 1;

page[logicNumber]write = 0;

page[logicNumber]pnumber = page[fail]pnumber;

page[fail]pnumber = 10000;

page[logicNumber]times++;

break;

}

else if(method == 2) //采用最近最少用算法

{

cout<<"采用最近最少用算法!"<<endl;

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

{

if(page[i]flag == 1)

{

if(page[i]times<times)

{

times = page[i]times;

temppage = page[i]lnumber;

}

}

}

cout<<"第"<<temppage<<"页将被替换!"<<endl;

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

{

if(p[i] == temppage)

{

p[i] = logicNumber;

}

}

if(page[temppage]write == 1)

cout<<"第"<<temppage<<"页曾被修改过!"<<endl;

page[temppage]flag = 0;

page[logicNumber]flag = 1;

page[logicNumber]write = 0;

page[logicNumber]pnumber = page[temppage]pnumber;

page[temppage]pnumber = 10000;

page[logicNumber]times++;

break;

}

else

{ cout<<"你输入有误,即将退出!";

exit(1);

}

}

}

}

}

void main()

{

char c,d;

computer os;

cout<<"页表正在初始化中,3秒钟后为你显示页和页表!"<<endl;

Sleep(3000);

osshowpage();

osshowpagelist();

T:

ostransformation();

cout<<"是否显示页和页表?(Y/N)";

cin>>c;

switch(c)

{

case 'y':

osshowpage();

osshowpagelist();

case 'n':

cout<<"是否继续进行请求分页?(Y/N)";

cin>>d;

if (d=='Y'||d=='y')

goto T;

else if (d=='N'||d=='n')

exit(1);

else

cout<<"输入错误!"<<endl;

default:cout<<"输入错误!"<<endl;

}

}

C、被中断的后一条

在CPU的控制部件中有一个能检测中断的机构,在每条指令执行周期的最后时刻扫描中断寄存器,询问是否有中断信号。若有,则CPU停止执行当前程序的后续指令,转入中断处理程序,处理完中断后应执行后续指令。作业在执行中发生了缺页中断,经 *** 作系统处理后,应让其执行被中断的后一条指令。因此,选择C。

扩展资料:

控制单元的功能就是根据用户预先编好的程序,依次从存储器中取出各条指令,放在指令寄存器IR中,通过指令译码(分析)确定应该进行什么 *** 作,然后通过 *** 作控制器OC,按确定的时序,向相应的部件发出微 *** 作控制信号。 *** 作控制器OC中主要包括节拍脉冲发生器、控制矩阵、时钟脉冲发生器、复位电路和启停电路等控制逻辑。

参考资料来源:百度百科-CPU

缺页中断就是异常,也就是故障。

在执行一条指令时,如果发现他要访问的页没有在内存中(存在位为0),那么停止该指令的执行,并产生一个页不存在异常,对应的故障处理程序可通过从外存加载加载该页到内存的方法来排除故障,之后,原先引起的异常的指令就可以继续执行,而不再产生异常。

以上就是关于在请求分页系统中,为什么有时要I/O互锁全部的内容,包括:在请求分页系统中,为什么有时要I/O互锁、内存扩充之虚拟存储技术、求用c++程序设计的实验:模拟分页式存储管理中硬件的地址转换和用先进先出调度算法(FIFO)处理缺页中断。等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10122807.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存