【操作系统】虚拟存储管理-页面置换算法

简介: 【操作系统】虚拟存储管理-页面置换算法


一. 实验目的

(1)理解虚拟内存管理的原理和技术;

(2)掌握请求分页存储管理中的页面置换算法;

(3)理解请求分页中的按需调页机制。

二. 实验内容

设计一个虚拟存储区和一个内存工作区,并使用先进先出(FIFO)算法来计算命中率。要求如下:

(1) 通过随机数产生一个指令序列,里面共320条指令;

(2) 将指令序列转换成页面序列。假设:页面大小为1KB,用户内存容量为4~32页,用户虚存容量为32KB。在用户虚存中,按每页存放10条指令排列虚存低值,320条指令将存放在32个页面中。

(3) 计算出置换算法在不同内存容量下的访问命中率。

(4) 访问命中率=1-(页面失效次数/页面访问总数)

三. 实验步骤

(1)编写C程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> 
#define TRUE 1
#define FALSE 0
#define INVALID -1
#define total_instruction 321
#define total_vp 32
//这里是 页表项 的 数组
typedef struct {
  int pn; //页号
  int pfn; //内存块号
  int counter;
  int time;
} p1_type;
p1_type p1[total_vp];
//这里是 页表项 的 链表
typedef struct pfc_struct {
  int pn;
  int pfn;
  struct pfc_struct *next;
} pfc_type;
pfc_type pfc[total_vp];
pfc_type *freepf_head;
pfc_type *busypf_head;
pfc_type *busypf_tail;
int diseffect;
int a[total_instruction]; //指令流数组
int page[total_instruction]; //每条指令 所属页号
int offset[total_instruction];
void initialize();
void FIFO(int total_pf);
int main() {
  int s,i,j;
  int pid=getpid();
  printf("pid=%d\n",pid);
  srand(10*pid);
  s=(float)319*rand()/32767/32767/2+1;
  printf("initialize s==%d\n",s);
  for(i=0; i<total_instruction; i+=4) {
    if(s<0 || s>319) {
      printf("When i==%d, Error, s==%d\n",i,s);
      exit(0);
    }
    a[i]=s;
    a[i+1]=a[i]+1;
    //a[i+2]=(float)a[i]*rand()/32767/32767/2;
    a[i+2]=(float)a[i]*rand()/32767/2;
    //printf("a[%d+2]=%d\n",i,a[i+2]);
    a[i+3]=a[i+2]+1;
    //s=(float)(318-a[i+2])*rand()/32767/32767/2+a[i+2]+2;
    s=(float)(318-a[i+2])*rand()/32767/2+a[i+2]+2;
    //printf("s==%d\n",s);
    if((a[i+2]>318) ||(s>319))
      printf("a[%d+2], a number which is %d and s==%d\n",i,a[i+2],s);
  }
  //
  for(i=0; i<total_instruction; i+=4) {
    for(j=0; j<4; j++)
      printf("%d ",a[i+j]);
    printf("\n");
  }
  for(i=0; i<total_instruction; i++) {
    page[i]=a[i]/10;
    offset[i]=a[i]%10;
  }
  for(i=4; i<=32; i++) {
    printf("%2d page frames",i);
    FIFO(i);
    printf("\n");
  }
} //end main
void initialize(int total_pf) {
  int i;
  diseffect=0;
  for(i=0; i<total_vp; i++) {
    p1[i].pn=i;
    p1[i].pfn=INVALID;
    p1[i].counter=0;
    p1[i].time=-1;
  }
  for(i=0; i<total_pf-1; i++) {
    pfc[i].next=&pfc[i+1];
    pfc[i].pfn=i;
  }
  pfc[total_pf-1].next=NULL;
  pfc[total_pf-1].pfn=total_pf-1;
  freepf_head=&pfc[0];
}
void FIFO(int total_pf) {
  int i,j;
  pfc_type *p;
  initialize(total_pf);
  busypf_head=busypf_tail=NULL;
  for(i=0; i<total_instruction; i++) {
    if(p1[page[i]].pfn==INVALID) {
      diseffect+=1;
      if(freepf_head==NULL) {
        p=busypf_head->next;
        p1[busypf_head->pn].pfn=INVALID;//释放第一个页面
        freepf_head=busypf_head;
        freepf_head->next=NULL;
        busypf_head=p;
      }
      p=freepf_head->next;
      freepf_head->next=NULL;
      freepf_head->pn=page[i];
      p1[page[i]].pfn=freepf_head->pfn;
      if(busypf_tail==NULL)
        busypf_head=busypf_tail=freepf_head;
      else {
        busypf_tail->next=freepf_head;
        busypf_tail=freepf_head;
      }
      freepf_head=p;
    } else
      //printf("mingzhong p1[page[%d]].pfn==%d\n",i,p1[page[i]].pfn);
      ;
  }
  printf(" FIFO:%6.4f",1-(float)diseffect/320);
}

该程序主要实现了FIFO算法来模拟页面置换过程。

首先,定义了几个常量和结构体,包括页表项和页表项链表的结构。

初始化函数initialize用于初始化页表项和页表项链表,并设置了空闲页面帧和正在使用的页面帧的头节点。

FIFO函数实现了FIFO算法的页面置换过程。该算法的思想是,若所需页面不在内存中,则将内存中的最早进入的页面置换出去,并将所需页面加入内存中。具体实现过程如下:

  1. 初始化页面帧和页面帧链表。
  2. 遍历指令流数组,判断是否所需页面在内存中。
  3. 若所需页面不在内存中,则发生缺页中断,需要进行页面置换。
  4. 若空闲页面帧不为空,则将所需的页面加入内存中。更新页表项的页面帧号,并将该页面帧从空闲页面帧链表中移除,加入正在使用的页面帧链表中。
  5. 若空闲页面帧为空,则选择最早进入的页面帧进行置换。首先释放该页面帧对应的页表项,然后将最早进入的页面帧从正在使用的页面帧链表中移除,加入空闲页面帧链表中,最后将所需的页面加入内存中。更新页表项的页面帧号,并将该页面帧从空闲页面帧链表中移除,加入正在使用的页面帧链表中。
  6. 统计页面缺失次数。
  7. 输出FIFO算法的缺页率。

最后,在main函数中,生成了指令流数组,并通过FIFO函数模拟了不同页面帧数下的页面置换过程,并输出了相应的缺页率。

四. 实验结果

五. 实验总结

页面置换算法是操作系统中用来解决内存管理问题的一种重要技术。在计算机中,内存是有限的资源,而进程需要占用内存来运行。当内存不足时,操作系统需要进行页面置换,将部分进程从内存中调出,以便为新的进程腾出空间。

页面置换算法的目标是尽可能地提高内存利用率和进程的执行效率。常见的页面置换算法包括最佳置换算法(OPT)、先进先出置换算法(FIFO)、最近最久未使用置换算法(LRU)等。

最佳置换算法(OPT)是一种理想的页面置换算法,它假设可以预测未来的访问序列。它会将最久未被使用到的页面替换出去,以便给未来有可能被使用的页面腾出空间。然而,由于无法准确预测未来的访问序列,实际上很难实现最佳置换算法。

先进先出置换算法(FIFO)是一种简单而常用的页面置换算法。它按照进程进入内存的先后顺序进行页面置换。当内存不足时,最先进入内存的页面会被置换出去。然而,先进先出置换算法存在一种缺点,即它无法考虑页面的访问频率和重要性。

最近最久未使用置换算法(LRU)是一种基于页面访问历史的置换算法。它假设过去被访问得最近的页面最有可能在未来被再次访问。因此,最近最久未使用置换算法会选择最久未被访问的页面进行置换。相比于先进先出置换算法,LRU算法更加智能化,能够更好地适应不同的页面访问特征。

除了上述几种页面置换算法外,还有一些其他的算法,如时钟算法、工作集算法等。这些算法都有各自的特点和适用场景。

页面置换算法是操作系统中内存管理的关键技术之一。通过合理地选择和使用页面置换算法,可以提高内存利用率和进程执行效率,从而提升系统的整体性能。

目录
相关文章
|
3月前
|
算法 调度 UED
探索操作系统的心脏:调度算法的奥秘与影响
【10月更文挑战第9天】 本文深入探讨了操作系统中至关重要的组件——调度算法,它如同人体的心脏,维持着系统资源的有序流动和任务的高效执行。我们将揭开调度算法的神秘面纱,从基本概念到实际应用,全面剖析其在操作系统中的核心地位,以及如何通过优化调度算法来提升系统性能。
|
2月前
|
算法 调度 Python
深入理解操作系统中的进程调度算法
在操作系统中,进程调度是核心任务之一,它决定了哪个进程将获得CPU的使用权。本文通过浅显易懂的语言和生动的比喻,带领读者了解进程调度算法的重要性及其工作原理,同时提供代码示例帮助理解。
|
2月前
|
机器学习/深度学习 算法 数据挖掘
提高时钟置换算法的性能
【10月更文挑战第25天】通过上述一种或多种方法的综合应用,可以在不同程度上提高时钟置换算法的性能,使其更好地适应各种复杂的系统环境和应用场景,提高虚拟内存管理的效率和系统的整体性能。
129 62
|
2月前
|
算法
时钟置换算法
【10月更文挑战第25天】时钟置换算法是一种简单而有效的页面置换算法,它通过使用位标志和环形链表的结构,在一定程度上平衡了算法的复杂性和性能表现。虽然它存在一些局限性,但通过改进和与其他算法的结合,可以在不同的系统环境中发挥重要作用,提高虚拟内存管理的效率和系统的整体性能。
185 51
|
2月前
|
算法
虚拟内存的页面置换算法有哪些?
【10月更文挑战第25天】不同的页面置换算法各有优缺点,在实际应用中,操作系统会根据不同的应用场景和系统需求选择合适的页面置换算法,或者对算法进行适当的改进和优化,以平衡系统的性能、开销和资源利用率等因素。
70 5
|
2月前
|
算法 大数据 Linux
深入理解操作系统之进程调度算法
【10月更文挑战第24天】本文旨在通过浅显易懂的语言,带领读者深入了解操作系统中的进程调度算法。我们将从进程的基本概念出发,逐步解析进程调度的目的、重要性以及常见的几种调度算法。文章将通过比喻和实例,使复杂的技术内容变得生动有趣,帮助读者建立对操作系统进程调度机制的清晰认识。最后,我们还将探讨这些调度算法在现代操作系统中的应用和发展趋势。
|
3月前
|
算法 调度 UED
深入理解操作系统的进程调度算法
【10月更文挑战第7天】在操作系统的心脏——内核中,进程调度算法扮演着至关重要的角色。它不仅影响系统的性能和用户体验,还直接关系到资源的合理分配。本文将通过浅显易懂的语言和生动的比喻,带你一探进程调度的秘密花园,从最简单的先来先服务到复杂的多级反馈队列,我们将一起见证算法如何在微观世界里编织宏观世界的和谐乐章。
|
3月前
|
边缘计算 算法 调度
探究操作系统的心脏:调度算法的进化与影响
【10月更文挑战第2天】 本文深入探讨了操作系统中核心组件——调度算法的历史演变、关键技术突破及其对现代计算的影响。通过详细回顾从单任务到多任务、实时系统及分布式计算环境下调度算法的发展,文章揭示了这些算法如何塑造我们的数字世界,并对未来的趋势进行了展望。不同于传统的摘要,本文特别聚焦于技术细节与实际应用的结合点,为读者提供一幅清晰的技术演进蓝图。
79 4
|
3月前
|
算法 调度 UED
探索操作系统的心脏:进程调度算法
【9月更文挑战第32天】在数字世界的每一次心跳中,都隐藏着一个不为人知的英雄——进程调度算法。它默默地在后台运作,确保我们的命令得到快速响应,应用程序平稳运行。本文将带你走进操作系统的核心,一探进程调度的奥秘,并通过代码示例揭示其背后的智慧。准备好跟随我一起深入这趟技术之旅了吗?让我们开始吧!
|
4月前
|
算法 调度
操作系统的心脏:深入解析进程调度算法
本文旨在深入探讨现代操作系统中的核心功能之一——进程调度。进程调度算法是操作系统用于分配CPU时间片给各个进程的机制,以确保系统资源的高效利用和公平分配。本文将详细介绍几种主要的进程调度算法,包括先来先服务(FCFS)、短作业优先(SJF)、时间片轮转(RR)以及优先级调度(PS)。我们将分析每种算法的基本原理、优缺点及其适用场景。同时,本文还将讨论多级反馈队列(MFQ)调度算法,并探讨这些算法在实际应用中的表现及未来发展趋势。通过深入解析这些内容,希望能够为读者提供对操作系统进程调度机制的全面理解。