【实验题目】
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;
}
2157

被折叠的 条评论
为什么被折叠?



