FIFO
FIFO页面置换算法,先进先出算法,是相对简单的算法, 并且效率不是最佳的. 算法思路顾名思义,就是当页框(物理内存块)不够的时候, 将最先到内存中的页面置换出去,借此来空出位置换入新的页面.
备注:西南大学 操作系统实验
代码说明
可用页面4-32个,随机函数产生0-319的随机数共320个,模10后形成32个页面。
定义了两个类型的结构体,一个代表页面信息(逻辑),一个代表页框(物理),均有pn记录页号,pfn记录页框号,两个结构体的pn,pfn意义不同。页面的pn代表自己的页号以及自己存放在“页框号=pfn“的页框中;页框的pn代表自己存放的页面的页号,pfn代表自己的页框号。
initialize()用于初始化两个结构体,如把页框串联起来。
FIFO利用了free,busy两个链表实现。
最终结果应当在可用页面为32个时,命中率>=90%。
实现代码
#include "stdafx.h"
//
// paging_emulator.c
//
//
// Created by Jianwei Liao on 11/30/12.
// Copyright (c) 2012 Southwest University. All rights reserved.
//
#include <stdlib.h>
#include <stdio.h>
#include <process.h>
#define TRUE 1
#define FALSE 0
#define INVALID -1
#define INSTRUCT_CNT 320 /* length of instruction stream */
#define VIRTUAL_PAGE_LEN 32 /* length of virtual page */
typedef struct {
int pn, /* page number */
pfn; /* page frame number */
}page_struct_type;
page_struct_type page_array[VIRTUAL_PAGE_LEN]; /* page struct array */
struct pf_ctl_struct { /* page frame control struct */
int pn, /* page number */
pfn; /* page frame number */
struct pf_ctl_struct *next; /* to next */
};
/* used for paging replacement, such as free page frame list or busy page frame list */
typedef struct pf_ctl_struct pf_ctl_t;
pf_ctl_t pfc[VIRTUAL_PAGE_LEN],
*freepf_head, /* head of free page frame list */
*busypf_head, /* head of busy page frame list */
*busypf_tail; /* tail of busy page frame list */
int page_fault_cnt; /* number of page fault */
int a[INSTRUCT_CNT]; /* the instruction list, which contains the logical address */
int page[INSTRUCT_CNT]; /* page number, the instruction<> */
void initialize(int a);
void FIFO(int b);
int main() {
/* generate the instruction stream randomly */
int S, i;
srand(10 * getpid());
S = (float)((INSTRUCT_CNT - 1)*rand() / (RAND_MAX + 1.0)); //FLOAT
printf("%2d RAND_MAX\n", RAND_MAX);
for (i = 0; i<INSTRUCT_CNT; i += 4) {
a[i] = S;
a[i + 1] = a[i] + 1;
a[i + 2] = (float)a[i] * rand() / RAND_MAX;
a[i + 3] = a[i + 2] + 1;
S = (float)rand()*(INSTRUCT_CNT - 2 - a[i + 2]) / RAND_MAX + a[i + 2] + 2;
//printf("%d ", a[i]);
}
/* change the instruction sequence to page address stream */
printf("\n页面访问序列:\n\n");
for (i = 0; i<INSTRUCT_CNT; i++)
{
page[i] = a[i] / 10;printf("%d\t", page[i]);
}
/* use memory page frames from 4 pages to 32 pages */
printf("\n\n采用的是FIFO页面置换算法:\n\n");
printf(" 可用页框数量 缺页次数 命中率\n");
printf(" ----------------------------------\n");
for(i = 4;i <= 32; i++) {
FIFO(i);
printf("%2d page frames %3d %f", i,page_fault_cnt,1-(float)(page_fault_cnt)/320);
printf("\n");
}
return 0;
}
void FIFO(int total_page_frame) /*FIFO ALGORITHM*/
{
int i;
pf_ctl_t *p;
page_fault_cnt = 0;
/* initialize the associated page control struct */
initialize(total_page_frame);
/* busy page frame head, busy page frame tail */
busypf_head = busypf_tail = NULL;
p = busypf_head;//保存busypf头结点,用p来代替busypf_head
int sum = 0;//记录已经用了多少页框
for (i = 0; i < INSTRUCT_CNT;i++)
{
if (page_array[page[i]].pfn == INVALID &&sum<total_page_frame) //如果当前页不在内存,还有空闲页框,就调入
{
page_fault_cnt += 1; //缺页数加1
sum++; //所用页框数加1
page_array[page[i]].pfn = 1; //标记当前页在内存
freepf_head->pn = page[i]; //freepf挂上当前页
if (busypf_head == NULL) //因为要构造一个busypf链表,如果busypf没有结点,就要将head指针指向一个结点
{
p = busypf_head = busypf_tail = freepf_head;
freepf_head = freepf_head->next; //freepf指针指向下一个结点
}
else //如果busypf链表已经有结点,busypf直接挂起freepf_head指向的结点
{
p->next = freepf_head; //用p指针代替busypf_head
p = p->next;
busypf_tail->next = freepf_head;
busypf_tail = busypf_tail->next;
freepf_head = freepf_head->next;
}
}
else if (page_array[page[i]].pfn == INVALID && sum>=total_page_frame) //如果当前页不在内存,没有空闲页框,就置换
{
page_fault_cnt++; //缺页数加1
sum++; //所用页框数加1
page_array[busypf_head->pn].pfn = INVALID; //将最先进来的页面的页框标记为INVALID
page_array[page[i]].pfn = 1; //将置换进内存的页面标记为在内存中
busypf_head->pn = page[i]; //下面4步将busypf做成了一个循环链表,置换的过程就是修改结点信息的过程
busypf_tail->next=busypf_head;
busypf_tail = busypf_tail->next;
busypf_head = busypf_head->next;
}
}
}
/* initialize the associated page control struct */
void initialize(int total_page_frame)
{
int i;
page_fault_cnt = 0;
for (i = 0; i<32; i++) {
page_array[i].pn = i;
/* INVALID shows the page is not in the memory */
page_array[i].pfn = INVALID;
}
for (i = 1; i<total_page_frame; i++) {
/* set link between pfc[i-1] and pfc[i] */
pfc[i - 1].next = &pfc[i];
pfc[i - 1].pfn = i - 1;
}
/* page frame control */
pfc[total_page_frame - 1].next = NULL;
pfc[total_page_frame - 1].pfn = total_page_frame - 1;
/* the head pointer of free page array is pfc[0] */
freepf_head = &pfc[0];
}