操作系统实验3

实验题目

1、实验目的

通过对页面、页表、地址转换和页面置换过程的模拟,加深对请求调页系统的原理和实现过程的理解。

2、实验内容

(1)假设每个页面中可存放10条指令,分配给一作业的内存块数为4。

(2)用C语言模拟一作业的执行过程。该作业共有320条指令,即它的地址空间为32页,目前它的所有页都还未调入内存。在模拟过程中,如果所访问的指令已经在内存中,则显示其物理地址,并转下一条指令。如果所访问的指令还未装入内存,则发生缺页,此时需记录缺页的次数,并将相应页调入内存。如果4个内存块中均已装入该作业,则需进行页面置换。最后显示其物理地址,并转下一条指令。在所有320条指令执行完毕后,请计算并显示作业运行过程中发生的缺页率。

(3)置换算法:请分别考虑OPT、FIFO和LRU算法。

(4)作业中指令的访问次序按下述原则生成:

•50%的指令是顺序执行的。

•25%的指令是均匀分布在前地址部分。

•25%的指令时均匀分布在后地址部分。

具体的实施办法是:

  • 在[0,319]之间随机选取一条起始执行指令,其序号为m;
  • 顺序执行下一条指令,即序号为m+1的指令;
  • 通过随机数,跳转到前地址部分[0,m-1]中的某条指令处,其序号为m1;
  • 顺序执行下一条指令,即序号为m1+1的指令;
  • 通过随机数,跳转到后地址部分[m1+2,319]中的某条指令处,其序号为m2;
  • 顺序执行下一条指令,即序号为m2+1的指令;

重复跳转到前地址部分、顺序执行、跳转到后地址部分、顺序执行的过程,直至执行320条指令

实验核心代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
using namespace std;

const int maxn = 320;     //序列个数
const int max = maxn +20;//数组大小
const int maxp = max/10; //最大页数

int inst[max];//指令序列
int page[max];//页地址流
int size;      //内存能容纳的页数

bool in[maxp];  //该页是否在内存里,提高效率
int pin[maxp];  //现在在内存里的页

void welcome()
{
    printf("******************************************\n");
    printf("**            操作系统模拟实验\t\t**\n");
    printf("**             页式存储管理\t\t**\n");
    printf("******************************************\n\n");
}

void input_hint()
{
    printf("\n1--create new instruction sequence      2--set memory page number(4 to 32)\n");
    printf("3--solve by FIFO algorithm              4--solve by LRU algorithm\n");
    printf("5--solve by OPT algorithm               0--exit\n");
    printf("*********Please input Your choice:  ");
}

/*通过随机数产生一个指令序列,共320条指令*/
void produce_inst()
{
    int m, n;
    int num = 0;

    // 50%的指令是顺序执行的
    for (m = 1; m <= maxn / 2; ++m) {
        inst[num++] = m;
    }

    // 25%的指令是均匀分布在前地址部分
    for (int i = 0; i < maxn / 4; ++i) {
        n = rand() % (maxn / 2 + 1); // 确保不会超出前半部分的地址范围
        inst[num++] = n;
    }

    // 25%的指令是均匀分布在后地址部分
    for (int i = 0; i < maxn / 4; ++i) {
        n = rand() % (maxn / 2) + (maxn / 2 + 1); // 确保不会超出后半部分的地址范围
        inst[num++] = n;
    }

    // 打印生成的指令序列
    printf("Generated instruction sequence:\n");
    for (int i = 0; i < maxn; ++i) {
        printf("%d ", inst[i]);
        if ((i + 1) % 10 == 0) { // 每10个指令换行
            printf("\n");
        }
    }
    printf("\n"); // 在序列结束后换行
}


/*将指令序列变换成为页地址流*/
void turn_page_address()
{
    for(int i=0; i<maxn; i++){
        page[i] = inst[i]/10;
    }
}

void FIFO_solve()
{
    memset(in, false, sizeof(in));
    int fault_n = 0;//缺页率
    int ptr, i;

    //预调页填满空间
    ptr = 0; //下一个要放的位置
    for(i=0; i<maxn && ptr<size; i++)
        if(!in[page[i]])
        {
            pin[ptr++] = page[i];
            in[page[i]] = true;
            fault_n++;
        }

    //继续执行剩下的指令
    ptr = 0;//队列里最先进来的位置,即下一个要被替换的位置
    for(; i<maxn; i++)
        if(!in[page[i]])
        {
            /*--------------*/
            //请补全该部分
            /*--------------*/
            in[pin[ptr]] = false; // 将最老的页面置换出去
            pin[ptr] = page[i]; // 放入新页面
            in[page[i]] = true; // 更新页面状态
            fault_n++;
            ptr = (ptr + 1) % size; // 循环队列
        }
        else // 已经在内存中,更新ptr指向下一个要检查的页面
        {
            ptr = (ptr + 1) % size;
        }


    printf("\nBy FIFO algorithm, the fault-page number is:  %d\n", fault_n);
    printf("                   the hit ratio is :  %.2lf\n", (1-(fault_n+0.0)/320.0));
    printf("                   the Page Fault Rate is :  %.2lf\n", (fault_n+0.0)/320.0);
}

void LRU_solve()
{
    int ltu[maxp]; //last_time_use
    int ti = 1;    //模拟时间
    int fault_n = 0;
    memset(ltu, 0, sizeof(ltu));
    memset(in, false, sizeof(in));
    memset(pin, -1, sizeof(pin));

    int min, ptr, i, j;
    for(i=0; i<maxn; i++)
    {
        if(!in[page[i]])
        {
            //寻找lru
            min=1000000; ptr=0;
            for(j=0; j<size; j++)
            {
                if(ltu[j] < min)
                {
                    min = ltu[j];
                    ptr = j;
                }
            }
            //替换或写入
            if(pin[ptr] != -1){
                 in[pin[ptr]] = false;
            }
            pin[ptr] = page[i];
            in[page[i]] = true;
            ltu[ptr] = ti++;
            fault_n++;
        }
        else//已经在内存里则只需更改最近使用时间
        {
            for(j=0; j<size; j++)
                if(pin[j] == page[i])
                {
                    ltu[j] = ti++;
                    break;
                }
        }
    }

    printf("\nBy LRU algorithm, the fault-page number is:  %d\n", fault_n);
    printf("                   the hit ratio is :  %.2lf\n", (1-(fault_n+0.0)/320.0));
    printf("                   the Page Fault Rate is :  %.2lf\n", (fault_n+0.0)/320.0);
}

void OPT_solve()
{
    int ntu[maxp];//next_time_use
    int fault_n = 0;
    int i, j;
    memset(in, false, sizeof(in));
    memset(ntu, -1, sizeof(ntu));

    //预调页填满
    int ptr = 0;
    for(i=0; i<maxn && fault_n<size; i++)
    {
        if(!in[page[i]])
        {
            in[page[i]] = true;
            pin[ptr] = page[i];
            fault_n++;
            ptr++;
        }
    }

    //初始化ntu数组
    ptr = 0;
    for(j=i; j<maxn && ptr<32; j++)
    {
        if(ntu[page[j]] == -1)
        {
            ntu[page[j]] = j;
            for(int k = j+1; k < maxn; k++)
            {
                if(page[k] == page[j])
                {
                    ntu[page[j]] = k;
                    break;
                }
            }
        }
    }

    int max;
    for(; i<maxn; i++)
    {
        if(!in[page[i]])
        {
            max = -1; ptr = 0;
            for(j=0; j<size; j++)
            {
                if(ntu[pin[j]] == -1)
                {
                    ptr = j;
                    break;
                }
                if(ntu[pin[j]] > max)
                {
                    max = ntu[pin[j]];
                    ptr = j;
                }
            }
            in[pin[ptr]] = false;
            in[page[i]] = true;
            pin[ptr] = page[i];
            fault_n++;
        }

        ntu[page[i]] = -1;
        for(j=i+1; j<maxn; j++)
            if(page[j] == page[i])
            {
                ntu[page[i]] = j;
                break;
            }
    }

    printf("\nBy OPT algorithm, the fault-page number is:  %d\n", fault_n);
    printf("                   the hit ratio is :  %.2lf\n", (1-(fault_n+0.0)/320.0));
    printf("                   the Page Fault Rate is :  %.2lf\n", (fault_n+0.0)/320.0);
}


int main()
{
    srand(time(NULL));
    welcome();

    int choice;
    while(1)
    {
        input_hint();
        scanf("%d", &choice);
        printf("\n");

        if(choice == 0)
        {
            printf("BYE-BYE!!!\n");
            break;
        }
        if(choice == 1)
        {
            produce_inst();
            turn_page_address();
            printf("New page address sequence is set OK!!!\n");
        }
        else if(choice == 2)
        {
            printf("Please input the size of memory page number:  ");
            scanf("%d", &size);
        }
        else if(choice == 3)
            FIFO_solve();
        else if(choice == 4)
            LRU_solve();
        else if(choice == 5)
            OPT_solve();
        else
            printf("INPUT ERROR !!! \n");
    }

    return 0;
}

实验目的】 1. 通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解; 2. 熟悉虚存管理的各种页面淘汰算法3. 通过编写和调试地址转换过程的模拟程序以加强对地址转换过程的了解。 【实验准备】 1.虚拟存储器的管理方式  段式管理  页式管理  段页式管理 2.页面置换算法  先进先出置换算法  最近最久未使用置换算法  Clock置换算法  其他置换算法实验内容】 1. 实验题目 设计一个请求页式存储管理方案。并编写模拟程序实现之。产生一个需要访问的指令地址流。它是一系列需要访问的指令的地址。为不失一般性,你可以适当地(用人工指定地方法或用随机数产生器)生成这个序列,使得 50%的指令是顺序执行的。25%的指令均匀地散布在前地址部分,25%的地址是均匀地散布在后地址部分。为简单起见。页面淘汰算法采用 FIFO页面淘汰算法,并且在淘汰一页时,只将该页在页表中抹去。而不再判断它是否被改写过,也不将它写回到辅存。 2. 具体做法 产生一个需要访问的指令地址流;指令合适的页面尺寸(例如以 1K或2K为1页);指定内存页表的最大长度,并对页表进行初始化;每访问一个地址时,首先要计算该地址所在的页的页号,然后查页表,判断该页是否在主存——如果该页已在主存,则打印页表情况;如果该页不在主存且页表未满,则调入一页并打印页表情况;如果该页不足主存且页表已满,则按 FIFO页面淘汰算法淘汰一页后调入所需的页,打印页表情况;逐个地址访问,直到所有地址访问完毕。
假设每个页面中可存放10条指令,分配给作业的内存块数为4。 用C语言语言模拟一个作业的执行过程,该作业共有320条指令, 即它的地址空间为32页,目前它的所有页都还未调入内存。在模拟过程中,如果所访问的指令已在内存,则显示其物理地址,并转下一条指令。如果所访问的指令还未装入内存,则发生缺页,此时需要记录缺页的次数,并将相应页调入内存。如果4个内存块均已装入该作业,则需要进行页面置换,最后显示其物理地址,并转向下一条指令。在所有320条指令执行完毕后,请计算并显示作业运行过程中发生的缺页率。 置换算法:请分别考虑最佳置换算法(OPT)、先进先出(FIFO)算法和最近最久未使用算法(LRU)。 作业中指令的访问次序按下述原则生成: 50%的指令是顺序执行的; 25%的指令是均匀分布在前地址部分; 25%的指令是均匀分布在后地址部分; 具体的实施方法是:    在[0,319]的指令地址之间随机选取一起点m;    顺序执行下一条指令,即执行地址序号为m+1的指令;    通过随机数,跳转到前地址部分[0,m+1]中的某条指令处,其序号为m1;    顺序执行下一条指令,其地址序号为m1+1的指令;    通过随机数,跳转到后地址部分[m1+2,319]中的某条指令处,其序号为m2;    顺序执行下一条指令,其地址序号为m2+1的指令; 重复跳转到前地址部分,顺序执行,跳转到后地址部分,顺序执行的过程直至执行320条指令。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值