操作系统实验报告虚拟内存.docx

上传人:b****4 文档编号:6614537 上传时间:2023-05-10 格式:DOCX 页数:29 大小:273.44KB
下载 相关 举报
操作系统实验报告虚拟内存.docx_第1页
第1页 / 共29页
操作系统实验报告虚拟内存.docx_第2页
第2页 / 共29页
操作系统实验报告虚拟内存.docx_第3页
第3页 / 共29页
操作系统实验报告虚拟内存.docx_第4页
第4页 / 共29页
操作系统实验报告虚拟内存.docx_第5页
第5页 / 共29页
操作系统实验报告虚拟内存.docx_第6页
第6页 / 共29页
操作系统实验报告虚拟内存.docx_第7页
第7页 / 共29页
操作系统实验报告虚拟内存.docx_第8页
第8页 / 共29页
操作系统实验报告虚拟内存.docx_第9页
第9页 / 共29页
操作系统实验报告虚拟内存.docx_第10页
第10页 / 共29页
操作系统实验报告虚拟内存.docx_第11页
第11页 / 共29页
操作系统实验报告虚拟内存.docx_第12页
第12页 / 共29页
操作系统实验报告虚拟内存.docx_第13页
第13页 / 共29页
操作系统实验报告虚拟内存.docx_第14页
第14页 / 共29页
操作系统实验报告虚拟内存.docx_第15页
第15页 / 共29页
操作系统实验报告虚拟内存.docx_第16页
第16页 / 共29页
操作系统实验报告虚拟内存.docx_第17页
第17页 / 共29页
操作系统实验报告虚拟内存.docx_第18页
第18页 / 共29页
操作系统实验报告虚拟内存.docx_第19页
第19页 / 共29页
操作系统实验报告虚拟内存.docx_第20页
第20页 / 共29页
亲,该文档总共29页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

操作系统实验报告虚拟内存.docx

《操作系统实验报告虚拟内存.docx》由会员分享,可在线阅读,更多相关《操作系统实验报告虚拟内存.docx(29页珍藏版)》请在冰点文库上搜索。

操作系统实验报告虚拟内存.docx

操作系统实验报告虚拟内存

北京邮电大学软件学院

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

四、实验过程描述

本实验需要分几个步骤完成。

本实验所定义的数据结构:

#define I_NUM 320

#define CONST 1000

//页表

typedef struct pagetable {

  int p_num;    //页号

   int access_time[32];//记录访问的时间

  bool status[32];//状态位(是否写入内存) 写入1 未写入0

  int m_num[32];//存入的内存块号

}PageTable;

//队列的结构

typedef struct {

  int count;    //计数

  int front;    //头指针

  int rear;     //尾指针

  int *data;    //数据域

  int size;     //大小

} CirQueue;

int ins[I_NUM];       //指令数组

int visit_times[32]; //每一个页面访问次数的数组

步骤一:

按要求产生指令序列。

这部分按照指导书上做就ok了。

具体实现:

void initIns()

{

    for (int i = 0; i < I_NUM; i += 4)

    {

        int m = rand() % I_NUM; //0到319的随机数

        ins[i] = (m + 1) % I_NUM;  //执行地址为m+1的指令

        int m1 = rand() % (m + 2); //随机选取一条指令并执行

        ins[i + 1] = m1;

        ins[i + 2] = (m1 + 1) % I_NUM; //执行地址为m1+1的指令

        ins[i + 3] = rand() % (I_NUM - m1 - 2) + m1 + 2;

    }

}

 

步骤二:

指令序列变换成页地址流

只需将指令所在的位置整除10即可得到页号。

步骤三:

实现各种算法

首先是FIFO算法。

相关原理:

该算法总是淘汰最新进入内存的页面,即选择在内存中驻留时间最久的页面予

以淘汰。

该算法实现简单,只需把一个进程已调入内存的页面,按先后次序链接成一个队列,并设置一个指针,称为替换指针,使它总是指向最老的页面。

思路:

先检查内存是否还有空间,如果还有则直接插入,否则调用此算法,将先出队再入队来完成页面置换。

实现:

void FIFO(int f_num, PageTable *pagetable)

{

    int p_fault = 0;

    CirQueue *queue = (CirQueue *)malloc(sizeof(CirQueue));

    initPage(pagetable, f_num);

    initQueue(queue, f_num);

    int i;

    for (int i_num = 0; i_num < 320; i_num++)

    {

        if (!

isHitted(f_num, i_num, pagetable)) //没命中

        {

            p_fault++; //页表内没有查询到当前指令所属的页

            for (i = 0; i < pagetable->p_num; i++)

            {

                if (pagetable->status[i] == 0)

                

                    break;

                

            }

            if (i < pagetable->p_num) //内存未满 让新的页进来

            {

                pagetable->status[i] = true;

                pagetable->m_num[i] = ins[i_num] / 10;

                Enqueue(queue, (ins[i_num] / 10)); //同时 此页进队

            }

            else //内存已满 开始置换

            {

                int last_page = Dequeue(queue); //页号

                for (i = 0; i < pagetable->p_num; i++)

                {

                    if (pagetable->m_num[i] == last_page)

                        break;

                }

                pagetable->m_num[i] = ins[i_num] / 10;

                Enqueue(queue, (ins[i_num] / 10)); //新的页号进队

            }

        }

    }

    double p_fault_r = (double)p_fault / I_NUM;

    printf("%f\t", 1 - p_fault_r);

}

 

其次是LRU算法。

相关原理:

最近最久未使用(LRU)页面置换算法,是根据页面调入内存后的使用情况进行决策的。

由于无法预测各页面将来的使用情况,只能利用“最近的过去”作为“最近的将来”的近似,因此,LRU置换算法是选择最近最久未使用的页面予以淘汰。

该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间t,当需淘汰一个页面时,选择现有页面中其t值最大的,即最近最久未使用的页面予以淘汰。

思路:

同样先判断内存是否为满。

如果未满则直接插入,否则调用该算法。

该算法需要一个记录访问时间的数组access_time[],当需要置换时,选择数组中元素最大的元素,将其置换出去,然后将新页面放进来。

每次访问时将未访问的页面的access_time加一。

实现:

//lru算法

void LRU(int f_num, PageTable *pagetable)

{

    int p_fault = 0;

    initPage(pagetable, f_num);

    int k;

    for (int i_num = 0; i_num < I_NUM; i_num++)

    {

        if (!

isHitted(f_num, i_num, pagetable)) //没命中

        {

            p_fault++;

            //页表内没有查询到当前指令所属的页

            for (k = 0; k < pagetable->p_num; k++)

            {

                if (pagetable->status[k] == false)

                {

                    break;

                }

            }

            if (k < pagetable->p_num)

            {

                //内存未满 让新的页进来

                pagetable->status[k] = true;

                pagetable->m_num[k] = ins[i_num] / 10;

                //所有页的访问次数自增

                incTime(pagetable, f_num);

            }

            else

            {

                //内存已满 开始置换

                int index = LeastUsed(pagetable, f_num);

                pagetable->access_time[index] = 0;

                pagetable->m_num[index] = ins[i_num] / 10;

                //所有页的访问时间自增

                incTime(pagetable, f_num);

            }

        }

    }

    double p_fault_r = (double)p_fault / I_NUM;

    printf("%f\t", 1 - p_fault_r);

}

void incTime(PageTable *pagetable, int f_num)

{

    for (int i = 0; i < f_num; i++)

    {

        if (pagetable->status[i] == true)

            pagetable->access_time[i]++;

    }

}

int LeastUsed(PageTable *pagetable, int f_num) //选择现有页面中其 t 值最大的,即用的最少的页

{

    int k = pagetable->access_time[0];

    int max = 0;

    for (int i = 0; i < f_num; i++)

    {

        if (pagetable->access_time[i] > k)

        {

            k = pagetable->access_time[i];

            max = i;

        }

    }

    return max;

}

 

然后是LFR算法。

相关原理:

在采用该算法时,应为在内存中的每个页面设置一个移位寄存器,用来记录页面被访问的频率。

该置换算法选择在最近使其使用最少的页面作为淘汰页。

思路:

需要一个数组visit_times[]来记录每个页面访问的次数,即为频率。

同样先判断内存是否为满。

如果未满则直接插入,否则调用该算法。

选择频率最低的页面,将其置换出去,然后将新页面放进来。

实现:

//lfr算法

void LFR(int f_num, PageTable *pagetable)

{

    int p_fault = 0;

    initPage(pagetable, f_num);

    int i;

    for (int i_num = 0; i_num < 320; i_num++)

    {

        if (!

isHitted(f_num, i_num, pagetable)) //没命中

        {

            p_fault++;

            //页表内没有查询到当前指令所属的页

            for (i = 0; i< pagetable->p_num; i++)

            {

                if (pagetable->status[i] == false)

                {

                    break;

                }

            }

            if (i < pagetable->p_num)   //内存未满 让新的页进来

            {

                pagetable->status[i] = true;

                pagetable->m_num[i] = ins[i_num] / 10;

                visit_times[ins[i_num] / 10]++;     //同时 所有页的访问次数自增

            }

            else

            {

                //内存已满 开始置换

                

                int min_index = 0;

                int min = CONST;

                for (int k = 0; k < 32; k++)

                {

                    if (pagetable->status[k] == true)   //寻找在内存中的被访问次数最少的页面换出

                        if (visit_times[k] < min)

                        {

                            min = visit_times[k];

                            min_index = k;

                        }

                }

                pagetable->m_num[min_index] = ins[i_num] / 10;

                visit_times[ins[i_num] / 10]++;

            }

        }

    }

    double p_fault_r = (double)p_fault / I_NUM;

    printf("%f\t", 1 - p_fault_r);

}

 

最后是OPT算法。

相关原理:

该算法选择的被淘汰页面,将是以后永远不使用的,或许是在最长(未来)时间内不再被访问的页面。

采用该算法,通常可保证获得最低的缺页率。

但由于人们目前

还无法预知一个进程在内存的若干个页面中,哪一个页面是未来最长时间

思路:

由于本模拟实验已经知道将来会有那些序列被放进内存,所以该算法可以实现。

同样先判断内存是否为满。

如果未满则直接插入,否则调用该算法。

该算法需要数组distance[]表示该页到未来最近一次的距离。

需要置换时,选择距离被使用的页面将其置换,然后将新页面置换进来。

实现:

void OPT(int f_num, PageTable *pagetable)

{

    int p_fault = 0;

    initPage(pagetable, f_num);

    int i;

    for (int i_num = 0; i_num < 320; i_num++)

    {

        if (!

isHitted(f_num, i_num, pagetable)) //没命中

        {

            p_fault++;

            //页表内没有查询到当前指令所属的页

            for (i = 0; i < pagetable->p_num; i++)

            {

                if (pagetable->status[i] == false)

                    break;

            }

            if (i < pagetable->p_num)

            {

                //内存未满 让新的页进来

                pagetable->status[i] = true;

                pagetable->m_num[i] = ins[i_num] / 10;

            }

            else

            {

                //内存已满 开始置换

                //检查当前内存里的页哪个最久会被使用

                int *distance = (int *)malloc(sizeof(int) * f_num); //暂存距离的数组

                //初始化

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

                {

                    distance[i] = CONST;

                }

                for (int l = 0; l < f_num; l++)

                {

                    i = pagetable->m_num[l];

                    for (int k = i_num; k < f_num; k++)

                    {

                        if (ins[k] == i)

                        {

                            distance[l] = k - l; 

                            break;

                        }

                    }

                }

                //找出之后最远被使用的

                i = distance[0];

                int max = 0;

                for (int j = 0; j < f_num; j++)

                {

                    if (distance[j] > i)

                    {

                        i = distance[j];

                        max = j;

                    }

                }

                pagetable->m_num[max] = ins[i_num] / 10;

            }

        }

    }

    double p_fault_r = (double)p_fault / I_NUM;

    printf("%f\t", 1 - p_fault_r);

}

五、实验结果

运行结果如下:

随着物理内存的增加,命中率逐渐上升。

4种算法的命中率差别不大。

六、附件

6.1附件1:

源代码

Vm.h

#include 

#include 

#include 

#define I_NUM 320

#define CONST 1000

//页表

typedef struct pagetable {

  int p_num;    //页号

   int access_time[32];//记录访问的时间

  bool status[32];//状态位(是否写入内存) 写入1 未写入0

  int m_num[32];//存入的内存块号

}PageTable;

//队列的结构

typedef struct {

  int count;    //计数

  int front;    //头指针

  int rear;     //尾指针

  int *data;    //数据域

  int size;     //大小

} CirQueue;

int ins[I_NUM];       //指令数组

int visit_times[32]; //每一个页面访问次数的数组

void initQueue(CirQueue* queue,int i);

bool isEmpty(CirQueue* queue);

bool 

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2