您的位置:首页 > 其它

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

2006-06-02 09:50 591 查看
在本实验中,引用串的长度为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;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: