操作系统实验三——页面替换算法的比较研究

来源:互联网 发布:病理图像分析算法 编辑:程序博客网 时间:2024/06/06 09:24

在本实验中,引用串的长度为100000个,生成方法为按照给定的指令跳转率随即生成,指令跳转率由调用函数给出。由于指令的跳转率对最终的各种替换算法的缺页率有明显的影响,所以,在实验中,我用一组不同的跳转率来测试在不同指令跳转条件下不同算法的缺页率。

另外,实验中使用的内存的页面数为10,虚拟存储器中的页面总是为100

 

以下是程序中定义的一些数据结构和函数原形:

#define STREAM_LEN 100000

#define MAX_PAGE_NO 100

#define WORK_PAGES 10

 

typedef enum {BEST_REP, FIFO_REP, LRU_REP, CLOCK_REP, RAND_REP} REP;

 

void best_rep(int *stream, int pos, int *memory);

void fifo_rep(int *stream, int pos, int *memory);

void lru_rep(int *stream, int pos, int *memory);

void clock_rep(int *stream, int pos, int *memory);

void rand_rep(int *stream, int pos, int *memory);

 

各种替换算法如课本中所述,再次不再重复。

page_stream.cpp

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "page_stream.h"

void generateStream(int stream[], int stream_len, double jumpRate, int maxPageNo, int workPages) {
 srand((unsigned)time(NULL));
 int startPageRange = maxPageNo - workPages + 1;

 int startPage = getStartPage(startPageRange);
 int position = 0;
 while (true) {
  position = genSubStr(stream, position, startPage);
  if (position == stream_len)
   break;
  if (genRate() < jumpRate)
   startPage = getStartPage(startPageRange);
 }

 return;
}

int getStartPage(int range) {
 return (rand() % (range + 1));
}

double genRate() {
 return ((double)rand())/RAND_MAX;
}

int genSubStr(int stream[], int startPosition, int startPage) {
 for (int i = 0; i < 10; i++) {
  stream[startPosition + i] = startPage + (rand()%10);
 }

 return startPosition + i;
}

replace_fun.cpp

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "replace_fun.h"

bool in_mem(int page, int *memory) {
 for (int i = 0; i < WORK_PAGES; i++) {
  if (memory[i] == page) {
   return true;
  }
 }

 return false;
}

void replacePage(int *stream, int *memory, REP rep, int pos) {
 switch (rep) {
 case BEST_REP:
  best_rep(stream, pos, memory);
  break;
 case FIFO_REP:
  fifo_rep(stream, pos, memory);
  break;
 case LRU_REP:
  lru_rep(stream, pos, memory);
  break;
 case CLOCK_REP:
  clock_rep(stream, pos, memory);
  break;
 case RAND_REP:
  srand((unsigned)time(NULL));
  rand_rep(stream, pos, memory);
  break;
 }
}

static int lruAid[WORK_PAGES] = {0};
void updateLRU(int *memory, int page) {
 for (int i = 0; i < WORK_PAGES; i++) {
  lruAid[i]++;
 }
 for (i = 0; i < WORK_PAGES; i++) {
  if (memory[i] == page) {
   lruAid[i] = 0;
   break;
  }
 }

 return;
}

static int clockAid[WORK_PAGES] = {0};
void updateClock(int *memory, int page) {
 for (int i = 0; i < WORK_PAGES; i++) {
  if (memory[i] == page) {
   clockAid[i] = 1;
   break;
  }
 }

 return;
}

double run(int *stream, int *memory, REP rep) {
 int pos = 0;
 int replaceTimes = 0;
 for (pos = 0; pos < STREAM_LEN;) {
  if (in_mem(stream[pos], memory)) {
   if (rep == LRU_REP) {
    updateLRU(memory, stream[pos]);
   }
   else if (rep == CLOCK_REP) {
    updateClock(memory, stream[pos]);
   }
   pos++;
   continue;
  }
  else {
   replacePage(stream, memory, rep, pos);
   replaceTimes++;
  }
 }
 
 return ((double)replaceTimes)/STREAM_LEN;
}

bool check(int *memTemp, int check_page, int replace_page, int *memory) {
 int k = 0;
 for (int i = 0; i < WORK_PAGES; i++) {
  if (memTemp[i] == -1) {
   k++;
  }
  if (memTemp[i] == check_page) {
   memTemp[i] = -1;
   k++;
  }
 }
 if (k == WORK_PAGES-1) {
  for (int i = 0; i < WORK_PAGES; i++) {
   if (memTemp[i] != -1)
    break;
  }
  memory[i] = replace_page;
  return true;
 }

 return false;
}

void best_rep(int *stream, int pos, int *memory) {
 int temp[WORK_PAGES];
 for (int i = 0; i < WORK_PAGES; i++) {
  temp[i] = memory[i];
 }

 int posTemp = pos + 1;
 bool hasReplaced = false;
 while (posTemp != STREAM_LEN) {
  hasReplaced = check(temp, stream[posTemp], stream[pos], memory);
  if (hasReplaced)
   break;
  else
   posTemp++;
 }
 if (!hasReplaced) {
  for (int i = 0; i < WORK_PAGES; i++) {
   if (temp[i] != -1)
    break;
  }
  memory[i] = stream[pos];
 }

 return;
}

void fifo_rep(int *stream, int pos, int *memory) {
 static int oldest = -1;
 memory[(oldest ++) % WORK_PAGES] = stream[pos];

 return;
}

void lru_rep(int *stream, int pos, int *memory) {
 int k = 0, temp = -1;
 for (int i = 0; i < WORK_PAGES; i++) {
  if (lruAid[i] > temp) {
   temp = lruAid[i];
   k = i;
  }
 }

 memory[k] = stream[pos];
 lruAid[k] = 0;

 return;
}

static int clockPointer = 0;
void clock_rep(int *stream, int pos, int *memory) {
 while (true) {
  if (clockAid[clockPointer] == 1) {
   clockAid[clockPointer] = 0;
   clockPointer = (clockPointer + 1) % WORK_PAGES;
  }
  else if (clockAid[clockPointer] == 0) {
   break;
  }
 }

 memory[clockPointer] = stream[pos];
 
 return;
}

void rand_rep(int *stream, int pos, int *memory) {
 memory[rand()%WORK_PAGES] = stream[pos];

 return;
}

main.cpp

#include <stdio.h>
#include <memory.h>
#include "page_stream.h"
#include "main.h"
#include "replace_fun.h"

main() {
 int stream[STREAM_LEN];
 int memory[WORK_PAGES];
 double jumpRate;

 jumpRate = 0.4;
 memset(memory, -1, WORK_PAGES);
 generateStream(stream, STREAM_LEN, jumpRate, MAX_PAGE_NO, WORK_PAGES);
 int i = 0, j = 0;
 do {
  if (!in_mem(stream[j], memory)) {
   memory[i++] = stream[j++];
  }
  else {
   j++;
  }
 } while (i < WORK_PAGES);

 printf("指令跳转率为%f时:/n/n", jumpRate);
 printf("最佳替换算法缺页率:/n");
 printf("%f/n", run(stream, memory, BEST_REP));
 printf("随机替换算法缺页率:/n");
 printf("%f/n", run(stream, memory, RAND_REP));
 printf("先进先出替换算法缺页率:/n");
 printf("%f/n", run(stream, memory, FIFO_REP));
 printf("最近最久未使用替换算法缺页率:/n");
 printf("%f/n", run(stream, memory, LRU_REP));
 printf("CLOCK替换算法缺页率:/n");
 printf("%f/n", run(stream, memory, CLOCK_REP));

 return 0;
}

原创粉丝点击