虚拟内存管理实习报告
- 格式:doc
- 大小:44.50 KB
- 文档页数:10
操作系统实验实验报告虚拟内存一、实验目的本次操作系统实验的目的是深入理解虚拟内存的概念、原理和实现机制,通过实际操作和观察,掌握虚拟内存的相关技术,包括页面置换算法、内存分配策略等,并分析其对系统性能的影响。
二、实验环境操作系统:Windows 10 专业版开发工具:Visual Studio 2019编程语言:C++三、实验原理1、虚拟内存的概念虚拟内存是一种计算机系统内存管理技术,它使得应用程序认为自己拥有连续的可用内存(一个连续完整的地址空间),而实际上,这些内存可能是被分散存储在物理内存和外部存储设备(如硬盘)中的。
虚拟内存通过将程序使用的内存地址映射到物理内存地址,实现了内存的按需分配和管理。
2、页面置换算法当物理内存不足时,操作系统需要选择一些页面(内存中的固定大小的块)换出到外部存储设备,以腾出空间给新的页面。
常见的页面置换算法有先进先出(FIFO)算法、最近最少使用(LRU)算法、时钟(Clock)算法等。
3、内存分配策略操作系统在分配内存时,需要考虑如何有效地利用有限的物理内存资源。
常见的内存分配策略有连续分配、分页分配和分段分配等。
四、实验内容与步骤1、实现简单的虚拟内存系统使用 C++编写一个简单的虚拟内存模拟程序,包括内存页面的管理、地址映射、页面置换等功能。
2、测试不同的页面置换算法在虚拟内存系统中,分别实现 FIFO、LRU 和 Clock 算法,并对相同的访问序列进行测试,比较它们的页面置换次数和缺页率。
3、分析内存分配策略的影响分别采用连续分配、分页分配和分段分配策略,对不同大小和类型的程序进行内存分配,观察系统的性能(如内存利用率、执行时间等)。
具体步骤如下:(1)定义内存页面的结构,包括页面号、标志位(是否在内存中、是否被修改等)等。
(2)实现地址映射函数,将虚拟地址转换为物理地址。
(3)编写页面置换算法的函数,根据不同的算法选择要置换的页面。
(4)创建测试用例,生成随机的访问序列,对不同的算法和分配策略进行测试。
一、实训背景随着计算机技术的发展,计算机系统的内存容量需求越来越大。
然而,由于物理内存(RAM)的成本较高,且受限于物理空间的限制,很难满足用户对大内存的需求。
为了解决这个问题,虚拟内存技术应运而生。
虚拟内存是一种将部分硬盘空间虚拟化为内存的技术,可以有效扩充计算机系统的内存容量,提高系统的运行效率。
本实训旨在设计并实现一个虚拟内存系统,通过对虚拟内存的设计、实现和测试,加深对虚拟内存原理和技术的理解。
二、实训目标1. 理解虚拟内存的基本原理和设计方法;2. 掌握虚拟内存的硬件和软件实现技术;3. 设计并实现一个简单的虚拟内存系统;4. 对虚拟内存系统进行测试和分析,评估其性能。
三、实训内容1. 虚拟内存基本原理虚拟内存的核心思想是将计算机的物理内存与硬盘空间进行映射,使得计算机在访问内存时,可以将部分数据存储到硬盘上,从而实现内存的扩充。
虚拟内存的主要技术包括:(1)页式存储管理:将内存划分为固定大小的页,硬盘空间也划分为同样大小的块(或称为页框)。
当程序需要访问内存时,虚拟内存管理系统会将所需的页加载到物理内存中。
(2)置换算法:当物理内存不足时,虚拟内存管理系统需要选择一部分页从内存中移出,并将它们存储到硬盘上。
常用的置换算法有FIFO、LRU、OPT等。
(3)地址映射:虚拟内存管理系统需要将虚拟地址转换为物理地址,以便计算机可以访问到正确的内存位置。
2. 虚拟内存硬件实现虚拟内存的硬件实现主要包括以下部分:(1)内存控制器:负责控制物理内存的读写操作。
(2)地址转换逻辑:将虚拟地址转换为物理地址。
(3)页面缓存:用于缓存频繁访问的页,以提高系统性能。
3. 虚拟内存软件实现虚拟内存的软件实现主要包括以下部分:(1)虚拟内存管理系统:负责管理虚拟内存的分配、回收和页面置换等操作。
(2)页面置换算法实现:根据不同的置换算法实现相应的页面置换逻辑。
(3)地址映射表:用于存储虚拟地址与物理地址的映射关系。
2011年操作系统大作业1.虚拟内存管理实验。
在Linux环境下编写一个内核模块,分别实现如下几个函数:●static void mtest_dump_vma_list(void):依次列出当前进程所占用的虚拟内存空间各段的读、写或执行权限。
●static void mtest_find_vma(unsigned long addr):查找出虚拟地址addr所在的vma,并通过printk打印该段的起始地址、终止地址和段标志等信息。
●static void mtest_find_page(unsigned long addr):找到虚拟地址addr对应的物理地址并打印。
为了测试和使用以上函数,需要在内核模块的初始化函数中创建一个名为mtest的/proc 文件。
mtest文件绑定的写函数mtest_write允许用户程序写入一串字符串:●如果写入的字符串是listvma则调用函数mtest_dump_vma_list(void);●如果写入的字符串是findvma0xffffffff则调用函数mtest_find_vma(0xffffffff),字符串的后几个字符是传递给函数的参数;●如果写入的字符串是findpage0xffffffff则调用函数mtest_find_page(0xffffffff),同样字符串的后几个字符是参数。
实验要求:为了测试以上模块的正确性,需要编写一个小型的test应用程序,它打开/proc/mtest文件,并向其中写入字符串调用模块中的相关函数并给出相应的反馈信息。
知识储备:●虚拟存储空间管理的相关数据结构vm_area_struct和mm_struct●/proc文件系统的相关知识●内核模块的相关知识实验思路及过程:相关知识储备:1.可以使用/proc文件系统和pmap工具查看给定进程的内存空间和其中所包含的内存区域mmap描述的该地址空间中的全部内存区域。
内核使用内存描述符结构表示进程的地址空间,由结构体mm_struct结构体表示,定义在linux/sched.h中,同时linux操作系统采用虚拟内存技术,所有进程之间以虚拟方式共享内存。
一、实训目的1. 通过本次实训,加深对存储管理方案的理解,掌握虚拟存储器的管理方式,熟悉虚存管理的各种页面淘汰算法。
2. 通过编写和调试地址转换过程的模拟程序,加强对地址转换过程的理解。
3. 培养编程能力和问题解决能力,提高实际操作水平。
二、实训环境1. 操作系统:Windows 102. 编程语言:C++3. 开发环境:Visual Studio 20194. 硬件配置:CPU:Intel Core i5,内存:8GB,硬盘:256GB SSD三、实训原理1. 虚拟存储器:虚拟存储器是一种将内存与外存相结合的存储管理技术,可以扩大程序可访问的存储空间。
2. 页面置换算法:页面置换算法是虚拟存储器中的一种内存管理技术,用于确定在内存中保留哪些页面,淘汰哪些页面。
3. 地址转换过程:地址转换过程是将逻辑地址转换为物理地址的过程。
四、实训内容1. 设计一个请求页式存储管理方案,并编写模拟程序实现。
2. 产生一个需要访问的指令地址流,其中50%的指令是顺序执行的,25%的指令均匀地散布在前地址部分,25%的地址是均匀地散布在后地址部分。
3. 指定内存页表的最大长度,并对页表进行初始化。
4. 每访问一个地址时,计算该地址所在的页的页号,然后查页表,判断该页是否在主存。
5. 如果该页已在主存,则打印页表情况;如果该页不在主存,则采用FIFO页面淘汰算法淘汰一页,并将该页在页表中抹去。
6. 编写代码实现上述功能,并进行测试。
五、实训过程1. 确定虚拟存储器的大小、内存大小、页面大小和页面置换算法。
2. 设计数据结构存储页面信息,包括页号、是否在内存中、是否被修改等。
3. 编写函数实现地址转换过程,包括计算页号、判断页是否在内存中等。
4. 编写FIFO页面淘汰算法,淘汰不在内存中的页面。
5. 编写测试程序,生成指令地址流,并调用相关函数进行测试。
六、实训结果1. 成功实现了请求页式存储管理方案,并编写了相应的模拟程序。
虚拟存储管理实验报告实验概述虚拟存储管理实验是操作系统课程中的一项重要实验,旨在通过模拟内存管理中的分页机制和页面置换算法,深入理解操作系统中的虚拟内存管理技术。
本实验主要包括以下几个关键点:- 模拟内存的分页机制- 实现页面置换算法- 分析不同页面置换算法的性能指标实验环境本次实验基于C语言和Linux操作系统进行实现,使用gcc编译器进行编译和调试。
实验过程及实现细节在本次实验中,我们实现了一个简单的虚拟内存系统,主要包括以下几个模块:页面管理、页面分配、页面置换和性能分析。
下面对每个模块的实现细节进行详细描述。
页面管理页面管理模块主要负责管理虚拟内存和物理内存之间的映射关系。
我们采用了分页机制进行管理,将虚拟内存和物理内存划分为固定大小的页面。
页面的大小由实验设置为4KB。
页面分配页面分配模块负责分配物理内存空间给进程使用。
我们使用一个位图作为物理内存管理的数据结构,记录每个页面的使用情况。
在每次页面分配时,我们会查找位图中第一个空闲的页面,并将其分配给进程。
页面置换页面置换模块是虚拟存储管理中的核心算法,主要用于解决内存中页面不足时的页面置换问题。
本次实验中我们实现了两种常用的页面置换算法:FIFO(先进先出)和LRU(最近最少使用)算法。
FIFO算法是一种简单的页面置换算法,它总是选择最早被加载到物理内存的页面进行置换。
LRU算法是一种基于页面访问历史的算法,它总是选择最长时间未被访问的页面进行置换。
性能分析性能分析模块主要用于评估不同的页面置换算法的性能指标。
我们使用了缺页率(Page Fault Rate)和命中率(Hit Rate)作为评价指标。
缺页率表示物理内存中的页面不能满足进程请求的比例,命中率表示进程请求的页面已经在物理内存中的比例。
实验结果为了评估不同的页面置换算法的性能,在实验过程中,我们通过模拟进程的页面访问序列,统计页面置换次数、缺页率和命中率等指标。
以一个包含100个页面访问请求的序列为例,我们分别使用FIFO算法和LRU 算法进行页面置换。
虚拟内存管理实习报告目录内容一:总体概述 (3)内容二:任务完成情况 (3)任务完成列表(Y/N) (3)具体Exercise的完成情况 (3)内容三:遇到的困难以及解决方法 (11)内容四:收获及感想 (11)内容五:对课程的意见和建议 (11)内容六:参考文献 (11)内容一:总体概述本次lab主要是针对操作系统内存管理的学习,内存管理主要有固定分区、可变分区、页式和段式管理。
现代操作系统主要采用页式内存管理,它把用户程序地址空间划分成大小相等的部分,称为页。
内存空间按页的大小划分为大小相等的区域,称为内存块(物理页面,页框,页帧)。
以页为单位进行分配,逻辑上相邻的页,物理上不一定相邻。
虚拟内存的基本思想:每个程序拥有自己的地址空间,这个空间被分割成多个块,每一块称作一页或者页面,每一页有连续的地址范围。
这些页被映射到物理内存,但并不是所有页都必须在内存中才能运行。
当程序引用到一部分在物理内存中的地址空间时,由硬件立即执行必要的映射。
当程序引导到一部分不在物理内存中德的地址空间时,由操作系统负责将缺失的部分装入屋里内存并重新执行失效的指令。
内容二:任务完成情况任务完成列表(Y/N)Exercise1 Exercise2 Exercise3 Exercise4 Exercise5 Exercise6 Exercise7 Challange 完成情况Y Y Y Y Y Y N N具体Exercise的完成情况一、TLB异常处理目前,Nachos系统对于内存的管理是基于软件模拟的TLB机制。
其工作原理、异常处理、替换算法等方面,与分页式内存管理非常相像。
Exercise 1 源代码阅读Ø阅读code/userprog/,着重理解nachos执行用户程序的过程,以及该过程中与内存管理相关的要点。
Ø阅读code/machine目录下的machine.h(cc),translate.h(cc)文件和code/userprog目录下的exception.h(cc),理解当前Nachos系统所采用的TLB机制和地址转换机制。
操作系统虚拟内存调优实验报告摘要:本实验通过对操作系统中虚拟内存的调优进行研究,旨在优化内存管理策略,提高系统性能。
实验采用了xxx方法,通过对不同参数的调节和对比分析,得出了一系列实验结果。
实验结果表明,在xxx场景下,调整虚拟内存的配置可以显著改善系统性能,从而提高用户体验。
1. 引言在当今多任务操作系统中,虚拟内存是一种重要的内存管理技术。
它允许系统在有限的物理内存资源下运行更多的应用程序,有效提高了系统的利用率。
然而,在虚拟内存的设计和配置上存在一定的挑战,因此本实验旨在通过调优虚拟内存的配置,进一步提升系统性能。
2. 实验环境本实验使用了xxx虚拟机软件,搭建了xxx操作系统环境。
实验过程中,我们采用了xxx指标来评估系统的性能,并通过对比分析得出结论。
3. 实验设计3.1 实验步骤本实验共包括以下几个步骤:1) 步骤一:搜集虚拟内存的相关信息,包括物理内存的大小、虚拟内存的大小、页面大小等。
2) 步骤二:根据实验需要,选择合适的测试场景和工作负载。
3) 步骤三:记录系统的初始性能数据,作为比较的基准。
4) 步骤四:根据实验需求,调整虚拟内存的相关参数。
5) 步骤五:运行相同的测试场景和工作负载,并记录性能数据。
6) 步骤六:对比初始性能数据和调优后的性能数据,分析调优效果。
3.2 实验指标本实验主要评估以下指标:1) 指标一:系统的响应时间。
2) 指标二:系统的吞吐量。
3) 指标三:页面错误率。
4) 指标四:页面置换算法的效果。
4. 实验结果与分析4.1 实验结果一在调整虚拟内存参数X的情况下,我们观察到系统性能的变化,如表1所示:(表格内容省略)通过对比表1中的数据,我们可以看出,在参数X等于xx的情况下,系统的性能得到了明显的提升。
具体而言,系统的响应时间减少了xx%,吞吐量增加了xx%。
4.2 实验结果二除了参数X,我们还对参数Y进行了调优。
实验结果如表2所示:(表格内容省略)根据表2中的数据分析,我们可以发现,在参数Y等于xx的情况下,系统的性能得到了进一步的改善。
实习五虚拟存储器一、实习内容模拟分页式虚拟存储管理中硬件的地址转换和缺页中断,以及选择页面调度算法处理缺页中断。
二、实习目的在计算机系统中,为了提高主存利用率,往往把辅助存储器(如磁盘)作为主存储器的扩充,使多道运行的作业的全部逻辑地址空间总和可以超出主存的绝对地址空间。
用这种办法扩充的主存储器称为虚拟存储器。
通过本实习帮助同学理解在分页式存储管理中怎样实现虚拟存储器。
三、实习题目本实习有三个题,其中第一题必做,第二、第三题中可任选一个。
第一题:模拟分页式存储管理中硬件的地址转换和产生缺页中断。
[提示]:(1) 分页式虚拟存储系统是把作业信息的副本存放在磁盘上,当作业被选中时,可把作业的开始几页先装入主存且启动执行。
为此,在为作业建立页表时,应说明哪些页已在主存,哪些页尚未装入主存,页表的格式为:其中,标志——用来表示对应页是否已经装入主存,标志位=1,则表示该页已经在主存,标志位=0,则表示该页尚未装入主存。
主存块号——用来表示已经装入主存的页所占的块号。
在磁盘上的位置——用来指出作业副本的每一页被存放在磁盘上的位置。
(2) 作业执行时,指令中的逻辑地址指出了参加运算的操作数存放的页号和单元号,硬件的地址转换机构按页号查页表,若该页对应标志为“1”,则表示该页已在主存,这时根据关系式:绝对地址=块号 块长+单元号计算出欲访问的主存单元地址。
如果块长为2的幂次,则可把块号作为高地址部分,把单元号作为低地址部分,两者拼接而成绝对地址。
按计算出的绝对地址可以取到操作数,完成一条指令的执行。
若访问的页对应标志为“0”,则表示该页不在主存,这时硬件发“缺页中断”信号,由操作系统按该页在磁盘上的位置,把该页信息从磁盘读出装入主存后再重新执行这条指令。
(3) 设计一个“地址转换”程序来模拟硬件的地址转换工作。
当访问的页在主存时,则形成绝对地址,但不去模拟指令的执行,而用输出转换后的地址来代替一条指令的执行。
北京邮电大学软件学院2019-2020学年第1学期实验报告课程名称:操作系统实验名称:虚拟存储器管理实验完成人:日期:2019 年12 月21 日一、实验目的(说明通过本实验希望达到的目的)1. 了解虚拟存储技术的特点;2. 掌握请求页式管理的页面置换算法。
二、实验内容(说明本实验的内容)1. 通过随机数产生一个指令序列,共320 条指令。
其地址按下述原则生成:(1)50%的指令是顺序执行的;(2)50%的指令是均匀分布在前地址部分;(3)50%的指令是均匀分布在后地址部分;具体的实施方法是:A. 在[0,319]的指令地址之间随机选取一起点M;B. 顺序执行一条指令,即执行地址为M+1 的指令;C. 在前地址[0,M+1]中随机选取一条指令并执行,该指令的地址为M’;D. 顺序执行一条指令,其地址为M’+1;E. 在后地址[M’+2,319]中随机选取一条指令并执行;F. 重复A—E,直到执行320 次指令。
2. 指令序列变换成页地址流设:(1)页面大小为1K;(2)用户内存容量为4 页到32 页;(3)用户虚存容量为32K。
在用户虚存中,按每K 存放10 条指令排列虚存地址,即320 条指令在虚存中的存放方式为:第0 条—第9 条指令为第0 页(对应虚存地址为[0,9]);第10 条—第19 条指令为第1 页(对应虚存地址为[10,19]);……………………第310 条—第319 条指令为第31 页(对应虚存地址为[310,319]);按以上方式,用户指令可组成32 页。
3. 计算并输出下述各种算法在不同内存容量下的命中率。
A. 先进先出(FIFO)页面置换算法B. 最近最久未使用(LRU)页面置换算法--最近最少使用算法C. 最少使用(LFR)页面置换算法D. 最佳(Optimal)页面置换算法三、实验环境(说明本实验需要的环境)Vscode+ubuntun四、实验过程描述本实验需要分几个步骤完成。
操作系统管理-虚拟存储器-实验报告-代码7页一、实验目的学习操作系统中虚拟存储器的概念,掌握虚拟存储器的实现思路和方式。
二、实验要求在C语言环境下,实现基于分页机制的虚拟存储和页表管理。
三、实验内容1.实现一个虚拟存储器,其中分页大小为4KB,虚拟地址空间大小为4GB(每个进程可以使用的虚拟地址空间)。
物理内存大小为512MB,即实际内存中有128个物理页面。
2.实现页表管理,将虚拟地址映射到物理地址。
3.实现页面替换算法,当物理内存不足时,需要将某些页面从内存中置换出来。
4.实现程序的运行,能够根据页面缺失率输出性能参数。
四、实验步骤1.确定程序设计思路和数据结构。
2.实现虚拟存储器和页表管理。
3.实现页面替换算法。
五、实验代码及解析对于程序设计思路,首先需要确定虚拟存储器和物理内存的大小,以及页面大小。
虚拟存储器大小默认为4GB,物理内存大小为512MB,页面大小为4KB。
其次,需要设计页表数据结构。
页表可以使用一个二维数组表示,其中第一维表示页表项,第二维表示页内地址。
页表项有四个字段,分别为标志位(是否在内存中)、页框号(页面所在的物理页框号)、保护(页面的读写权限)、计数(页面使用情况的计数器)。
第三,需要设计页面替换算法。
本程序采用最近最少使用算法(LRU)作为页面替换算法,当物理内存不足时,选择使用最近最少使用的页面进行替换。
#define PAGE_SIZE 4096 // 页面大小#define VIRTUAL_MEM_SIZE 4 * 1024 * 1024 * 1024 // 虚拟存储器大小#define PHYSICAL_MEM_SIZE 512 * 1024 * 1024 // 物理内存大小#define PAGE_NUM (VIRTUAL_MEM_SIZE / PAGE_SIZE) // 页面总数#define PHYSICAL_PAGE_NUM (PHYSICAL_MEM_SIZE / PAGE_SIZE) // 物理页面数struct page_table_entry {int present; // 是否在内存中(1为在,0为不在)int page_frame; // 页面所在的物理页框号int protect; // 页面的读写权限int count; // 页面使用情况的计数器}struct page_table_entry page_table[PAGE_NUM][PAGE_SIZE]; // 页表虚拟存储器和页表管理需要掌握的是页表的相关数据结构,还有一个重要的点,就是如何将虚拟地址映射到物理地址。
虚拟内存管理实习报告姓名李炜学号**********日期4月10日目录内容一:总体概述 (3)内容二:任务完成情况 (3)任务完成列表(Y/N) (3)具体Exercise的完成情况 (3)内容三:遇到的困难以及解决方法 (9)内容四:收获及感想 (9)内容五:对课程的意见和建议 (9)内容六:参考文献 (10)内容一:总体概述这次实习主要是加入对tlb和虚拟内存的进一步支持,并且实验一下在原理课上学到过的各种替换策略,tlb是为了加速从虚拟地址到物理地址的翻译过程,而虚拟内存更是肩负着提供比实际物理内存更大的虚拟内存的重任,有了虚拟内存,才可以运行比实际内存更大的程序。
内容二:任务完成情况任务完成列表(Y/N)具体Exercise的完成情况TLB异常处理部分:Exercise 1:这个文件中和本次实习相关的主要是StartProcess这个函数,在这个函数中,首先打开一个文件,判断这个文件是否是可执行文件,如果是的话,为这个文件开辟一块地址空间来运行一个新线程,之后初始化和这个线程相关的寄存器,初始化完成之后运行这个程序。
其中在开辟新的地址空间的时候,为这个地址空间中的page table的每一项进行了初始化。
所以在后面对translationEntry增加内容的时候,最好还是在这个初始化过程中加入相应的初始化操作。
在构造可执行文件的空间时,首先读入这个文件的开始部分,即noffH,这个部分包含了文件的magic number(表示是否是可执行文件),文件中代码,数据,栈等各部分的位置、大小等。
之后根据这个大小,按照页大小分配内存页数量,初始化page table,将可执行文件的代码段和数据段按照虚存与内存一一对应的方式读入内存中。
(h)在这个文件中,主要是针对虚拟机整体的操作,其中在构造函数中,首先初始化了寄存器和内存,这个部分和本次实习没有关系,下面初始化了tlb中的项。
开始的时候,我认为对于每个地址空间都应该有自己的tlb,每次切换线(进)程的时候都要同时切换tlb内容,这个方案在nachos这样的虚拟机上实际上时可以实现的,而且tlb的miss可能会比只有一个tlb 要少很多,但是这种情况不符合计算机系统的实际情况,因为对于实际的计算机体系结构来说,tlb是一个硬件不见,每个cpu的核心应该具备一个tlb,因为多超标量等优化机制的存在,线程切换十分频繁,如果每次都要同时按照线程切换tlb,那样代价太大了,tlb本身是用来利用局部性来减少对page table的访问的,如果频繁改变tlb内容开销上太大,得不偿失。
在这个文件中,与本次实习相关的还有raiseexception这个函数,这个函数其实就是针对不同的异常调用相应的处理函数的地方,在处理异常之前要先使得系统进入系统模式运行(之前在用户模式下)。
(h)这个文件在这次实习中具有十分重要的作用,readMem和writeMem分别是从内存中读和写的函数,它们都需要首先进行虚拟地址到物理地址的转换,如果转换成功则继续读写操作,否则会对因为转换产生的异常进行处理。
在translate函数中,首先检查想要读取的内存地址是不是对齐的,之后根据虚拟地址算出相应的虚拟页号和页内偏移(需要转换的其实只是虚拟页号到物理页号,页内偏移在虚拟页中和在物理页中都是相同的)。
因为nachos本身只支持tlb或者page table中的一个,所以如果是page table模式的话,那么就在page table中直接取出vpn对应的项,并且取出物理页号,当然其间也要进行有效性检查,如果所需要的物理页是无效的,就会引发page fault异常。
如果使用的是tlb模式,则在tlb中遍历查找想要读取的vpn,如果找不到,同样会引发page fault异常。
之后的操作就是读出这个物理页的具体地址以及一些其它的检查操作。
对于这个文件来说,只有一个Exceptionhandler函数,用来判断异常的类型和相应的处理方式并且处理异常,对于本次实习来说,其实就是加一个else if判断pagefaultexception异常并处理这个tlb miss。
Exercise 2:从ExceptionHandler中可以看到对于系统调用的处理方法,就是输出调试信息,并且停止用户进程,对于TLB miss来说,开始的时候我仍然使用了PageFaultException,因为在translate 文件中如果出现tlb miss会返回PageFaultException,也就是说在handler中首先判断产生的是PageFaultException,判断完之后,我感到很茫然,因为除了需要知道是何种异常外,还必须知道引发这个寻址异常的具体地址是什么,这样才能从page table中调入这个页,去哪里得知这个信息呢?重新去看translate中的读写内存的两个函数,可以看到translate函数返回异常,那么就会调用RaiseException这个函数,而我们可以看到引发异常的那个地址也被当做参数传了进去,在这个函数中,和这个我们需要的地址有关的就是把这个地址写到了一个寄存器中,因为寄存器是machine中的属性,也就是说不管是用户进程还是系统进程都共享相同的寄存器,这样我们就知道可以在exception handler中通过读取寄存器信息来得到那个引发异常的地址了。
那么是哪个寄存器呢?从raiseException中可以看到是BadVAddrReg,这个是一个宏,对应着39号寄存器。
这样,在ExceptionHandler中,我首先通过machine的读取寄存器的方法读出BadVAddrReg寄存器中的内容,有了这个地址就可以开始具体的替换过程了,对于替换的方法,我首先实验了通过hit次数多少来决定去除哪一个entry的方法,因为其中许多操作都涉及machine中的信息,所以我把这个处理函数放在了machine中,这个函数接受地址作为参数,学习translate中的方法,首先通过address计算获得vpn和offset,其实后来发现offset用处不大,只是在输出哪个物理地址时有帮助,有了vpn也就知道了哪个页要被换进,问题就是要找到一个tlb项来换出,对于这个目标来说,也很简单,只要通过遍历tlb表项,找到hit最小的一项,如果有valid为false的项,那么可以直接把这个项作为应该被换出的项即可,之后把这个tlb项写回到page table中,并且把vpn号page table中的项调入这个应该被换出的项所在的位置。
之后还需要做些tlb项的初始化工作,把这个项的hit置为1(如果置成0的话可能会造成震荡,这一点是我在调试程序的时候,发现的),valid置为TRUE,为了看哪个地址引发了异常,我还让它输出了对应的物理地址。
当然还要维护这个hit值,也就是说,在translate中每次tlb项被找到,就使相应的hit值加一。
但是再后来的测试阶段我发现matmult这个算矩阵乘法的程序会产生真正的pagefault(内存不足),这样就有必要区分tlb miss和page fault了,于是我在machine.h中定义了新的异常类型叫TLBMissException,并且在exceptionHandler中添加了对这种类型的处理。
Exercise 3:已经有了上一个exercise的基础,其实这个exercise也就不难了,我首先选择了使用aging 算法(因为体系大作业曾经实现过,觉得不难),我通过定义宏GROWOLD使得tlb项的age 右移一位,通过REFEREDTO使得age右移一位并且首位或上1,每次tlb项被使用时,就对它REFEREDTO,而在Exceptionhandler中如果不是要找的项,就先对它GROWOLD,这样较近时间被使用的tlb项就不会很快被换出(找的时候直接找age最小的就可以)。
说起来比较简单,但是实际编写的过程中,发现在sort这个程序的测试中出现了震荡现象,经过仔细检查发现是因为age在translationEntry中被我定义为了int,但是实际上必须被定义成unsigned int,在找age最小的时候也需要使用unsigned int类型。
之后听同学说lru实现起来比较简单,只需要通过stats->totalTick就可以知道最近被访问的时间了,于是我在之前应该REFEREDTO的地方把lastUsedTime赋成stats->totalTick,比较的时候同样找lastUsedTime最小的项。
由于实现起来差不多,所以就不多说了。
测试的时候我主要跑了halt,sort,matmult三个程序,halt是用来验证pageTable中的项可以被换入的正确性的,对性能比较上基本没有意义。
而在测试sort时,aging算法和lru竟然产生了相同的miss次数,在tlb最多为8的时候,内存为1024页的时候,都产生了8678次miss,改变一些参数仍然相同,于是我只好继续通过matmult来测试。
但是matmult在测试时会产生很大的问题,tlb中竟然出现了多次相同的项且valid都是1,我查了很长时间程序都不知道哪里错了,后来看matmult程序本身,发现注释说这个程序会造成内存溢出,于是我明白了,因为开始的时候我没有区别tlb miss和page fault,所以其实是引发了真正的page fault,之后像之前说的,我首先扩大了内存页数从128变到1024,之后区别page fault 和tlb miss,这样之后测试aging和lru的miss次数,结果令我大跌眼睛,aging miss发生了8647次,而lru却只发生了5722次,原本一位aging会更高级的,结果却是原理更加简单的lru的miss次数更少。
分页式内存管理部分:Exercise 4:由于nachos本身提供了bitmap这个很好的数据结构,所以我就直接使用bitmap来指示内存页的使用情况了,因为一个机器只能有一个内存,所以我把bitmap直接放到了 中作为全局的数据结构称为memoryBitMap,并且在原来的if user_program中加入创建bitmap的new 操作。
这样之后,就需要维护这个位图,也就是在addrspace中的初始化pagetable的时候,把原本是一一对应的虚存与物理内存的映射关系,改变成每次到bitmap 中寻找空闲的页(bitmap中提供了find操作,可以直接做到,而且找到以后就已经标记了)。
也就是说,在原来physical page直接赋成i的地方改成memoryBitMap->find就可以了。