Shine's dev log

가상 메모리 특징들 (Thrashing, buddy system allocator, Slab, prepaging, page pinning) 본문

운영체제

가상 메모리 특징들 (Thrashing, buddy system allocator, Slab, prepaging, page pinning)

dong1 2020. 7. 26. 23:38

앞서 살펴보았던 Virtual memory system은 여러가지 장점들이 있기 때문에 대부분의 OS에서 사용하는 개념이다.

 

이번에는, Virtual memory와 관련된 여러가지 특징들을 살펴보자.

 

 

 

1. address space 와 VM

 

우선 address space는 크게 code, stack, heap, data 영역으로 나눌 수 있다.

 

1) code

 

code 영역은 read-only로 page table에 mapping된다. 또한, sharable 하다는 특징이 있다.

 

디스크로부터 file의 내용이 변화없이 읽어져 와서 따로 변화를 백업해 둘 swap file을 만들지 않아도 되는 놈을 file-backed pages라고 하는데, code 영역이 executable file 형태로 backed 되는 file-backed pages이다. 예를 들어 a.out이라는 executable file이 디스크로부터 메인메모리에 읽어져 오면, 이를 file-backed pages 라고 할 수 있는 것이다. 반대로 디스크의 어디에서 읽어져 온 지 불명확한 놈을 anonymous pages라고 한다.

 

만약 코드를 메인 메모리에서 지우려면, 그냥 삭제해주면 된다.

 

2) stack, heap

 

대표적인 anonymouse pages이다. 보통 zero page에서 시작해서 CoW를 통해 점점 늘어간다.

 

내용이 계속해서 바뀌므로 swap file의 형태로 backed 되어야 한다.

 

3) data

 

data영역은 file형태로 시작해서 만약 수정이 일어나면, CoW를 통해 업데이트한다.

 

내용이 계속해서 바뀌므로 swap file의 형태로 backed 되어야 한다.

 

 

 

2. Frame allocation

 

여러 프로세스들에게 page frame을 나누어주는 방식은 크게 세가지가 있다.

 

1) equal allocation

 

모든 프로세스들에게 같은 양의 page frame을 할당해주는 방법이다.

 

2) proportional allocation

 

동적으로 프로세스의 상황에 맞춰 page frame을 할당해주는 방법이다.

 

3) priority allocation

 

proportional allocation에서 priority 변수를 추가하여 page frame을 할당해주는 방법이다.

 

 

 

3. Thrashing

 

앞서 demand paging이 잘 먹히는 이유는 principle of locality 때문이라고 하였다. 즉 쓰이는 녀석들이 자주 쓰이기 때문에 demand paging의 성능이 잘 나오는 것이다.

 

하지만, 자주 쓰이는 working sets의 크기가 physical memory의 크기보다 크면 어떻게 될까?

 

맞다. 계속해서 page frame들이 swap되면서 성능이 크게 저하될 것인데, 이를 Thrashing이라고 한다. 하드디스크를 쓰는 경우에는 드드드드 소리가 나기도 하는데, 이는 Thrashing이 발생하여 나는 소리이다.

 

이럴 경우, 현질해서 메모리를 추가하거나 프로세스를 줄여주는 것만이 해결책이다.

 

 

 

4. Memory-mapped file

 

memory-mapped file

 

memory-mapped file이란, 위의 그림처럼 메모리를 읽었을 때 디스크의 파일을 읽어올 수 있도록 하는 방식이다.

 

이 방식을 통해 여러 프로세스가 하나의 파일을 공유할 수도 있다.

 

 

 

5. Buddy System Allocator

 

연속된 페이지를 할당하거나 할당을 해제할 때 사용하는 방법이다.

 

buddy-system allocator - allocate

 

위의 그림과 같이 16개의 페이지 시스템에서 연속된 2개의 페이지를 할당하려고 한다.

 

이 때, 그냥 랜덤하게 2개의 페이지를 주는 것이 아니라, 자신의 페이지를 반으로 잘라서 8개의 페이지 두개를 만들고, 또다시 반으로 잘라서 4개의 페이지 두개를 만들고, 또다시 반으로 잘라서 2개의 페이지 두개를 만든다. 이제 2개의 페이지가 만들어졌으므로 이 2개의 페이지를 할당해주면 된다.

 

즉, 원하는 크기의 페이지가 나올 때까지 반으로 자르는 과정을 반복하는 것이다.

 

그리고 반으로 자를 때, 잘려진 두 녀석이 서로의 buddy라고 한다.

 

buddy system allocator - deallocate

 

위의 그림과 같이 할당을 해제할 때는

1) 자신의 buddy가 할당되어 있으면 그냥 혼자 반환하고

2) 자신의 buddy가 할당되어 있지 않으면(free) 자신의 buddy와 합쳐져 하나의 chunk가 된 후 반환한다.

 

즉, 이 buddy system allocator는 오직 2의 지수승 크기의 연속된 페이지만 할당해줄 수 있다. 따라서 만약 54개의 연속된 페이지가 필요하다면 2^6 = 64개의 페이지를 할당받는 식으로 사용해야 한다.

 

 

 

 

6. Slab allocator

 

malloc과 같은 함수를 쓰다보면, 같은 크기의 메모리를 여러개 할당받아야 하는 경우가 자주 생긴다.

 

같은 크기의 오브젝트 여러개를 빠르게 할당할 수 있는 녀석을 Slab이라고 한다. Slab allocator는 특정 크기의 allocation을 빨리 처리할 수 있도록 최적화되어있다.

 

 

 

7. Prepaging

 

demand paging을 할 때 principle of locality가 중요하다고 했다.

 

만약 어떤 page가 fault가 나면, 그 주변에 있는 page도 또한 참조될 가능성이 높다. (spaital locality)

 

따라서 fault가 나면, 그 page만 바꿔주는 것이 아니라, locality를 고려해 주변 pages도 같이 메모리에 올려주는 것을 prepaging이라고 한다.

 

 

 

8. Page pinning

 

그래픽을 랜더링 해줄 때, 특정 그래픽 관련 정보가 메모리에 저장되어 있다고 생각해보자. GPU는 이 메모리에 저장된 정보들을 가지고 랜더링을 해줄 것이다.

 

만약 이 시스템이 demand paging을 사용한다면, 그래픽 관련 정보가 저장되어 있는 메모리 영역이 swap out될 수도 있다. 원래는 swap out 되었더라도, page table을 읽어서 원래의 데이터를 가져올 수 있지만, GPU와 같은 디바이스들은 page table을 읽지 못하는 경우가 일반적이다.

 

따라서 디바이스들이 사용하는 swap out 되지 말아야 할 메모리의 영역을 고정해주는 것이 Page pinning이다.

 

 

오늘 배운 내용을 정리해보면,

 

1. address space에서 code영역은 file-backed pages이고, heap stack은 anonymouse pages이다.

2. 자주 사용하는 working set의 크기가 page frame의 크기보다 크면 Thrashing이 발생한다.

3. page frame을 할당해주는 방식은 여러가지가 있다.

4. VM에서는 buddy system allocator, Slab allocator, prepaging, page pinning 등의 컨셉들이 존재한다.

 

 

본 내용은 공부하며 작성한 것으로, 오류가 있을수 있습니다.