您的位置:首页 > 其它

页面置换算法 FIFO和LRU 及各自的命中率

2016-12-16 11:30 141 查看
(1) 先进先出算法FIFO:该算法的实质是选择作业中在主存驻留时间最长的一页淘汰,这种算法容易实现,例如分配一个作业的存储块数为m,则只需建立一张m个元素的队列表Q(0)、Q(1)、…、Q(m-1)和一个替换指针。这个队列是按页调入主存的一页。如图4-1所示,某时刻调入主存四个块,(即m=4),它们按页进入主存的先后顺序为4、5、1、2,当需要置换时,总是淘汰替换指针所指向的那一页, 新调进的页面装入主存后,修改相应的队列元素,然后将替换指针往前移动,使其指向当前最老的一页。

(2) 最近最少使用页面淘汰算法(LRU):这是一种经常使用的方法,有多种不同的实施方案。这里采用不断调整页表链的方法,即总是淘汰页表链链首的页面,而把新访问的页面插入链尾。如果当前调用页面已在页表内,则把它再次调整到链尾。这样就能保证最近使用的页面总处于靠近链尾部分,而不常使用的页面被移到链首,逐个被淘汰。

#include<stdio.h>
#define N 100
#define M 12//作业数
#define ASSIGN 4//存储块数
//请求式分页存储算法
//队列
typedef struct Queue{
int Q
;//存储页面
int front,rear;//队头和队尾
}Queue;
//链表
typedef struct AdjList{
int data;
struct AdjList *next;
}AdjList;
//初始化队列
void InitQueue(Queue *Q){
Q->front=-1;
Q->rear=0;
}
//加入队列
void EnterQueue(Queue *Q,int n){
if(Q->front>=Q->rear){
printf("插入失败\n");
}else{
Q->front++;
Q->Q[Q->front]=n;
Q->rear++;
}
}
//出队
void OutQueue(Queue *Q){
if(Q->front<0){
printf("queue is empty\n");
}else{
Q->front--;
Q->rear--;
}
}
//在队列中查找
int CheckQueue(Queue *Q,int n){
int i;
if(Q->front<0){
//printf("queue is empty\n");
}else{
for(i=0;i<Q->rear;i++){
if(n==Q->Q[i]){
return 1;
}
}
}
return 0;
}
//打印队列
void PrintQueue(Queue *Q){
int i;
if(Q->front<0){
//printf("queue is empty\n");
}else{
printf("打印队列:");
for(i=0;i<Q->rear;i++){
printf("%d ",Q->Q[i]);
}
printf("\n");
}
}
//先进先出并算命中率
void FIFO(int A[]){
int i,num=0,k=0;
Queue *Q=(Queue *)malloc(sizeof(Queue));
InitQueue(Q);
for(i=0;i<M;i++){
if(CheckQueue(Q,A[i])==1){
num++;
}else{
if(k<ASSIGN){
EnterQueue(Q,A[i]);
}else{
OutQueue(Q);
EnterQueue(Q,A[i]);
}
k++;
}
PrintQueue(Q);
}
printf("FIFO的命中率为%f\n",(float)num/M);
}
//插入链表 头插法,链尾为队首(逻辑上)
void AddTail(AdjList *L,int n){
if(L!=NULL){
AdjList *p=(AdjList *)malloc(sizeof(AdjList));
p->next=L->next;
p->data=n;
L->next=p;

}else{
printf("链表为空\n");
}
}
//删除链首
void deleteTail(AdjList *L){
if(L!=NULL){
AdjList *p=L;
while(p->next->next!=NULL){
p=p->next;
}
p->next=NULL;
}else{
printf("链表为空\n");
}
}
//查找n,若在,则调整到队尾
int CheckChangeTail(AdjList *L,int n){
if(L!=NULL){
AdjList *p=L;
while(p->next!=NULL){
//printf("链表为空\n");
if(p->next->data==n){
p->next=p->next->next;
AddTail(L,n);
return 1;
}
p=p->next;
}
return 0;
}
}
//打印链表、
void printTail(AdjList *L){
if(L!=NULL){
AdjList *p=L->next;
printf("打印链表:");
while(p!=NULL){
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
}
//最近最少使用页面淘汰算法
void LRU(int A[]){
int i,num=0,k=0;
AdjList *L=(AdjList *)malloc(sizeof(AdjList));
L->next=NULL;
for(i=0;i<M;i++){
//printf("链表为空\n");
if(CheckChangeTail(L,A[i])==1){
num++;
}else{
if(k<ASSIGN){
AddTail(L,A[i]);
}else{
deleteTail(L);
AddTail(L,A[i]);
}
k++;
}
printTail(L);
}
printf("LRU的命中率为%f\n",(float)num/M);
}
int main(){
int i,A
;
for(i=0;i<M;i++){//随机产生个M个进程作业数,没次调用的页面在1-8之间
A[i]=rand()%8+1;
printf("%d ",A[i]);
}
printf("\n");
FIFO(A);
LRU(A);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: