【操作系统】编程模拟FIFO,LRU,NUR,OPT页面置换算法

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define random(x) (rand()%x)

#define LOG     1        //1-show log    2-no show
#define TYPE 10     //page types
#define NUM 20         //page nums
#define SIZE 5        //cache size

struct page{
    int id;//page id
    int time=0;//different meaning in different algorithm
};
struct page pageList[NUM],cache[SIZE];//page needs,page cache

void init(){//random data init
    printf("PageList:\n");
    srand((unsigned)time(NULL));
    for(int i=0;i<NUM;i++)
        printf("%d ",pageList[i].id=random(TYPE));
    printf("\n");
}

void cacheClear(){//clear the cache
    for(int i=0;i<SIZE;i++){
        cache[i].id=-1;
        cache[i].time=0;    
    }
}

int cacheHit(int i){//find cache hit or not
    for(int j=0;j<SIZE;j++)
        if(cache[j].id==pageList[i].id){
            if(LOG) 
                printf(" hit ");
            return j;
        }
    if(LOG) 
        printf("     ");
    return -1;
}

int cacheRoom(){//find cache have free room or not
    for(int i=0;i<SIZE;i++)
        if(cache[i].id==-1)
            return i;
    return -1;
}

void cacheShow(){//show the cache pages
    if(LOG) {
        printf("cache: ");
        for(int i=0;i<SIZE;i++)
            if(cache[i].id==-1){
                printf("N\t");                
            }else
                printf("%d\t",cache[i].id);
        printf("\n");
    } 
}

void cacheTimeAdd(){//add the pages time in cache
    for(int i=0;i<SIZE;i++)
        cache[i].time++;
}

int FIFOfun(){//FIFO replace
    int maxtime=cache[0].time,t=0;
    for(int i=1;i<SIZE;i++)
        if(maxtime<cache[i].time){
            maxtime=cache[i].time;
            t=i;
        }
    return t;
}

double FIFO(){//time in FIFO:live time
    double ret;
    if(LOG) 
        printf("\nFIFO:\n");
    cacheClear();
    int hitsum=0;
    for(int i=0;i<NUM;i++){
        if(LOG) 
            printf("input:%d\t",pageList[i].id);
        int hit=cacheHit(i);
        if(hit==-1){//if not hit
            int room=cacheRoom();
            if(room!=-1)// if have free room
                cache[room]=pageList[i];//use room save page
            else//if have not free room 
                cache[FIFOfun()]=pageList[i];//use FIFO to replace
        }else{//if hit
            hitsum++;    
        }
        cacheShow();
        cacheTimeAdd();
    }
    if(LOG) {
        printf("PageReplacement:%d\n",hitsum);
        printf("PageFault:%d\n",NUM-hitsum);    
    }
    printf("HitRate:%lf\n",ret=(double)hitsum/NUM);
    return ret;
}

double LRU(){//time:from last use to now
    double ret;
    if(LOG)
        printf("\nLRU:\n");
    cacheClear();
    int hitsum=0;
    for(int i=0;i<NUM;i++){
        if(LOG)
            printf("input:%d\t",pageList[i].id);
        int hit=cacheHit(i);
        if(hit==-1){//if not hit
            int room=cacheRoom();
            if(room!=-1)//if have free room
                cache[room]=pageList[i];//use free room to save page
            else//if have not free room
                cache[FIFOfun()]=pageList[i];//use LRU ,because time have different meaning ,function is same as FIFO 
        }else{//if hit 
            hitsum++;
            cache[hit].time=0;//LRU:every hit reflash time 
        }
        cacheShow();
        cacheTimeAdd();
    }
    if(LOG){
        printf("PageReplacement:%d\n",hitsum);
        printf("PageFault:%d\n",NUM-hitsum);    
    }
    printf("HitRate:%lf\n",ret=(double)hitsum/NUM);
    return ret;
}

double NUR(){//time:notuse-0 use-1
    double ret;
    if(LOG)
        printf("\nNUR:\n");
    cacheClear();
    int hitsum=0,clockcur=0;//cur of the cache 
    for(int i=0;i<NUM;i++){
        if(LOG)
            printf("input:%d\t",pageList[i].id);
        int loop=1,ishit=0;
        for(int j=0;j<SIZE;j++){  //first loop to find hit or not
            if(cache[j].id==pageList[i].id){
                clockcur=j;
                cache[clockcur].time=1;
                clockcur=(clockcur+1)%SIZE;
                ishit=1;
                loop=0;// if hit ,there not next loop 
                break;
            }
        }
        while(loop){//next loop to find one to replace
            loop=0;
            if(cache[clockcur].id==-1){ //id==-1,free room,loop end
                cache[clockcur]=pageList[i];
                cache[clockcur].time=1;
            }else if(cache[clockcur].time==0){//time==0,replace,loop end
                cache[clockcur]=pageList[i];
                cache[clockcur].time=1;
            }else{ //time==1,change time to 0,loop continue
                cache[clockcur].time=0;
                loop=1; 
            }
            clockcur=(clockcur+1)%SIZE;
        }
        if(ishit){//show hit
            hitsum++;
            if(LOG)
                printf(" hit ");
        }else{
            if(LOG)
                printf("     ");    
        }
        cacheShow();
    }
    if(LOG){
        printf("PageReplacement:%d\n",hitsum);
        printf("PageFault:%d\n",NUM-hitsum);
    }    
    printf("HitRate:%lf\n",ret=(double)hitsum/NUM);
    return ret;
}

int OPTfun(int i){//OPT replace
    int arr[SIZE];//save cache page next use
    for(int j=0;j<SIZE;j++){
        arr[j]=INT_MAX;
        for(int k=i+1;k<NUM;k++){
            if(cache[j].id==pageList[k].id){
                arr[j]=k;
                break;
            }
        }
    }
    int arrmax=arr[0],t=0;//find the longest next use 
    for(int j=1;j<SIZE;j++){
        if(arr[j]>arrmax){
            arrmax=arr[j];
            t=j;
        }
    }
    return t;
} 

double OPT(){
    double ret;
    if(LOG)
        printf("\nOPT:\n");
    cacheClear();
    int hitsum=0;
    for(int i=0;i<NUM;i++){
        if(LOG)
            printf("input:%d\t",pageList[i].id);
        int hit=cacheHit(i);
        if(hit==-1){//if not hit
            int room=cacheRoom();
            if(room!=-1)//if have free room 
                cache[room]=pageList[i];//use free room to save
            else// not free room 
                cache[OPTfun(i)]=pageList[i];//use OPT replace
        }else{//if hit 
            hitsum++;
        }
        cacheShow();
        cacheTimeAdd();
    }
    if(LOG){
        printf("PageReplacement:%d\n",hitsum);
        printf("PageFault:%d\n",NUM-hitsum);    
    }    
    printf("HitRate:%lf\n",ret=(double)hitsum/NUM);
    return ret;
}

int main(){
    int    alltime=LOG?1:100;
    double arr[4]={0,0,0,0};
    for(int i=0;i<alltime;i++){
        init();
        arr[0]+=FIFO();
        arr[1]+=LRU();
        arr[2]+=NUR();
        arr[3]+=OPT();
    }
    printf("\n");
    printf("FIFO:%lf\n",arr[0]/alltime);
    printf("LRU:%lf\n",arr[1]/alltime);
    printf("NUR:%lf\n",arr[2]/alltime);
    printf("OPT:%lf\n",arr[3]/alltime); 
    return 0;
}

 

上一篇:PHP多进程编程(三) 管道通信2


下一篇:使用FIFO解决设计中数据速率转换的问题