(1)通过随机数产生一个指令序列,共320条指令。其地址按下述原则生成: ①50%的指令是顺序执行的; ②25%的指令是均匀分布在前地址部分; ③25%的指令是均匀分布在后地址部分; 具体的实施方法是: ① 在[0,319]的指令地址之间随机选取一起点m; ② 顺序执行一条指令,即执行地址为m+1的指令; ③ 在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m’; ④ 顺序执行一条指令,其地址为m’+1; ⑤ 在后地址[m’+2,319]中随机选取一条指令并执行; ⑥ 重复①-⑤,直到执行320次指令。 (2)将指令序列变换成页地址流,设: ①页面大小为1K; ②用户内存容量为4页到32页; ③用户虚存容量为32K。 在用户虚存中,按每页存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为: 第0条—第9条指令为第0页(对应虚存地址为[0,9]); 第10条—第19条指令为第1页(对应虚存地址为[10,19]); 。。。。。。。。。。。。。。。。。。。。。 第310条—第319条指令为第31页(对应虚存地址为[310,319]); 按以上方式,用户指令可组成32页。 (3)计算并输出下述各种算法在不同内存容量下的命中率。 ①FIFO先进先出的页面淘汰算法 ②LRU最近最少使用页面淘汰算法 ③OPT最佳页面淘汰算法 ④LFU最不经常使用页面淘汰算法 ⑤NUR最近没有使用页面淘汰算法。 按上述要求编写C语言代码

时间: 2023-06-18 17:08:48 浏览: 77
```c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define INSTRUCTION_NUM 320 #define PAGE_SIZE 1024 #define MIN_PAGE_NUM 4 #define MAX_PAGE_NUM 32 #define VIRTUAL_SIZE (PAGE_SIZE * MAX_PAGE_NUM) // 生成随机指令序列 void generateInstructions(int* instructions) { // 初始化指令序列 for (int i = 0; i < INSTRUCTION_NUM; i++) { instructions[i] = i; } // 按要求打乱指令序列 for (int i = 0; i < INSTRUCTION_NUM; i++) { int j = rand() % INSTRUCTION_NUM; int temp = instructions[i]; instructions[i] = instructions[j]; instructions[j] = temp; } } // 将指令序列转换为页地址流 void generatePageStream(int* instructions, int* pageStream, int pageTable[][2]) { int nextPage = 0; // 下一页的页号 int instructionCount = 0; // 当前已经生成的指令数 // 将指令序列分页 while (instructionCount < INSTRUCTION_NUM) { // 计算当前指令所在页的页号 int currentPage = nextPage; nextPage = (nextPage + 1) % MAX_PAGE_NUM; // 将当前页号与页表的映射存储起来 pageTable[currentPage][0] = instructionCount / 10; pageTable[currentPage][1] = instructionCount % 10; // 将当前页的指令加入页地址流中 for (int i = 0; i < 10 && instructionCount < INSTRUCTION_NUM; i++) { pageStream[instructionCount] = currentPage; instructionCount++; } } } // FIFO算法 int FIFO(int* pageStream, int pageTable[][2], int pageFrameNum) { int hitCount = 0; // 命中次数 int currentFrame = 0; // 当前指令所在帧的下标 int* pageFrames = (int*)malloc(sizeof(int) * pageFrameNum); // 物理内存中的页帧 // 初始化页帧 for (int i = 0; i < pageFrameNum; i++) { pageFrames[i] = -1; // -1表示帧为空 } // 逐条执行指令 for (int i = 0; i < INSTRUCTION_NUM; i++) { int currentPage = pageStream[i]; bool isHit = false; // 当前指令是否命中 // 在页帧中查找当前页是否已经存在 for (int j = 0; j < pageFrameNum; j++) { if (pageFrames[j] == currentPage) { isHit = true; break; } } // 如果未命中,则将当前页替换到物理内存中的一页帧中 if (!isHit) { pageFrames[currentFrame % pageFrameNum] = currentPage; currentFrame++; } else { hitCount++; } } free(pageFrames); return hitCount; } // LRU算法 int LRU(int* pageStream, int pageTable[][2], int pageFrameNum) { int hitCount = 0; // 命中次数 int currentFrame = 0; // 当前指令所在帧的下标 int* pageFrames = (int*)malloc(sizeof(int) * pageFrameNum); // 物理内存中的页帧 int* lastAccessTime = (int*)malloc(sizeof(int) * MAX_PAGE_NUM); // 记录每个页最近访问时间 // 初始化页帧和最近访问时间 for (int i = 0; i < pageFrameNum; i++) { pageFrames[i] = -1; lastAccessTime[i] = -1; } // 逐条执行指令 for (int i = 0; i < INSTRUCTION_NUM; i++) { int currentPage = pageStream[i]; bool isHit = false; // 当前指令是否命中 // 在页帧中查找当前页是否已经存在,同时更新最近访问时间 for (int j = 0; j < pageFrameNum; j++) { if (pageFrames[j] == currentPage) { isHit = true; lastAccessTime[currentPage] = i; break; } } // 如果未命中,则将最近最少使用的页替换到物理内存中的一页帧中 if (!isHit) { int minAccessTime = INSTRUCTION_NUM; int minAccessIndex = -1; // 在页帧中查找最近最少使用的页 for (int j = 0; j < pageFrameNum; j++) { if (lastAccessTime[pageFrames[j]] < minAccessTime) { minAccessTime = lastAccessTime[pageFrames[j]]; minAccessIndex = j; } } pageFrames[minAccessIndex] = currentPage; lastAccessTime[currentPage] = i; } else { hitCount++; } } free(pageFrames); free(lastAccessTime); return hitCount; } // OPT算法 int OPT(int* pageStream, int pageTable[][2], int pageFrameNum) { int hitCount = 0; // 命中次数 int currentFrame = 0; // 当前指令所在帧的下标 int* pageFrames = (int*)malloc(sizeof(int) * pageFrameNum); // 物理内存中的页帧 int* nextUseTime = (int*)malloc(sizeof(int) * MAX_PAGE_NUM); // 记录每个页下一次使用的时间 // 初始化页帧和下一次使用时间 for (int i = 0; i < pageFrameNum; i++) { pageFrames[i] = -1; nextUseTime[i] = INSTRUCTION_NUM; // 初始设为最大值,表示未来不再使用 } // 预先计算所有页的下一次使用时间 for (int i = 0; i < INSTRUCTION_NUM; i++) { int nextPage = pageStream[i + 1]; // 下一条指令所在页 if (nextUseTime[nextPage] == INSTRUCTION_NUM) { nextUseTime[nextPage] = i + 1; } } // 逐条执行指令 for (int i = 0; i < INSTRUCTION_NUM; i++) { int currentPage = pageStream[i]; bool isHit = false; // 当前指令是否命中 // 在页帧中查找当前页是否已经存在,同时更新下一次使用时间 for (int j = 0; j < pageFrameNum; j++) { if (pageFrames[j] == currentPage) { isHit = true; nextUseTime[currentPage] = INSTRUCTION_NUM; // 设置为未来不再使用 break; } } // 如果未命中,则将下一次不再使用的页替换到物理内存中的一页帧中 if (!isHit) { int maxNextUseTime = -1; int maxNextUseIndex = -1; // 在页帧中查找下一次不再使用的页 for (int j = 0; j < pageFrameNum; j++) { if (nextUseTime[pageFrames[j]] > maxNextUseTime) { maxNextUseTime = nextUseTime[pageFrames[j]]; maxNextUseIndex = j; } } pageFrames[maxNextUseIndex] = currentPage; nextUseTime[currentPage] = INSTRUCTION_NUM; // 设置为未来不再使用 } else { hitCount++; } } free(pageFrames); free(nextUseTime); return hitCount; } // LFU算法 int LFU(int* pageStream, int pageTable[][2], int pageFrameNum) { int hitCount = 0; // 命中次数 int currentFrame = 0; // 当前指令所在帧的下标 int* pageFrames = (int*)malloc(sizeof(int) * pageFrameNum); // 物理内存中的页帧 int* accessCount = (int*)malloc(sizeof(int) * MAX_PAGE_NUM); // 记录每个页的访问次数 // 初始化页帧和访问次数 for (int i = 0; i < pageFrameNum; i++) { pageFrames[i] = -1; accessCount[i] = 0; } // 逐条执行指令 for (int i = 0; i < INSTRUCTION_NUM; i++) { int currentPage = pageStream[i]; bool isHit = false; // 当前指令是否命中 // 在页帧中查找当前页是否已经存在,同时更新访问次数 for (int j = 0; j < pageFrameNum; j++) { if (pageFrames[j] == currentPage) { isHit = true; accessCount[currentPage]++; break; } } // 如果未命中,则将访问次数最少的页替换到物理内存中的一页帧中 if (!isHit) { int minAccessCount = INSTRUCTION_NUM; int minAccessIndex = -1; // 在页帧中查找访问次数最少的页 for (int j = 0; j < pageFrameNum; j++) { if (accessCount[pageFrames[j]] < minAccessCount) { minAccessCount = accessCount[pageFrames[j]]; minAccessIndex = j; } } pageFrames[minAccessIndex] = currentPage; accessCount[currentPage] = 1; } else { hitCount++; } } free(pageFrames); free(accessCount); return hitCount; } // NUR算法 int NUR(int* pageStream, int pageTable[][2], int pageFrameNum) { int hitCount = 0; // 命中次数 int currentFrame = 0; // 当前指令所在帧的下标 int* pageFrames = (int*)malloc(sizeof(int) * pageFrameNum); // 物理内存中的页帧 int* useFlag = (int*)malloc(sizeof(int) * MAX_PAGE_NUM); // 记录每个页是否被访问过 // 初始化页帧和使用标志 for (int i = 0; i < pageFrameNum; i++) { pageFrames[i] = -1; useFlag[i] = 0; } // 逐条执行指令 for (int i = 0; i < INSTRUCTION_NUM; i++) { int currentPage = pageStream[i]; bool isHit = false; // 当前指令是否命中 // 在页帧中查找当前页是否已经存在,同时更新使用标志 for (int j = 0; j < pageFrameNum; j++) { if (pageFrames[j] == currentPage) { isHit = true; useFlag[currentPage] = 1; break; } } // 如果未命中,则将最近没有使用的页替换到物理内存中的一页帧中 if (!isHit) { int minUseFlag = INSTRUCTION_NUM; int minUseIndex = -1; // 在页帧中查找最近没有使用的页 for (int j = 0; j < pageFrameNum; j++) { if (useFlag[pageFrames[j]] < minUseFlag) { minUseFlag = useFlag[pageFrames[j]]; minUseIndex = j; } } pageFrames[minUseIndex] = currentPage; useFlag[currentPage] = 1; } else { hitCount++; } // 每5次指令更新一次使用标志 if (i % 5 == 4) { for (int j = 0; j < pageFrameNum; j++) { useFlag[pageFrames[j]] >>= 1; // 右移1位相当于除以2 } } } free(pageFrames); free(useFlag); return hitCount; } int main() { int instructions[INSTRUCTION_NUM]; int pageStream[INSTRUCTION_NUM]; int pageTable[MAX_PAGE_NUM][2]; // 生成随机指令序列 generateInstructions(instructions); // 将指令序列转换为页地址流 generatePageStream(instructions, pageStream, pageTable); // 遍历不同内存容量 for (int pageFrameNum = MIN_PAGE_NUM; pageFrameNum <= MAX_PAGE_NUM; pageFrameNum++) { printf("内存容量为%d页:\n", pageFrameNum); // 计算FIFO算法的命中率 int fifoHitCount = FIFO(pageStream, pageTable, pageFrameNum); printf("FIFO算法的命中率为%.2f%%\n", (fifoHitCount * 100.0 / INSTRUCTION_NUM)); // 计算LRU算法的命中率 int lruHitCount = LRU(pageStream, pageTable, pageFrameNum); printf("LRU算法的命中率为%.2f%%\n", (lruHitCount * 100.0 / INSTRUCTION_NUM)); // 计算OPT算法的命中率 int optHitCount = OPT(pageStream, pageTable, pageFrameNum); printf("OPT算法的命中率为%.2f%%\n", (optHitCount * 100.0 / INSTRUCTION_NUM)); // 计算LFU算法的命中率 int lfuHitCount = LFU(pageStream, pageTable, pageFrameNum); printf("LFU算法的命中率为%.2f%%\n", (lfuHitCount * 100.0 / INSTRUCTION_NUM)); // 计算NUR算法的命中率 int nurHitCount = NUR(pageStream, pageTable, pageFrameNum); printf("NUR算法的命中率为%.2f%%\n", (nurHitCount * 100.0 / INSTRUCTION_NUM)); printf("\n"); } return 0; } ```

相关推荐

最新推荐

recommend-type

操作系统实验报告(存储管理实验)

(1) 通过随机数产生一个指令序列,共320条指令。指令的地址按下述原则生成: 1. 50%的指令是顺序执行的; 2. 25%的指令是均匀分布在前地址部分; 3. 25%的指令是均匀分布在后地址部分; 具体的实施方法是: 1. 在...
recommend-type

操作系统存储管理实验报告(c/c++)

(1) 通过随机数产生一个指令序列(实际上是指令的逻辑地址序列),共320条指令。指令的地址按下述原则生成: A:50%的指令是顺序执行的 B:25%的指令要实现向前跳转,均匀分布在前地址部分 C:25%的指令要实现向后...
recommend-type

模拟操作系统的页面置换

华师要求的实验报告.没分,来捞点分 ...或采用以下方式:(1)通过随机数产生一个指令序列,共320条指令。指令的地址按下述原则生成: A:50%的指令是顺序执行的 B:25%的指令是均匀分布在前地址部分
recommend-type

员工考勤系统.docx

员工考勤系统.docx
recommend-type

基于STM32的调试模块的外设和时钟电路分析

基于STM32的调试模块的外设和时钟电路分析。回顾 CMSIS、LL、HAL 库
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

MATLAB图像处理算法宝典:从理论到实战

![MATLAB图像处理算法宝典:从理论到实战](https://img-blog.csdnimg.cn/20200717112736401.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2d1emhhbzk5MDE=,size_16,color_FFFFFF,t_70) # 1. MATLAB图像处理基础理论 MATLAB图像处理是一种利用MATLAB编程语言进行图像处理的强大工具。它提供了丰富的函数和工具箱,用于图像获取、增强、分
recommend-type

matlab中1/x的非线性规划

在MATLAB中,可以使用非线性规划函数(`fmincon`)来优化一个包含1/x的非线性目标函数。下面是一个简单的例子: ```matlab % 定义目标函数 fun = @(x) 1/x; % 定义约束函数(这里没有约束) nonlcon = []; % 定义初始点 x0 = 1; % 定义优化选项 options = optimoptions('fmincon', 'Display', 'iter'); % 进行非线性规划 [x, fval] = fmincon(fun, x0, [], [], [], [], [], [], nonlcon, options); ``` 在
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。