학부시절 운영체제 수업을 들었던 기억이 가물 가물한데,...
LRU 알고리즘이 갑자기 생각나서 수업 자료들을 뒤지는 중 시뮬레이션 소스를 발견하였다.
10년 정도 지나고 나서 보니, 대체 왜 이런식으로 코딩을 했을까 하고 생각도 들긴하지만, 그때 당시 열심히 공부했었구나 싶기도 하다.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 2002년 11월 20일
// 운영체제론 Report #2
// PageFault Simulation.
// Algorithm : FIFO
// Optimal
// LRU
// Compiler : MS Visual C++ 6.0
// Test : Pentium III 866Mhz, 512Mb SDRAM, VIA694 Board
// 실행 시 유의 사항 : 윈도우즈에서 실행 시킬 경우 도스명령창이 뜨는데 그때 그 창의 속성을 너비 84이상으로 할것
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <stdio.h> // 표준 입출력함수를 사용하기 위해서 포함시킴
#include <stdlib.h> // rand()를 사용하기 위해서 포함시킴
#include <time.h> // rand()의 seed를 time을 사용하기 위해서 포함시킴
#include <malloc.h> // 메모리 할당함수인 malloc 함수의 사용을 위해
#define MAX_FRAME 10 // 프레임의 수를 최대 10로 설정
// 페이지가 1~7까지라서 7이면 충분하지만, test를 위해 여유 있게 10으로 함.
#define MAX_REF_SIZE 60 // reference string의 길이를 60으로 한다.
#define default_of_frame 3 //frame의 수를 default 값으로 3으로 한다.
int ref_string[MAX_REF_SIZE]; // reference string의 길이를 60으로 한다.
int frame[MAX_FRAME]={0}; // FIFO와 Optimal 방식에서 사용될 frame 배열(초기화 시킴)
int number_of_frame=0; // 입력 받을 프레임의 수
int cfifo=0; //fifo 방식의 pagefault 발생횟수
int coptimal=0; //optimal 방식의 pagefault 발생횟수
int clru=0; //LRU 방식의 pagefault 발생횟수
typedef struct stack_dlist *stack_ptr; //LRU방식에서 사용될 이중연결 리스트 구조체 선언
typedef struct stack_dlist{
stack_ptr uplink;
stack_ptr downlink;
int data;
};
stack_ptr top=NULL; // 일종의 stack형식이므로 top값을 지정
stack_ptr bottom=NULL; // 접근 편리를 위해 bottom값을 지정(pagefault 때에는 bottom에 있는 값을 victim으로 한다.
void init(); // reference string 만들기, 프레임의 수 입력 받기 ,screen 만들기, 각 함수 호출하기
void fifo(); // fifo replacement 방식을 구현한 함수
void optimal(); // optimal replacement 방식을 구현한 함수
void lru(); // LRU replacement 방식을 구현한 함수
short int pagefault(int); // pagefault를 검사하는 함수
short int lru_pagefault(int); // LRU 방식에서 pagefault 검사하는 함수
int flength(int,int); // optimal 에서 현재위치 i에서 프레임의 각 원소들이 얼마나 멀리 있는지 검사하는 함수
void main(void)
{
init();
}
void init()
{
int number=0; // 프레임의 수를 저장한다.
int i=0; // loop에 사용될 변수
char *cnumber;// frame 의 갯수를 입력받아서 저장할 포인터
cnumber=(char *)malloc(3*sizeof(char)); // 크기를 3으로한다.
printf("Number of Frame (Maximum value is %d, Default value is %d) : ",MAX_FRAME,default_of_frame);
gets(cnumber); // frame의 수를 사용자로부터 입력받아서 number변수에 저장한다.
if(cnumber[0]==NULL) //default값으로 대치한다.
{
number=default_of_frame;
}
else // 문자열을 정수형으로 변환한다.
{
number=atoi(cnumber);
}
if((number > 0) && (number < MAX_FRAME+1))
{
number_of_frame=number;
}
else //범위에 벗어나는 입력이 들어 왔을경우 디폴트 값으로 한다.
{
number_of_frame=default_of_frame;
}
// 화면을 구성한다.
printf("\nNumber of Frame : %d PageFault: F",number_of_frame);
printf("\n┌────┬──────────────────────────────┬───┐");
printf("\n│ Method │Reference String │Counts│");
printf("\n│ │");
srand( (unsigned)time( NULL ) ); // 랜덤하게 Reference String을 만들것이므로 rand()의 seed를 넣어준다.
for(i=0;i<MAX_REF_SIZE;i++) // Reference String의 길이를 MAX_REF_SIZE로 해서 만든다.
{
ref_string[i]=rand()%7+1;
printf("%d",ref_string[i]);
}
printf("│ │");
printf("\n");
printf("├────┼──────────────────────────────┼───┤");
printf("\n");
printf("│FIFO │");
fifo(); // fifo함수 호출
if(cfifo>9) // fifo카운터의 자릿수가 두 자리 일 때
{
printf("│ %d │",cfifo);
}
else // fifo카운터의 자릿수가 한 자리 일 때
{
printf("│ %d │",cfifo);
}
printf("\n");
printf("├────┼──────────────────────────────┼───┤");
printf("\n");
for(i=0;i<MAX_FRAME;i++) // frame을 0으로 초기화 시킨다.(fifo에서 사용했던 프레임의 내용을 제거)
{
frame[i]=0;
}
printf("│Optimal │");
optimal();
if(coptimal>9) // optimal 카운터의 자릿수가 두 자리 일 때
{
printf("│ %d │",coptimal);
}
else // optimal 카운터의 자릿수가 한 자리 일 때
{
printf("│ %d │",coptimal);
}
printf("\n");
printf("├────┼──────────────────────────────┼───┤");
printf("\n");
printf("│LRU │");
lru(); // LRU함수 호출
if(clru>9) // LRU 카운터의 자릿수가 두 자리 일 때
{
printf("│ %d │",clru);
}
else // LRU 카운터의 자릿수가 한 자리 일 때
{
printf("│ %d │",clru);
}
printf("\n└────┴──────────────────────────────┴───┘");
printf("\n");
}
void fifo()
{
int i=0,f=0;
for(i=0;i<MAX_REF_SIZE;i++)
{
if(pagefault(ref_string[i])) // pagefault발생하면
{
cfifo++; // 그 카운터를 증가시키고
frame[f]=ref_string[i]; // replacement한다.
printf("F"); // pagefault가 발생했다는 표시한다.
f=(f+1)%number_of_frame; // frame의 인덱스를 프레임의 수에 맞게 바꾼다.(fifo)
}
else
{
printf(" "); // 아무일도 없다.
}
}
}
void optimal()
{
int i=0,f=0,k=0;
int length[MAX_FRAME]={0}; // 프레임내의 어떤 원소의 위치가 어디 인지를 저장하는 변수
int max=0; // 가장 늦게 나오는 프레임인덱스를 저장하게 된다.
for(i=0;i<MAX_REF_SIZE;i++)
{
max=0;
if(pagefault(ref_string[i])) // pagefault발생하면
{
coptimal++;//카운터 증가
if(frame[f]==-1)//frame에 비어 있는 공간이 있으면 그냥 넣어도 됨,처음에는 프레임이 비어 있음
{
frame[f]=ref_string[i];
f=f+1;
}
else// frame에 빈 공간이 없을때, 프레임에 있는 item들이 다음의 refrence string에서 어디에 위치하는지 알아보고
// 가장 늦게 나오는 item을 replacement한다.
{
for(k=0;k<number_of_frame;k++)// 각 아이템들이 지금 위치에서 얼마나 멀리 떨어져 있는지 검사
{
length[k]=flength(i,k);
}
for(k=0;k<number_of_frame-1;k++)
{
if(length[max]<length[k+1]) // 가장 늦게 나오는 원소를 replacement하기 위해서 골라 낸다.
{
max=k+1;
}
}
frame[max]=ref_string[i]; // replacement
}
printf("F");
}
else
{
printf(" ");
}
}
}
void lru()
{
int i=0,stack_count=0;
for(i=0;i<MAX_REF_SIZE;i++)
{
if(lru_pagefault(ref_string[i])) // pagefault발생하면
{
clru++;// 카운터 증가
if(number_of_frame==1)// 만약에 프레임의 수가 1 이라면
{
stack_ptr temp=(stack_ptr)malloc(sizeof(stack_dlist)); // 임시 노드를 하나 선언한다.
temp->downlink=NULL; // 프레임 노드가 하나만 있으므로 replacement는 그 data만 바꾸면 된다.
temp->uplink=NULL;
temp->data=ref_string[i];
top=temp;
bottom=temp;
}
else if(stack_count<number_of_frame) // 스택이 비어 있다면(프레임에 빈공간이 있다면)
{
stack_ptr temp=(stack_ptr)malloc(sizeof(stack_dlist)); // 임시 노드 선언
stack_count++;// 스택 카운터를 증가시킨다.
temp->downlink=top;// 이중연결 리스트 구조 이므로
temp->uplink=NULL; // 이중연결 리스트 구조 이므로 (리포트에 따로 정리)
if(top) // 노드가 하나라도 존재하면
{
top->uplink=temp; //존재하는 노드의 uplink를 새로운 노드로 포인팅한다.
}
temp->data=ref_string[i];// 데이터 저장
top=temp; // top를 새로운 노드로 한다.
if(!bottom) // 노드의 밑부분의 노드를 bottom으로 한다.
{
bottom=temp;
}
}
else // 프레임에 빈공간이 없을 경우
{
stack_ptr temp=(stack_ptr)malloc(sizeof(stack_dlist));
temp=bottom; // 교과서에 나온대로 제일 밑의 노드를 희생량으로 삼는다.
// 링크의 조정(자료구조 책에 나옴)
temp->uplink->downlink=temp->downlink;
bottom=temp->uplink;
temp->data=ref_string[i];
temp->downlink=top;
temp->uplink=top->uplink;
top->uplink=temp;
top=temp;
}
printf("F");
}
else
{
printf(" ");
}
}
}
short int pagefault(int item)
{
int i=0;
short int flag=1; // pagefault가 발생하면 1
for(i=0;i<number_of_frame;i++)
{
if(frame[i]==item)
flag=0; // 그렇지 않으면 0
}
return flag;
}
int flength(int now,int item_pos) // 현재 위치에서 얼마나 떨어져 있는지 검사
{
int i=0;
i=now+1;
while(i<MAX_REF_SIZE)
{
if(ref_string[i]==frame[item_pos])
{
return i;
}
i++;
}
return MAX_REF_SIZE+1;
}
short int lru_pagefault(int item) // LRU 의 pagefault검사
{
int flag=1;
stack_ptr temp=(stack_ptr)malloc(sizeof(stack_dlist));
stack_ptr position=(stack_ptr)malloc(sizeof(stack_dlist));
position=top;
temp=top;
while(position!=NULL) // 리스트에서 데이터를 찾는 방식과 같음
{
if(position->data==item)// 프레임에 지금 들어온 페이지가 존재하면 그 노드를 top으로하고 링크를 조정한다.
{
temp=position;
flag=0; // pagefault발생 안함
if((temp->uplink)&&(temp->downlink)) // 노드가 리스트의 중간에 있을 경우(top나 bottom이 아닐경우)
{
temp->uplink->downlink=temp->downlink;
temp->downlink->uplink=temp->uplink;
temp->downlink=top;
temp->uplink=top->uplink;
top->uplink=temp;
top=temp;
}
else if(!(temp->downlink)&&temp->uplink) // 노드가 bottom에 있을 경우(노드가 하나만 있다면 안된다)
{
temp->uplink->downlink=temp->downlink;
bottom=temp->uplink;
temp->uplink=top->uplink;
top->uplink=temp;
temp->downlink=top;
top=temp;
}
}
position=position->downlink;//리스트의 처음부터 끝까지 다 스캔해서 페이지를 검색.
}
return flag;
}
'코딩하고 > C,C++' 카테고리의 다른 글
| 큰 정수 계산하기 (0) | 2016.03.27 |
|---|---|
| cocosdx 사용해서 게임 개발하기 -1- (0) | 2012.11.19 |
| 자료구조 - 계산기 만들기 (10) | 2012.10.12 |
| C언어로 만든 객체 (0) | 2012.10.11 |
| 자료구조 - 다항식 연산하기 (2) | 2012.10.10 |