ImageVerifierCode 换一换
格式:DOCX , 页数:14 ,大小:21.92KB ,
资源ID:4123463      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/4123463.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(操作系统实验报告2.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

操作系统实验报告2.docx

1、操作系统实验报告2Nachos虚存实验报告一、 实验名称:Nachos虚存二、 实验目的:本实验牵涉到Nachos虚存子系统的部分实现,也是第一次用到Nachos的虚拟机。测试代码是一组覆盖了绝大部分虚存空间的数组操作,该虚存空间被映射到20个物理页中。地址转换和页表结构已给出。本实验的目的是要实现缺页处理程序,这需要在适当的时候将某些页面替换出/入。为了减少缺页和将页面从内存淘汰到磁盘的次数,要求实现以下五种页面替换算法: NRU(Not Recently Used)算法 SC(Second Chance)算法 Clock算法 Working Set算法 Aging算法三、 实验步骤1. 预

2、备(1) 素材:本实验的源代码是/home/nachos/mp3.tar文件。复制到本地目录后解包,要在userprog子目录下工作,也需阅读文件filesys/filesys.h,filesys/openfile.h,machine/translate.h,machine/timer.h,和bin/noff.h。本实验需修改文是memmanager.h和memmanager.cpp。(2) 分析代码: 每个地址空间都有相应的页表,页表中的每一项称为页表条目。在本实验中,我们会牵涉到其中的三个主要字段:USE、DIRTY和VALID,它们在machine/translate.h中有详细描述。A

3、ddrSpace结构包含了Nachos进程地址空间的所有信息:页表、页表长度等,以及操作地址空间的函数。当创建了一个新的进程时,该结构也就随之产生并初始化。所提供的代码已实现了页面调度机制,在该机制中,仅在一个执行进程访问页面时,才将它从可执行的源文件中读入物理内存。所以,在进程刚创建时,页表中的所有条目都是初始化为无效的(所有页表条目的有效位都置为false)。然而,访问这样的页面(不属于任何程序段)一般来说是不合法的。当初始化一个页表时,要生成一个报告,该报告说明哪些页面的访问是合法的,而哪些页面的访问是不合法的(Legal字段)。每个可执行程序都以一个头开始,它指定程序中所有程序段的虚存

4、范围。 开始时,调用AddrSpace:ReadSourcePage()函数来从可执行文件中读一个页面到物理内存。注意,该函数仅在进程第一次访问虚页时调用。至于后续的访问,如果页面不在物理内存中,则搜索替换文件而不是源文件。替换文件由类似与MainMemory的内存帧组成,只不过它们存储在磁盘上。一组称为“SwapOwners”的TranslationEntry指针用来跟踪指向替换文件中页面的页表条目,一个类似的结构“CoreOwners”则用来跟踪指向内存中页面的页表条目。 在执行阶段,仿真程序将在TranslationEntrys中设置适当的位,如:当出现写操作时置DIRTY=TRUE、当

5、出现写或读操作时置USE=TRUE。如果仿真器处理了这样一个TranslationEntry中的存储器请求:LEGAL=TRUE但VALID=FALSE,它将自陷到MemManager:faultIn()中去,这就是你要实现的地方:给定缺页的TranslationEntry,用PageIn()、PageOut()以及你要实现的将适当的缓冲页面调入物理页的方法,更新TranslationEntry并将控制权返回给虚拟机。阅读代码MemManager:PageFaultExceptionHandler(),它由ExceptionHandler()在接收到一个缺页异常时调用。关于如何实现MemMan

6、ager:faultIn()的一些细节和几点提示都以注释的方式在MemManager:PageFaultExceptionHandler()中给出。注意:在此函数中,程序计数器的值不应加一。在处理完异常且控制权返回给缺页进程后,引起缺页的那条指令将重新执行。2. 页面替换算法的实现本次实验对页面替换算法的实现主要是通过一个MemManagerr类来实现的,类中主要的函数有以下几个: faultIn是“handler”,而其它各种方法则聚合成了重要的功能: PageOut负责将页面写到备份存储中,它只处理脏页,因为其它的页面已在备份存储中或是与原始状态相比没有变化,所以其它的页面可以覆盖它; P

7、ageIn负责将页面读入指定的物理页,若该页不在备份存储中,则从原始文件中装载; MakeFreeFrame负责在没有空闲页时用适当的页面替换算法来选择一个牺牲页; doUpdation是一个定时中断处理程序(在memmanager.cc文件中),它修改translationEntries中适当的位来更新历史信息。整个实验修改的代码如下所示:(红色部分为修改的代码)int MemManager:makeFreeFrame () / victim is the number of the physical page to be swapped out int victim = 0; switch

8、(policy) case PAGEREPL_NRU: / 4.4.2 - Not Recently Used #ifdef CHANGE int i; bool find=false; for(i=0;(i!=NumPhysPages)&(!find);i+) if(!coreOwnersi-use) &(!coreOwnersi-dirty) victim=i; find=true; for(i=0;(i!=NumPhysPages)&(!find);i+) if(!coreOwnersi-use) &(coreOwnersi-dirty) victim=i; find=true; for

9、(i=0;(i!=NumPhysPages)&(!find);i+) if(coreOwnersi-use) &(!coreOwnersi-dirty) victim=i; find=true; #endif break; case PAGEREPL_FIFO: / 4.4.3 - FIFO int *ptr = fifoList-Remove(); victim = *ptr; #ifdef CHANGE if(ptr!=NULL) delete ptr; #endif break; case PAGEREPL_SC: / 4.4.4 - Second Chance #ifdef CHANG

10、E int *ptr = fifoList-Remove(); while(coreOwners*ptr-use) coreOwners*ptr-use=false; fifoList-Append(ptr); ptr = fifoList-Remove(); victim = *ptr; if(ptr!=NULL) delete ptr; #endif break; case PAGEREPL_CLOCK: / 4.4.5 - Clock #ifdef CHANGE while(coreOwnersclock_hand-use) coreOwnersclock_hand-use=false;

11、 clock_hand=(clock_hand+1)%NumPhysPages; victim=clock_hand; clock_hand=(clock_hand+1)%NumPhysPages; #endif break; case PAGEREPL_WS: / 4.4.8 - Working Set int v_timestamp = stats-totalTicks; #ifdef CHANGE for(int i=0;i!=NumPhysPages;i+) if(coreOwnersi-timeStamp timeStamp; victim=i; #endif break; case

12、 PAGEREPL_AGING: / 4.4.7 - Aging unsigned int v_bitmask = 0xFFFF; #ifdef CHANGE for(int i = 0; i != NumPhysPages; i+) if( historyi Test(i) coreOwnersi-use=false; #endif break; case PAGEREPL_AGING: / Aging Section 4.4.7 #ifdef CHANGE for(i = 0;i != NumPhysPages;i+) if(coreFreeMap-Test(i) historyi=his

13、toryi 1; if(coreOwnersi - use) historyi = historyi | (1 use = FALSE; #endif break; / the following dont use the timer interrupt case PAGEREPL_FIFO: / not used case PAGEREPL_SC: / not used case PAGEREPL_CLOCK: / not used case PAGEREPL_WS: / not used default: break; / end switch return;void MemManager

14、:pageIn (TranslationEntry * PTEntry, int physFrame) / MP3 - you need to make changes to the history keeping algorithms here / FIFO and Second Chance have been implemented for you switch(policy) case PAGEREPL_FIFO: / 4.4.3 - FIFO case PAGEREPL_SC: / 4.4.4 - SC int *ptr =new int; *ptr = physFrame; fif

15、oList-Append(ptr); break; case PAGEREPL_AGING: / 4.4.7 - AGING #ifdef CHANGE historyphysFrame = bitmask; #endif break; case PAGEREPL_NRU: / 4.4.2 - NRU case PAGEREPL_CLOCK: / 4.4.5 - CLOCK case PAGEREPL_WS: / 4.4.8 - WS default: break; return;(1)NRU算法的实现: 此算法是用R位和M位来构造的,R位在每次时间中断是被清零,以区别最近没有被访问和被访问的

16、页面,在系统中,R位和M位分别对应TranslationEntrys中的use和dirty字段,每次中断时,系统会调用doUpdation来进行中断处理,因此我们必须在doUpdation中将内存中所有页面的R位清零,也就是将use字段设为false。具体实现是在switch语句中的case PAGEREPL_NRU中加入:int i; for(i=0;i!=NumPhysPages;i+) if(coreFreeMap-Test(i) coreOwnersi-use=false; 要注意的是,在设置use字段时,如果此时coreOwnersi指向的内存页面为空就会发生严重的错误,所以我们必须

17、在设置之前加入一个判断语句if(coreFreeMap-Test(i),通过测试空闲位图的第i位(0为空,1为非空),来判断此页是否为空。当页面发生失效时,根据页面的R位和M位将其分为4类: 第0类:use=false,dirty=false 第1类:use=false,dirty=true 第2类:use=true,dirty=false 第3类:use=true,dirty=true我们将从最小编号的非空类中,选择第一个页面将其淘汰,具体实现是在makeFreeFrame中switch语句的case PAGEREPL_NRU中加入3个for循环: int i; bool find=fals

18、e; for(i=0;(i!=NumPhysPages)&(!find);i+) if(!coreOwnersi-use) &(!coreOwnersi-dirty) victim=i; find=true; for(i=0;(i!=NumPhysPages)&(!find);i+) if(!coreOwnersi-use) &(coreOwnersi-dirty) victim=i; find=true; for(i=0;(i!=NumPhysPages)&(!find);i+) if(coreOwnersi-use) &(!coreOwnersi-dirty) victim=i; find

19、=true; 这三个for循环依次寻找第0,1,2类页面,如果找到符合条件的页面,victim的值被置为i ,即符合条件的页面号,此页面将被置换掉,同时将find变量置为true,之后的循环便不再执行。当三个for循环执行完后,仍未找到符合条件的页面,那么所有页面都属于第3类,victim的值是默认的0,即第一个页面。 在实现这个算法的过程中,我曾考虑过用两个循环来实现,第一个循环检查每一类中是否有符合条件的页面,第二个循环在最小类中寻找一个符合条件的页面,由于在第一个循环中,无论编号较小的类中是否有页面,循环都必须继续,平均代价比三个for循环更大,所以最终决定用三个for循环来实现。(2)

20、SC算法的实现: SC算法只是对FIFO算法进行简单的修改:检查最老页面的use字段,如果为false,就置换此页面;如果为true,就将它置为false,并将此页面放到FIFO列表的末端。具体实现是在makeFreeFrame中switch语句的case PAGEREPL_SC中加入: int *ptr = fifoList-Remove(); while(coreOwners*ptr-use) coreOwners*ptr-use=false; fifoList-Append(ptr); ptr = fifoList-Remove(); victim = *ptr; if(ptr!=NUL

21、L) delete ptr; 我们用fifoList-Remove()取出FIFO链表头的页面号,即最老的页面号,用一个int指针指向该页面号,并判断该页面的use字段,如果为true,就将它置为false,并就调用fifoList-Append(ptr)函数将此页面号插入到FIFO链表的末端,继续取下一个链表头的页面号;如果为false,就将此页面号赋给victim,将此页面置换掉。最后将ptr指针指向的内存区域清空。(3)CLOCK算法的实现: Clock算法和SC算法的区别仅是实现上的不同,它将所有页面保存在一个类似钟面的环形链表中,用一个指针指向最老的页面,以减少SC算法在链表中移动页

22、面的代价。我们用coreOwners数组和求模操作来模拟环形链表,用一个clock_hand的正型变量来模拟表针。具体实现是在makeFreeFrame中switch语句的case PAGEREPL_CLOCK中加入: while(coreOwnersclock_hand-use) coreOwnersclock_hand-use=false; clock_hand=(clock_hand+1)%NumPhysPages; victim=clock_hand; clock_hand=(clock_hand+1)%NumPhysPages; clock_hand的值初始化为0,我们先判断第一个页

23、面的use字段,如果true,表示它最近被使用到,将use设为false,并将clock_hand的值置为(clock_hand+1)%NumPhysPages,进入下一次循环。这里的求模操作是一个关键,它保证了clock_hand的值在0到NumPhysPages之间循环,类似于一个表针。如果clock_hand所指的页面use字段为false,循环结束,将victim的值赋为clock_hand,此页面将被置换掉,并将表针向前移动一格,也就是将clock_hand的值设为(clock_hand+1)%NumPhysPages。(4) Working Set算法的实现: 这个算法中,我们认为

24、最早被访问的那个页面不在工作集中,将它置换出去,也就是说,我们要在内存中寻找最后一次访问时间最小的那个页面。页面中与最后访问时间相对应的是timeStamp字段,每次访问一个页面时,timeStamp都会被更新为访问时的时间。具体实现是在makeFreeFrame中switch语句的case PAGEREPL_WS中加入: for(int i=0;i!=NumPhysPages;i+) if(coreOwnersi-timeStamp timeStamp; victim=i; v_timestamp的初始值是当前系统时间,所有页面的最后访问时间都小于当前系统时间,所以可以将v_timestam

25、p作为一个临时变量,在遍历所有页面的时候储存最小的最后访问时间,我们用一个for循环遍历内存中的所有页面,并将每个页面的timeStamp与v_timestamp比较,如果小于v_timestamp,就将v_timestamp的值设为当前页面的timeStamp,并将victim的值置为当前页面号。这样,当遍历完所有页面时,v_timestamp值为所有页面的timeStamp的最小值,而victim的值也恰好是最小timeStamp值对应的页面,此页面将被置换出去。(5) Aging算法的实现: 在此算法中,每一个内存页面都分配了一个特定位数的计数器,每次时钟中断时,将所有计数器值右移一位,

26、然后将计数器的最高位设为R位的值,发生页面失效时,淘汰计数器值最小的页面。用一个无符号整形变量来表示一个计数器,无符号整形数组history的每一项代表一个页面的计数器,我们需要在调入页面的时候初始化计数器的值,具体实现是在pageIn的switch语句的case PAGEREPL_AGING中加入:historyphysFrame = bitmask; 整形变量bitmask的值为(1 Test(i) historyi=historyi 1; if(coreOwnersi - use) historyi = historyi | (1 use = FALSE; 我们用一个for循环遍历内存的每个页面。在对计数器修改之前,要先判断页面是否为空,如果为空,我们并不需要修改它的计数器。如果不为空,我们用historyi=historyi 1将其计数器的值右移一位。然后,我们继续判断该页面的use字段,如果为false,无需改变,因为右移一位后,最高位

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1