Search
💾

[OS] Virtual Memory 2

contents

들어가며

저번 시간에는 가상 메모리 시스템에서 어떤 페이지가 쫓겨나야 할 때 어떤 페이지를 쫓아낼 지 결정하는 Replacement algorithm에 대해 배웠습니다.
Replacement algorithm은 가상 메모리 시스템에서만 사용하는 것이 아니고 캐슁 환경같은 다양한 환경에서도 사용합니다.

다양한 캐싱 환경

캐싱(Caching)

한정되고 빠르게 접근할 수 있는 공간(캐시)에 요청된 데이터를 저장해두면 똑같은 데이터에 대한 요청이 왔을 때 느린 저장 장치까지 가지 않고 캐시로부터 받아서 사용할 수 있는 방식
가상 메모리(페이징 시스템)에는
한정된 공간(캐시) - 물리적인(메인) 메모리
느린 저장 장치 - 패킹 스토어(Swap Area)
  요청된 데이터가 물리적인 메모리에 있다면 물리적인 메모리로부터 직접 서비스를 하고 없다면 Page fault가 났을 때만 패킹 스토어에서 물리적인 메모리로 데이터를 읽어옵니다.
Paging system 외에 사용하는 방식
Cache memory
CPU하고 메인 메모리 사이에는 캐시 메모리라는 빠른 계층이 존재합니다. CPU에서 메모리에 접근할 때 직접 접근하는 것이 아니고 메인 메모리에 접근하기 전에 요청한 내용이 캐시 메모리에 있는지 먼저 확인을 한 후에 없는 경우에 메인 메모리에 요청합니다.
우리가 전에 배웠던 TLB(Translation Lookaside Buffer)도 주소 변환을 위한 특유의 cache입니다. 주소 변환 뿐만 아니라 일반적인 메모리 참조에서도 cache memory가 사용되고 있습니다.
Buffer caching
파일 시스템에 대한 read, write 요청을 메모리에서 빠르게 서비스하는 방식입니다.
버퍼 캐싱과 페이징 시스템의 매체는 빠른 공간 - 메인 메모리, 느린 공간 - 디스크로 동일합니다.
Paging system - Swap area
Buffer caching - File system
Web caching
웹 페이지에 대한 요청을 하면 웹 서버에서 해당 페이지를 가져와서 웹 브라우저에 표시해주는데 동일한 URL에 대해서 잠시 뒤 요청을 다시 한다면 멀리있는 웹 서버에서 해당 내용을 읽어오는데 시간이 걸리기 때문에 읽어온 웹 페이지를 저장해뒀다가 보여주는 캐싱 시스템입니다.
Cache memory, Buffer caching단일 시스템에서 저장 매체 간의 속도 차이가 나서 저장을 하는 경우이고, Web caching시스템이 다른 상황에서 지리적으로 멀리 떨어져 있기 때문에 저장을 하는 경우입니다.

캐시 운영의 시간 제약

replacement algorithm에는 시간 제약 조건이 있기 때문에 삭제 항목을 결정하는 일에 지나치게 많은 시간을 소비할 수 없습니다.
  O(n)의 시간 복잡도는 오버헤드가 크기 때문에 실제 시스템에서는 사용할 수 없습니다.
  대부분의 캐싱 환경에서는 O(1), O(log n)까지 허용해줍니다.
LRU, LFU도 이러한 시간 제약 조건을 만족합니다.
[ 캐싱 환경의 경우 ]
LRU
참조된 시간 순으로 줄세우기 진행
새로운 페이지가 메모리에 들어오면 맨 아랫쪽으로 추가
아래에 있을 수록 최근에 참조된 것
쫓아내야 하는 경우에 가장 위에 있는 걸 쫓아냄
메모리 안에서 어떤 페이지가 다시 참조되면 해당 노드를 빼서 가장 아래 부분으로 추가
n개가 있다고 할 때 비교할 필요가 없음. 항상 맨 위에 있는 노드를 쫓아내기 때문에.
LFU
참조된 횟수로 줄 세우기 진행
위로 갈 수록 참조 횟수가 적고 아래면 참조 횟수 많음
쫓아내야 하는 경우에 가장 위에 있는 걸 쫓아냄
어떤 페이지가 참조됐을 때 참조 횟수에 1를 더하는데 해당 값이 가장 참조 횟수가 많은 건 아니기 때문에 비교를 통해서 위치를 찾아야 함(LRU와의 차이)
한 칸씩 내려가면서 비교를 진행해야 함 → 최악의 경우에는 O(n)의 시간 복잡도가 걸림.
  heap이라는 데이터 구조를 사용해서 문제를 해결
노드를 한 줄로 줄 세우지 않고 트리 형태로 구성해서 항상 부모보다 자식의 참조 횟수가 많도록 구성(MinHeap)
쫓아낼 때 root에 있는 페이지를 쫓아내면 됨
heap을 재구성하는 오버헤드가 O(log n)
다시 참조되었을 때 일일이 다 비교하지 않고 직계 자손 경로만 따라내려가면 되기 때문에 자식하고만 비교를 진행하면 됨
참조 횟수가 1 늘어날 경우, 자식 중에 부모보다 작은 자식이 있다면 자리를 바꿈(반복)
효율적으로 사용 가능
[ 페이징 시스템의 경우 ]
  페이징 시스템에서는 엄청난 제약 조건이 존재합니다.
>> LRU, LFU 사용 가능한가요?
진행 순서
1. Process A가 CPU를 잡고 실행 중이라고 합시다.
2. Process A의 논리적인 메모리에서 매 순간마다 Instruction를 하나씩 읽어와서 실행 중입니다.
3. CPU에서 Process A에 대한 논리 주소(p)를 주는데 이걸 Page table를 통해서 물리적인 메모리 주소로 변환해서 CPU로 읽어들입니다.
4. 주소 변환을 했는데 해당 페이지가 이미 물리적인 메모리에 있다면 물리적인 메모리에서 데이터를 읽어서 CPU로 가져갑니다.(OS가 하는 일 없음)   주소 변환은 하드웨어적으로 발생하는 일
5. Process A가 CPU에서 실행하면서 주소 변환을 시도했는데 물리적인 메모리에 없었다면 Page fault가 발생합니다.   디스크 접근 필요, I/O 필요 → OS의 도움 필요
5-1. Process A가 직접 디스크에서 읽어올 수 없기 때문에 Trap이 발생하고 CPU 제어권이 A로부터 OS로 넘어갑니다.
5-2. OS가 디스크에 있는 페이지를 읽어서 물리적인 메모리에 올려두고 그 과정에서 필요하다면 Replacement를 해야 합니다.
5-3. OS가 어떤 걸 쫓아낼 지 찾을 때 LRU 알고리즘을 쓴다면 가장 오래된 페이지를 찾아서 쫓아낼 수 있을까요? LFU를 쓴다면 가장 참조 횟수가 적은 페이지를 알 수 있을까요? 아니오!
LRU, LFU를 가상 메모리 시스템에서는 사용할 수 없습니다!
왜냐면?
이 프로세스가 요청한 페이지가 메모리에 올라가 있는 경우에는 OS에게 CPU가 넘어가지 않습니다. 주소 변환은 하드웨어적으로 발생하는 일이기 때문에 OS는 모르는 일입니다.
Page fault가 발생하면(CPU제어권이 OS에게 넘어가면) 메모리에 올라온 시간을 알 수 있습니다. OS에게 주어진 정보가 반쪽짜리 정보라는 것이죠.
메모리에 그 페이지가 있으면 OS가 알 수 없는 정보고, page fault가 나면 운영권이 OS에게 와서 그 페이지가 언제 메모리에 올라갔는지 정보가 주어지게 됩니다.
그렇다면 페이징 시스템에서는 쫓아낼 페이지를 결정하기 위해 어떤 알고리즘을 사용할까요?

Clock Algorithm

LRU 알고리즘을 근사 시킨 알고리즘으로 Second chance algorithm, NUR, NRU라고 불립니다.
가상 메모리, 페이징 시스템에서 일반적으로 사용하는 방식
NRU(Not Recently Used)
오래된 페이지는 알 수 없지만 최근에 사용되지 않은 페이지는 알 수 있기 때문에 이 방식으로 페이지를 쫓아냄
Clock?
동그랗게 그려두고 시계 바늘이 움직이는 것처럼 알고리즘을 운영하는 형태라서 Clock 알고리즘이라고 부름 → circular linked list 사용
각각 사각형이 페이지 프레임(물리적 메모리 안의 페이지)
Reference bit
이미 메모리에 있는 페이지에 대해서 해당 페이지가 참조가 되면 CPU로 읽어들이면서 Reference bit를 1로 세팅해줍니다.
주소 변환을 해주는 하드웨어가 어떤 페이지에 접근해서 주소 변환을 한 후에 CPU가 그 페이지를 사용하게 되면 참조가 되었다고 판단해서 페이지에 있는 Reference bit를 1로 설정
페이지의 reference bit를 1로 세팅해서 페이지가 참조되었다고 알려주는 역할(하드웨어가 세팅)
  Page fault가 나서 페이지를 쫓아내야 할 경우 하드웨어가 세팅해둔 reference bit를 참조하게 됩니다.
참조 비트가 1인 경우 : 최근에 한 번 참조가 되었구나라고 확인하고 해당 비트를 0으로 변경 참조 비트가 0인 경우 : 해당 페이지를 쫓아냄
Plain Text
복사
운영 방식
1. OS가 시계 방향으로 돌면서 참조 비트가 1이면 참조를 확인하고 해당 비트를 0으로 변경하면서 지나갑니다.
2-1. 참조 비트가 0이라는 건 시계가 한 바퀴 돌 동안에 이 페이지에 대한 참조가 없었다는 것이기 때문에 해당 페이지를 쫓아냅니다.
2-2. 참조 비트가 1이라는 건 도는 동안에 적어도 1번의 참조는 있었다고 생각해서 넘어갑니다.
참조 비트가 0인 걸 쫓아내기 때문에 가장 오래된 페이지를 쫓아내는 건 아닙니다.
Modified bit(dirty bit)
메모리의 페이지가 참조될 때 read로도 참조될 수 있지만 write로도 참조가 될 수 있는데 이 때 Modified bit를 1로 하드웨어가 변경
어떤 페이지가 쫓겨날 때 Modified bit가 0이라고 하면 이 페이지가 패킹 스토어에서 물리적인 메모리로 올라온 이후에 write가 발생하지 않은 것으로 볼 수 있음. 이런 페이지는 패킹 스토어에 이미 동일한 카피가 존재하기 때문에 그냥 쫓아냄.
어떤 페이지가 쫓겨날 때 Modified bit가 1이라고 하면 메모리에 올라오고 나서 적어도 한 번은 CPU에서 write를 한 것으로 볼 수 있음. 해당 페이지가 쫓겨날 때는 패킹 스토어에 수정된 내용을 반영하고나서 지워야 함.
  Clock 알고리즘을 더 개선해서 사용하기 위해서 Modified bit가 1인걸 쫓아내지 않고 0인걸 우선해서 쫓아낸다면 디스크에 쫓아낸 페이지에 대한 변경된 내용을 써줄 필요가 없기 때문에 조금 더 빠르게 사용 가능하다.
추가 내용

Page Frame의 Allocation

알고리즘에는 프로그램 여러개가 물리적인 메모리에 같이 올라가 있습니다. 쫓아낼 때는 어떤 프로세스에 속한 페이지인지와는 무관하게 가장 오래된 페이지를 쫓아냅니다. 실제로 프로그램이 원활하게 실행되기 위해서는 CPU에서 실행이 되면서 page fault가 나지 않는 방향으로 구현이 되어야 합니다.
  그러기 위해서는 일련의 페이지들이 메모리에 같이 올라와 있어야 효율적입니다.
Allocation Example
Instrucation를 실행하는데 있어서 어떤 for문을 돌고 있다고 가정해봅시다. for문을 구성하는 페이지는 3개입니다.
. 이 프로그램에 3개의 페이지를 주면 for문을 도는 동안에 page fault는 발생하지 않습니다.
for문을 백만번 돈다고 해서 for문을 도는 동안에 page fault가 한 번도 발생하지 않습니다. 왜냐면 for문을 구성하는 페이지와 주어진 페이지가 동일하기 때문입니다.
  이 프로그램에 2개의 페이지를 주면 for문을 도는 동안에 page fault가 발생합니다.
프로그램 별로 최소한의 페이지를 줘야지 page fault가 발생하지 않습니다.
예를 들어서 프로그램이 실행되면서 명령어만 실행되는 게 아니라 데이터를 접근해야하는 경우도 있다고 한다면, 코드에 해당하는 페이지말고 데이터에 해당하는 페이지도 메모리에 같이 올라와 있어야만 page fault가 덜 난다는 것 입니다.
프로그램별로 페이지 할당을 해주지 않으면 메모리에서 특정 프로그램이 페이지 프레임을 장악하는 일이 발생할 수 있습니다.
 : 페이지 요청! 페이지 요청! 페이지 요청! 페이지 요청! 페이지 요청!
→ 서로 다른 페이지를 막 요청하면서 다른 프로그램 페이지는 다 밀어내고 본인 페이지만 올려놓을 수 있습니다.
  이런 문제는 너무 비효율적인 시스템을 발생시킬 수 있기 때문에 각각의 프로그램에게 어느정도의 메모리 페이지를 나누어주는 방식이 나왔습니다.
1.
Equal allocation : 모든 프로세스에게 똑같은 개수의 메모리 페이지 할당
어떤 프로그램은 페이지를 많이 필요로 하고 어떤 페이지는 적게 필요로 하기 때문에 비효율적일 수 있음.
2.
Proportional allocation : 크기에 비례해서 메모리 페이지 할당
같은 프로그램이라고 하더라도 시간에 따라서 필요한 페이지 크기가 다를 수 있음.
3.
Priority allocation : CPU 우선순위가 높은 것에다가 메모리 페이지를 더 많이 할당
  프로그램마다 필요한 페이지를 미리 할당하고 page fault를 줄일 수 있습니다.
*사실은 할당하지 않더라도 LRU, LFU같은 replacement algorithm를 사용하다보면 알아서 어느정도 할당되는 효과가 발생
어떤 프로그램이 메모리를 많이 필요로 하게 되면 그 프로그램의 메모리가 그 순간에는 메모리에 많이 올라오게 되고 다른 프로그램의 페이지는 쫓겨나게 됩니다. 그랬다가 다른 프로그램이 메모리를 많이 필요로 하는 순간 또 다른 프로그램 페이지를 쫓아내고 올라가게 됩니다. 이런 식으로 굳이 미리 할당하지 않더라도 Global replacement를 사용해서 문제를 해결할 수도 있습니다.

Global vs. Local Replacement

미리 할당하는 방법을 사용하지 않고 프로세스 별로 원하는 때마다 메모리 할당량을 자동으로 조절해서 사용하는 방식
LRU, LFU같은 방식은 프로그램에게 페이지를 할당하는 효과는 없습니다. Working set, PFF는 프로그램이 최소로 필요로 하는 페이지를 동시에 메모리에 올려놓는 할당 효과가 있는 알고리즘입니다.
Global replacement
replace 시 다른 프로세스에 할당된 프레임을 빼앗아 올 수 있음.(다른 프로그램 페이지 쫓아내기 가능)
Working set, PFF 알고리즘 사용
FIFO, LRU, LFU 등의 알고리즘을 global replacement로 사용시 해당
Local replacement
새로운 페이지를 올려두기 위해서 자신에게 할당된 페이지를 쫓아내는 방식
FIFO, LRU, LFU 등의 알고리즘을 process 별로 운영

Thrashing

프로그램에게 메모리가 너무 적게 할당돼서 지나치게 page fault가 전체적으로 아주 많이 일어나는 현상 프로세스의 원활한 수행에 필요한 최소한의 page frame 수를 할당 받지 못한 경우 발생
Thrashing Diagram를 통해서 어떤 식으로 발생하는지 알아보자.
X축 : 지금 메모리에 올라온 프로그램의 갯수(MPD)
Y축 : CPU 이용률
→ 메모리에 동시에 올라간 프로그램의 수가 올라감에 따라서 CPU 이용률이 어떻게 되는가?
시점
CPU 이용률
이유
초반
낮다
처음에는 프로그램 하나만 메모리에 올라가 있기 때문에 CPU 이용률이 낮다. 해당 프로세스가 메모리만 쓰는 게 아니고 I/O가 일어나면 I/O를 하러가기 때문에 그 사이에 CPU가 놀게 된다.
중반
높다
메모리에 프로그램을 더 올리면 하나가 I/O를 하러 간 사이에 다른 프로그램을 돌리기 때문에 놀지 않고 일하는 시간이 증가한다. ex) 10개의 프로그램 중 9개가 I/O를 하러 가더라도 레디큐에 당장 CPU만 주면 실행이 가능한 프로그램이 있기 때문에 MPD를 늘려주면 CPU 이용률이 올라간다.
후반
낮다
이용률이 뚝 떨어지고 Thrashing 발생!!!
왜 발생했는가?
프로세스한테 페이지를 너무 적게 할당하면 page fault가 빈번히 발생합니다. page fault가 빈번히 발생하다보면 이용률이 낮아지게 됩니다. 한 번 CPU가 명령어를 실행하려고 하면 그 페이지가 메모리에 없어서 디스크에서 페이지를 가져오기 위해서 I/O를 해야하기 때문에 CPU가 계속 쉬게 됩니다.
  MPD가 올라가서 각 프로그램마다 메모리 할당량이 적어지기 때문에 어떤 프로그램이든 CPU를 잡더라도 page fault가 발생하게 됩니다. 이는 곧 CPU 이용률을 낮춥니다.
OS는 MPD가 낮은걸보면 프로그램을 더 메모리에 올려야 겠다고 판단합니다.
MPD가 더 높아지고 각 프로세스가 가진 메모리 용량을 더 적어져서 page fault가 더 자주 발생하게 됩니다. 메모리에서 페이지를 쫓아내고 메모리에 페이지를 올리고 하는 작업을 하느라 시간이 다 가고 CPU는 한가해집니다. 비효율적인 시스템이 되는거죠.
이걸 막기 위해서는 MPD의 갯수를 조절해야 합니다.
갯수를 조절하면서 프로그램이 어느 정도 메모리 확보를 가능하게 해줘야 합니다. 이 역할을 해주는 것이 Working-set, PFF 알고리즘 입니다.

Working-Set Model

특정 순간에 메모리에 꼭 올라와 있어야만 하는 빈번히 참조되는 페이지 집합(워킹셋)이 그 순간에 메모리에 올라와 있는 걸 보장해주는 기법
적어도 프로그램들이 메모리에서 원활하게 실행이 되려면 어느 정도의 메모리 페이지를 가지고 있어야 합니다.
 : 프로그램들이 특정 시간에 특정 메모리 위치만을 참조하고 있잖아?
Locality of reference
프로그램이 특정 시간에는 특정 메모리 위치만 참조하는 특징을 가지고 있다는 것
For loop Example
for문이 실행된다고 하면 루프를 도는 동안에는 그 루프를 구성하는 페이지만 집중적으로 참조가 됩니다.
1.
루프를 구성하는 페이지만 집중 참조(다른 페이지 참조 X)
2.
프로그램이 실행되면 함수 구조로 실행
3.
그 함수를 구성하는 페이지만 집중 참조
4.
그 함수가 리턴되어서 다른 함수가 실행
5.
다른 함수를 구성하는 페이지만 집중 참조
…(반복)
  Locality of reference가 바뀜.
특정 시간에 집중적으로 참조되는 페이지 집합을 Locality set이라고 하고, Working-set algorithm에서는 Working set이라고 합니다.
Working set : 프로그램이 실행되면서 그 순간에 메모리에 꼭 올라와 있어야만 하는 빈번히 참조되는 페이지의 집합
  워킹셋은 메모리에 한꺼번에 올라와 있도록 보장해주는 기법이 있어야지만 page fault가 나지 않습니다.
MPD가 너무 높아지면 워킹셋을 메모리에 보장할 수 없게 됩니다.
워킹 셋은 페이지 5개로 구성되는데 메모리는 3개밖에 보장해줄 수 없는 상황이 발생했습니다.
워킹 셋 :     
메모리 :   
어떻게 해야할까요?
  : 구차하게 3개를 받아요.
  : 모든 페이지를 통째로 반납해요. 5개를 위한 자리를 줄 때까지 하나도 받지 않아요! 전체를 다 반납하고 해당 프로세스는 디스크로 swap out! 그리고 프로세스는 suspended 상태로 들어가요.
Working set모델은 MPD를 조절해서 워킹 셋이 한꺼번에 메모리에 올라가는 것이 보장이 안된다면 그 프로세스의 메모리를 통째로 빼앗는 방식으로 thrashing을 방지하고 MPD를 조절합니다.
알고리즘 동작 과정
우리는 워킹셋을 미리 알 수 없습니다. 메모리에 올라가 있으면 좋은 페이지 집합을 알면 그걸 올려다두면 되겠지만 정확하게 모르기 때문에 과거를 통해서 워킹셋을 추정합니다.
프로그램이 과거 델타시간동안 참조한 페이지를 워킹셋으로 간주해서 과거 델타시간동안 참조된 페이지는 메모리에서 쫓아내지 않고 유지
*델타 시간은 윈도우라고 합니다.
t1이 현재 시간이라고 하면 윈도우 사이즈(10)만큼을 이 프로그램의 워킹셋이라고 가정하고 메모리에 올려둡니다.
→ 과거 10개의 참조된 페이지들을 봤더니 동일한 페이지가 반복 참조된 것도 있고 그렇다.
  서로 다른 페이지들을 다 나열해보면 5개 페이지 { 1, 2, 5, 6, 7 }이 프로그램의 워킹 셋이기 때문에 워킹 셋 알고리즘은 5개의 페이지 프레임을 줄 수 있으며 만약 부족해서 5개를 못 주게 되면 전부 Swap out시키고 suspended 상태로 변경됩니다.
워킹 셋은 그때 그때 바뀌며, 윈도우 틀을 이동시키면 시점에 따라서 다르게 나타납니다.
만약 다른 시점에서는 2개 페이지 { 3, 4 }가 나왔다면 2개의 페이지만 할당하면 워킹 셋을 만족시킬 수 있습니다.
 : 델타 시간동안 유지하다가 버리는 것과 동일한 거 아닌가요?
  : 델타 시간을 유지하다가 시간이 지나면 버리는 것과 동일하며 다시 참조되면 다시 그 시점부터 델타 시간을 유지하다가 시간이 지나면 버립니다.
  적어도 메모리에 남아있는 프로그램이라도 워킹 셋을 보장받게 해주며 MPD를 조절하면서 워킹 셋을 보장합니다.

PFF

MPD를 조절하면서 Thrashing를 방지하는 방법 워킹 셋처럼 추정하는 방식이 아니고 직접 page fault가 있는 지 보는 방식
현재 시점에 이 시스템에서 page fault가 얼마나 나는지 보고 또 특정 프로그램이 page fault를 얼마나 내는지 보는 방식입니다.
프로그램  : page fault!!! page fault!!! page fault!!! page fault!!! page fault!!!
  : 저 프로그램의 워킹 셋이 메모리에 다 보장이 안되어 있는 상태구나? 페이지를 더 줘야 겠다!
프로그램에 할당되는 메모리 크기가 커지게 되면 page fault 발생 비율을 줄어듭니다.
프로그램 상태에 따라서 기울기의 가파른 정도는 다릅니다.
page fault가 일정 수준 이상으로 발생하고 있다고 하면 워킹 셋이 보장이 안된 것으로 간주해서 프로그램에게 페이지 수를 늘려줍니다. page fault는 줄고 발생 빈도가 어느 정도 이내로 들어오게 됩니다.
어떤 프로그램이 page fault를 너무 발생시키지 않으면 페이지가 메모리를 많이 가지고 있다고 간주해서 메모리를 빼앗아서 일정수준의 page fault를 유지하게 합니다.
만약 page fault 비율이 빈번하고 메모리를 더 줘야 하는데 줄 메모리가 없다면 그 프로그램을 통째로 Swap out 시켜서 메모리에 남아있는 프로그램이라도 page fault를 줄여서 thrashing를 방지합니다.
  Global replacement - 미리 할당을 하지 않더라도 알고리즘이 마치 할당을 한 것 같은 효과를 내면서 운영이 되는 알고리즘들
추가 내용

Page Size의 결정

페이징 시스템
동일한 크기의 페이지 단위로 물리적인 메모리의 프레임을 자르고 가상 메모리의 프로그램을 구성하는 페이지 주소 공간도 페이지 단위로 자릅니다. 페이지 사이즈는 보통 4KB를 사용하는데 메모리 공간이 32bit 주소 체계에서 64bit로 크기가 커지면서 페이지 크기도 커져야 합니다. 페이지 크기가 너무 작으면 페이지 테이블이 커져야 합니다.
페이지 사이즈를 줄이면 똑같은 크기의 메모리에서 더 잘게 썰기 때문에 페이지 개수가 증가하게 되고 테이블 엔트리 수가 더 많이 필요하기 때문에 페이지 테이블을 위한 메모리 낭비가 심해지게 됩니다.
→ 페이지 안에서 사용이 안되는 부분이 생길 수 있는데 그 부분은 줄어듭니다. 잘게 사용하기 때문에 효율적인 부분이 생깁니다. 특히 꼭 필요한 정보만 메모리에 올라오기 때문에 메모리 이용이 더 효율적입니다.
페이지 크기가 크면 페이지 안에서 아주 작은 부분만 필요한데 page fault가 났을 때 큰 페이지를 통째로 메모리에 올려야 하기 때문에 꼭 필요한 것만 올라오지 않을 수가 있습니다.
→ Locality 활용 측면에서는 페이지 크기가 큰 게 좋습니다. 프로그램이라는 게 locality라는 게 있고 함수가 실행되면 그 함수를 구성하는 코드들이 순차적으로 참조가 됩니다. 그렇기 때문에 page fault가 났을 때 페이지 하나를 통째로 올려놓으면 처음에는 page fault가 났지만 아랫쪽에 있는 메모리 위치들은 메모리에 올라온 이후로 page fault를 내지 않고 참조하기 때문에 더 효율적인 측면이 있습니다.
disk transfer의 효율성
페이지 크기가 클수록 좋아집니다.
디스크라는 건 seek를 해야합니다. 디스크 원판이 회전하면서 디스크 헤드가 이동을 하고 특정 위치 섹터를 읽거나 써야 하는데 사실 seek하는 시간이 대단히 오래 걸립니다. 따라서 가능하면 한 번 디스크 헤드가 이동해서 많은 양의 뭉치를 읽어서 메모리에 올리는 것이 좋기 때문에 페이지 크기가 큰 게 좋습니다. 작으면 계속 page fault가 나고 디스크 헤드가 움직여야 하는 seek 시간이 길어져서 비효율적입니다.
요즘은 페이지 크기를 점점 더 키워주는 추세입니다.
적정 페이지 크기