页面置换算法C语言实现(FIFO,OPT,LRU)

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>

#define NUM_OF_INSTRUSTIONS 320

void generate_instrustions(__u_int* instrustions,__u_int* original_page_address_flow)
{
  __u_int page_no = 0;
  for(size_t i = 0;i < NUM_OF_INSTRUSTIONS;i += 4) {
    __u_int begin;
    do
    {
      begin = (__u_int)rand() % NUM_OF_INSTRUSTIONS;
    } while (begin == 319);
    instrustions[i] = begin + 1;
    original_page_address_flow[i] = (begin + 1) / 10;
    __u_int before;
    do
    {
      before = (__u_int)rand() % ((begin + 1) + 1) + 0;
    } while (before > 317);
    instrustions[i + 1] = before;
    original_page_address_flow[i + 1] = before / 10;
    instrustions[i + 2] = before + 1;
    original_page_address_flow[i + 2] = (before + 1) / 10;
    __u_int after = (__u_int)rand() % (319 - (before + 2) + 1) + (before + 2);
    instrustions[i + 3] = after;
    original_page_address_flow[i + 3] = after / 10;
  }
}

__u_int merge(__u_int* original_page_address_flow,__u_int* page_address_flow)
{
  __u_int num_of_page_address_flow = 0;
  for(size_t i = 0;i < NUM_OF_INSTRUSTIONS;++i) {
    if(i == 0) {
      page_address_flow[num_of_page_address_flow] = original_page_address_flow[i];
      ++num_of_page_address_flow;
    }
    else {
      if(original_page_address_flow[i] != original_page_address_flow[i - 1]) {
        page_address_flow[num_of_page_address_flow] = original_page_address_flow[i];
        ++num_of_page_address_flow;
      }
    }
  }
  return num_of_page_address_flow;
}

void print_current_state(__u_int* array,__u_int length)
{
  for(__u_int i = 0;i < length;++i) {
    printf("%d ",array[i]);
  }
  printf("\n");
}

void fifo_algorithm(__u_int num_of_blocks,__u_int* page_address_flow,__u_int num_of_page_address_flow)
{
  assert(num_of_blocks);
  __u_int num_of_interrupt = 0;
  __u_int current_index = 0;
  __u_int blocks[num_of_blocks];
  memset((void*)blocks,-1,sizeof(blocks));
  for(__u_int i = 0;i < num_of_page_address_flow;++i) {
    printf("Current page address flow:%d\n",page_address_flow[i]);
    int find = 0;
    for(__u_int j = 0;j < num_of_blocks;++j) {
      if(blocks[j] == page_address_flow[i]) {
        find = 1;
        break;
      }
    } 
    if(!find) {
      ++num_of_interrupt;
      blocks[current_index] = page_address_flow[i];
      current_index = (++current_index) % num_of_blocks;
      print_current_state(blocks,num_of_blocks);
    }
  }
  printf("Number of page missing interrupts:%d\n",num_of_interrupt);
  float page_fault_rate = num_of_interrupt / (float)num_of_page_address_flow;
  printf("Page falut rate:%f\n",page_fault_rate);
}

void opt_algorithm(__u_int num_of_blocks,__u_int* page_address_flow,__u_int num_of_page_address_flow)
{
  assert(num_of_blocks);
  __u_int num_of_interrupt = 0;
  __u_int blocks[num_of_blocks];
  memset((void*)blocks,-1,sizeof(blocks));
  for(__u_int i = 0;i < num_of_page_address_flow;++i) { 
    printf("Current page address flow:%d\n",page_address_flow[i]);
    int find = 0;
    for(__u_int j = 0;j < num_of_blocks;++j) {
      if(blocks[j] == page_address_flow[i]) {
        find = 1;
        break;
      }
    }
    if(!find) {
      ++num_of_interrupt;
      __u_int distance[num_of_blocks];
      for(__u_int j = 0;j < num_of_blocks;++j) {
        distance[j] = __UINT16_MAX__;
      }
      for(__u_int j = i + 1;j < num_of_page_address_flow;++j) {
        for(__u_int n = 0;n < num_of_blocks;++n) {
          if(page_address_flow[j] == blocks[n] && distance[n] > j) {
            distance[n] = j;
            break;
          }
        }
      }
      __u_int target_index = 0;
      __u_int max_distance = distance[target_index];
      for(__u_int j = 0;j < num_of_blocks;++j) {
        if(distance[j] == __UINT16_MAX__) {
          target_index = j;
          break;
        }
        if(distance[j] > max_distance) {
          target_index = j;
          max_distance = distance[j];
        }
      }
      blocks[target_index] = page_address_flow[i];
      print_current_state(blocks,num_of_blocks);
    }
  }
  printf("Number of page missing interrupts:%d\n",num_of_interrupt);
  float page_fault_rate = num_of_interrupt / (float)num_of_page_address_flow;
  printf("Page falut rate:%f\n",page_fault_rate);
}

void lru_algorithm(__u_int num_of_blocks,__u_int* page_address_flow,__u_int num_of_page_address_flow)
{
  assert(num_of_blocks);
  __u_int num_of_interrupt = 0;
  __u_int blocks[num_of_blocks];
  memset((void*)blocks,-1,sizeof(blocks));
  int interval[num_of_blocks];
  for(__u_int i = 0;i < num_of_blocks;++i)
    interval[i] = __UINT16_MAX__;
  for(__u_int i = 0;i < num_of_page_address_flow;++i) {
    printf("Current page address flow:%d\n",page_address_flow[i]);
    int find = 0;
    for(__u_int j = 0;j < num_of_blocks;++j) {
      if(page_address_flow[i] == blocks[j]) {
        find = 1;
        interval[j] = 0;
        break;
      }
    }
    if(!find) {
      ++num_of_interrupt;
      __u_int target_index = 0;
      __u_int max_interval = interval[target_index];
      for(__u_int j = 0;j < num_of_blocks;++j) {
        if(interval[j] > max_interval) {
          target_index = j;
          max_interval = interval[j];
        }
      }
      blocks[target_index] = page_address_flow[i];
      interval[target_index] = 0;
      print_current_state(blocks,num_of_blocks);
    }
    for(__u_int j = 0;j < num_of_blocks;++j) {
      if(interval[j] != __UINT16_MAX__)
        ++interval[j];
    }
  }
  printf("Number of page missing interrupts:%d\n",num_of_interrupt);
  float page_fault_rate = num_of_interrupt / (float)num_of_page_address_flow;
  printf("Page falut rate:%f\n",page_fault_rate);
}

int main(void)
{
  srand((unsigned int)time(NULL));
  __u_int instrustions[NUM_OF_INSTRUSTIONS];
  memset((void*)instrustions,0,sizeof(instrustions));
  __u_int original_page_address_flow[NUM_OF_INSTRUSTIONS];
  memset((void*)original_page_address_flow,0,sizeof(original_page_address_flow));
  generate_instrustions(instrustions,original_page_address_flow);
  __u_int page_address_flow[NUM_OF_INSTRUSTIONS];
  memset((void*)page_address_flow,-1,sizeof(page_address_flow));
  __u_int num_of_page_address_flow = merge(original_page_address_flow,page_address_flow);
  printf("The number of page address flow:%d\n",num_of_page_address_flow);
  __u_int num_of_blocks;
  scanf("%d",&num_of_blocks);
  fifo_algorithm(num_of_blocks,page_address_flow,num_of_page_address_flow);
  opt_algorithm(num_of_blocks,page_address_flow,num_of_page_address_flow);
  lru_algorithm(num_of_blocks,page_address_flow,num_of_page_address_flow);
  return 0;
}

采用如下规则生成指令集:
A:50%的指令是顺序执行的
B:25%的指令是均匀分布在前地址部分
C:25%的指令是均匀分布在后地址部分
具体的实施方法是:
A:在[0,319]的指令地址之间随机选取一起点m
B:顺序执行一条指令,即执行地址为m+1的指令
C:在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m’
D:顺序执行一条指令,其地址为m’+1
E:在后地址[m’+2,319]中随机选取一条指令并执行
F:重复步骤A-E,直到320次指令

页面大小为1K,用户虚存容量为32K

(OPT算法应该写得过于冗余了,封装一个struct Page应该会更好

  • 0
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值