Nachos实习——Lab2虚拟内存实习报告

本文详述了作者在Nachos操作系统实习中Lab2关于虚拟内存的实现,包括TLB异常处理、置换算法(FIFO与CLOCK)、分页式内存管理和多线程支持。作者通过阅读源代码,理解了TLB机制和地址转换,并实现了缺页中断处理,最后介绍了挑战性的Lazy-loading机制。
摘要由CSDN通过智能技术生成

Nachos实习——Lab2虚拟内存实习报告

内容一:总体概述

本次实验主要是通过阅读相关代码,了解 nachos用户程序的执行过程,之后完成TLB,页表和虚拟内存等的实现。。其中第一部分主要内容是实现TLB相关异常处理和置换算法,当前的 nachos只支持单个用户程序,没有用到TLB。第二部分的主要内容是实现全局内存管理机制,使得 nachos内存可以同时存在多个线程。第三部分的主要内容是实现程序运行过程中发生缺页中断时,才会将所需的页面从磁盘调入内存。Challenge部分是增加线程挂起状态以及实现倒排页表。

内容二:任务完成情况

Exercise 1 Exercise 2 Exercise 3 Exercise 4 Exercise 5 Exercise 6 Exercise 7 Challenge
完成情况 Y Y Y Y Y Y Y Y

内容三:具体完成Exercise情况

一、TLB异常处理

目前,Nachos系统对于内存的管理是基于软件模拟的TLB机制。其工作原理、异常处理、替换算法等方面,与分页式内存管理非常相像。

Exercise 1 源代码阅读
  • 阅读code/userprog/progtest.cc,着重理解nachos执行用户程序的过程,以及该过程中与内存管理相关的要点。
  • 阅读code/machine目录下的machine.h(cc),translate.h(cc)文件和code/userprog目录下的exception.h(cc),理解当前Nachos系统所采用的TLB机制和地址转换机制。
1、userprog/progtest.cc

progtest.cc文件是Nachos系统中和执行用户程序相关的文件。在里面定义了两个函数。其中StartProcess函数是用来加载并执行用户程序的。具体流程如下:

  • 首先传入文件名,并打开该文件。之后会对该文件的文件格式进行一个判断。

  • 之后通过类 AddrSpace(在userprog/addrspace.cc文件下定义)的构造函数为用户程序分配并初始化地址空间,分配给当前线程/

  • 初始化用户寄存器的值,调用 RestoreState函数,将 machine的 pageTable指向该 AddrSpace对象的页表,将页表加载到 machine中

  • 调用 machine>Run执行用户程序。

Progtest.cc中还有一个ConsoleTest函数,用于控制台输入输出的测试。

2、machine/machine.cc和machine/machine.h

这两个文件主要用于模拟 nachos用户程序运行的机器。 machine.h中定义了一些内存相关的参数,如内存大小、TLB大小等,还有一些异常的种类和一些特殊用户寄存器的编号。还定义了两个类 Instruction和machine。类 Instruction用于将目标代码转为mips可执行的代码。Machine类模拟机器的运行。此外还有一个外部函数用来进行异常处理的。其中TLB的初始化是在machine/machine.cc文件中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AfoGykpf-1604393159510)(/Users/jaggerqian/Library/Application Support/typora-user-images/image-20201029183142093.png)]

目前默认是没有使用的,如需使用需要在userprog/Makefile文件中添加宏。

3、machine/translate.h(cc)和userprog/exception.h(cc)

在translate头文件中定义了页表TranslationEntry类,包含物理页号、虚拟页号、有效位、访问位、只读位、更改位等属性。translate.cc文件中实现了machine的读写内存和地址转换功能。地址转换有两种情况,使用线性页表或使用TLB。目前没有使用tlb所以直接跳转到tlb=null下面执行。在执行地址转换过程中可能会抛出各种异常。而异常的处理则使用userprog/exception.h(cc)文件下的ExceptionHandler函数。

通过阅读以上文件,我画了一个用户程序执行图。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Edt79bSw-1604393159511)(/Users/jaggerqian/Library/Application Support/typora-user-images/image-20201027163038452.png)]

Exercise 2 TLB MISS异常处理

修改code/userprog目录下exception.cc中的ExceptionHandler函数,使得Nachos系统可以对TLB异常进行处理(TLB异常时,Nachos系统会抛出PageFaultException,详见code/machine/machine.cc)

1、设计思路

首先Translate()方法,启动TLB,让用户程序在运行的时候先访问 TLB,如果出现 TLB MISS,会立刻抛出一个 RaiseException(),然后通过 ExceptionHandler()处理这个缺页异常,处理的动作就是让系统从pageTable 页表中查找要找的页表项。

2、userprog/Makefile

我们需要使用TLB,但是TLB并没有启用(在Exercise1里面解释过),所以我们需要先在userprog/Makefile添加宏
在这里插入图片描述

3、machine/translate.cc

因为系统是默认没有启用TLB的,但是我们现在启用了TLB,所以我们应该注释掉ASSERT(tlb == NULL || pageTable == NULL); ,否则会报错Assertion failed: line 203, file "../machine/translate.cc"

4、userprog/exception.cc

修改ExceptionHandler函数,因为之前系统是没有PageFaultException异常的(因为之前系统默认是把物理页面全部装入内存的,也没有启用TLB所以不会出现PageFaultException),所以我们需要添加PageFaultException,并进行处理。

else if(which == PageFaultException){
    	if (machine->tlb == NULL) { 
        //页表失效,因为默认不会出现所以直接使用ASSERT(FALSE);
            ASSERT(FALSE);
        } else { 
        //快表失效,处理流程是首先调用 machine的ReadRegister函数,从BadVAddrReg寄存器中取出发生异常的虚拟地址,并算出vpn。然后确定快表替换的表项,如果快表存在空的表项,那么直接使用空的表项,否则根据特定的规则确定替换的表项。
            DEBUG('m', "=> TLB miss (no TLB entry)\n");
            int BadVAddr = machine->ReadRegister(BadVAddrReg); 
            TLBMissHandler(BadVAddr);
        }
        return;
}
int position = 0;
void TLBMissHandler(int virtAddr)//快表失效处理函数
{
    unsigned int vpn;
    vpn = (unsigned) virtAddr / PageSize;
    machine->tlb[position] = machine->pageTable[vpn];
  //下面的Exercise3才实现了具体快表置换算法,这里为了简化测试,只使用了2个size的TLB
    if(position==0) 
    	position = 1;
    else 
    	position = 0;
}
5、测试结果截图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K0qjgj2T-1604393159514)(/Users/jaggerqian/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9/4bd6fb1bd54c6c60eedfec9d2b01e055/Message/MessageTemp/9e20f478899dc29eb19741386f9343c8/Image/1201603976836_.pic_hd.jpg)]

Exercise 3 置换算法

为TLB机制实现至少两种置换算法,通过比较不同算法的置换次数可比较算法的优劣。

1、FIFO算法

算法的思想是每次淘汰最先进入TLB的页面。具体实现方式则是每次移除块表数组的第一项,然后一次将后面的往前移,新的表项放在快表数组的尾项。

userprog/exception.cc

void TLBAlgoFIFO(int virtAddr)
{
   
    int position1 = -1;
    unsigned int vpn;
    vpn = (unsigned) virtAddr / PageSize;
 		//寻找空的TLB数组
    for (int i = 0; i < TLBSize; i++) {
   
        if (machine->tlb[i].valid == FALSE) {
   
            position1 = i;
            break;
        }
    }
    // 如果满了,移除首项,然后把每一项往前移动,然后放在最后一项
    if (position1 == -1) {
   
        position1 = TLBSize - 1;
        for (int i = 0; i < TLBSize - 1; i++) {
   
            machine->tlb[i] = machine->tlb[i+1];
        }
    }
    //更新TLB
    machine->tlb[position1] = machine->pageTable[vpn];
}
2、CLOCK时钟置换算法

Nachos系统已经定义了TLB的use和valid,所以我们可以很方便的实现时钟算法。具体实现是首先判断valid的值,看该位置是否被访问过,如果为false则直接进行替换;如果为true,则进一步判断use的值,来看是否被修改过,如果修改过则将其值置为false,然后判断下一位。如果为use为false则直接进行替换.

int position3 = 0;
void TLBAlgoClock(int virtAddr)
{
   
    //寻找那个use和valid都为0的位置,选取的顺序为(0,0)->(0,1)->(1,0)->(1,1)
    unsigned int vpn;
    vpn = (unsigned) virtAddr / PageSize;
    while (1) {
   
        position3 %= TLBSize;
        if (machine->tlb[position3].valid == FALSE) {
   
            break;
        } else  {
   
            if (machine->tlb[position3].use) {
   
               //更新use的值
                machine->tlb[position3].use = FALSE;
                position3++;
            } else {
   
                break;
            }
        }
    }
    //更新TLB
    machine->tlb[position3] = machine->pageTable[vpn];
    machine->tlb[position3].use = TRUE;
}
3、测试两个算法,并打印出TLB相关信息

首先在translate.cc中设置两个全局变量, TLBMissCount = 0;(记录TLB MISS);TranslateCount = 0(记录进程页面访问次数)。并在machine.h中进行扩展声明。

然后在每次发生PageFaultException让TLBMissCount+1;在每次执行TranslateCount函数时,让TranslateCount+1。分别调用两个算法最终在程序执行结束退出后调用debug函数打印出TLB缺页次数,缺页率等信息。

void
ExceptionHandler(ExceptionType which)
{
   
    if ((which == SyscallException) && (type == SC_Halt)) {
   
      	//	在程序执行结束后打印TLB信息
    		DEBUG('T', "TLB Miss: %d, TLB Hit: %d, Total Translate: %d, TLB Miss Rate: %.2lf%%\n",
        TLBMissCount, TranslateCount-TLBMissCount, TranslateCount, (double(TLBMissCount*100)/(TranslateCount));      
    } else if(which == PageFaultException){
   
      //发生缺页终端则让TLBMissCount++
        TLBMissCount++;
    	if (machine->tlb == NULL) {
    // linear page table page fault
					……………………
        } else {
    
            //TLBMissHandler(BadVAddr);//TLB MISS测试
            TLBAlgoFIFO(BadVAddr);//FIFO算法测试
            //TLBAlgoClock(BadVAddr);//CLOCK时钟算法测试
        }
        return;
    }
}

记得在translate函数中让TranslateCount++

4、测试结果

测试说明:我试用了系统提供的sort排序进行测试,在最开始的时候报错Assertion failed: line 81, file "../userprog/addrspace.cc,仔细阅读代码发现是因为系统给的sort排序超出了内存限制,同时原来sort在最后接触进行的系统调用EXIT 尚未在本系统中实现,所以我在原来的基础上进行了修改,并重新make.

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值