Search
Duplicate
🍎

[운영체제] 메모리 가상화 - 페이징

간단소개
페이징 기법의 초기 형태에 대해 알아보자
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
운영체제
Scrap
태그
메모리
9 more properties
“운영체제 : 아주 쉬운 세가지 이야기”를 읽으면서 핵심 내용을 정리하였습니다. 이화여대 반효경 교수님의 운영체제 강의를 듣고 복습 차원에서 책 한권을 완독해보고자 합니다. 잘못된 정보가 있다면 댓글 남겨주시면 감사하겠습니다!

세그멘테이션의 한계

논리적인 의미를 가지는 가변크기의 공간으로 메모리를 나눠서 물리 메모리에 올리게 되면 외부 단편화가 발생할 수 있는 태생적인 한계를 가지고 있다.
이를 해결 하기 위해 동일 크기의 공간으로 분할하는 아이디어에 대한 연구가 이루어졌고 이를 페이징(paging)이라고 부르게 되었다. 페이징에서는 프로세스의 주소공간을 고정 크기의 단위로 나누게 되고 물리 메모리 또한 페이지 프레임(page frame)이라는 고정크기로 나누게 되었다.

페이징의 간단한 예시

위의 그림과 같이 64바이트의 작은 주소 공간을 16바이트짜리 페이지 4개로 나눌수 있고 이를 물리 메모리의 페이지 프레임에 탑재 한것을 볼 수 있다.(물리 메모리의 페이지 프레임 또한 16바이트)
페이징을 사용 하였을 때 장점은 아래와 같다.
1.
유연성
주소공간의 사용 방식(힙인지 스택인지 코드영역인지)에 상관 없이 효율적으로 주소 공간을 관리 할 수 있다.
힙과 스택이 어느 방향으로 커지는지에 대한 고려가 필요 없어짐
2.
빈공간 관리의 단순화
빈공간 리스트에서 각 청크가 같은 크기를 가지고 있기 때문에 단순히 사용자가 원하는 수의 페이지 만큼 반환을 해주면 된다.
주소 공간의 각 가상 페이지에 대한 물리 메모리의 위치를 기록하기 위해서 운영체제는 각 프로세스마다 페이지 테이블이라는 자료구조를 가지고 있다. 페이지 테이블의 주요 역할은 주소 변환이다.

페이징 기법의 주소 변환 방법

주소 변환을 위해 먼저 가상 주소를 가상페이지 번호(virtual page number, VPN)와 페이지내에서의 오프셋(OFFSET)으로 나눈다.
예시에서는 64바이트의 가상주소로 가정하였으므로 6비트의가 필요하고 각 페이지의 크기를 16바이트로하고 총 4개로 나눴기 때문에 2개의 비트로 VPN을 나타낼 수 있다.
가상 주소 21을 변환해 보면 아래와 같다.
21의 이진수 형식 : 010101
vpn : 01 -> 1
offset : 0101 -> 5
의미 : 1번 가상페이지에서 5만큼 떨어진 곳
페이지 테이블을 가지고 가상 페이지가 어떤 물리 페이지 프레임에 저장되어 있는지 찾아 낼수 있고 offset을 통해 해당 물리 페이지 프레임에서 얼만큼 떨어져 있는지도 알아낼 수 있기 때문에 주소 변환이 가능해 진다.

페이지 테이블은 어디에 저장될까?

실제 32비트 주소 공간에서 4KB의 페이지를 사용한다고 하였을 때의 경우에 대해서 가상 주소 공간을 아래와 같이 나눌 수 있다.
VPN : 20비트 사용
OFFSET : 12 비트 사용 (10비트 = 1KB 이기 때문에 2비트만 추가 하면 4KB를 나타낼 수 있음)
이경우 페이지 테이블은 총 2^20(거의 백만) 개의 정보를 저장 하고 있어야 되고 페이지 테이블 항목(page table entry, PTE)마다 4바이트가 필요하다고 한다면 각페이지 테이블을 저장하기 위해 4MB의 메모리가 필요하게된다. 프로세스 100개만 실행 시켜도 400MB의 메모리가 필요하게 되므로 이는 꽤 큰 공간이고 현대의 64비트 주소 공간을 가정하게 된다면 아주 커지게 된다.
페이지 테이블의 크기가 크기 때문에 이를 MMU안에 유지할 수 없고 운영체제의 가상메모리에 저장된다.

페이지 테이블 안에는 실제 무엇이 있을까?

우선 페이지 테이블이 VPN을 인덱스로 하는 단순한 배열 자료 구조(선형 페이지 테이블)라고 가정하고 생각을 할 수 있다. 이는 이후에 페이징의 문제를 해결하기 위해 고급 자료 구조로 변환된다. VPN 인덱스에 접근하면 PTE에 저장된 정보를 확인 할 수 있다.
실제 PTE에는 여러 정보들이 담겨 있는데 이는 아래와 같다.
valid bit : 할당되지 않은 주소 공간을 표현
주소 공간에서 힙과 스택 사이의 미사용 공간과 같은 미사용 공간을 표시 함으로서 이러한 페이지에 물리 프레임을 할당할 필요를 없애 대량의 메모리를 절약할 수 있음
protection bit : 페이지의 읽기 / 쓰기 / 실행 권한을 나타냄
present bit : 페이지가 물리 메모리에 있는지 디스크에 있는지 (스왑 아웃 되었는지 판단)
dirty bit : 메모리에 반입된 이후 페이지가 변경되었는지 여부를 나타냄
reference bit : 페이지가 접근되었는지 추적하기 위해 사용
물리 메모리가 모자랄 떄 페이지 교체를 판단하는데 필요한 정보( 어떤 페이지가 인기가 많을 까를 판단)
이외 여러 다양한 비트들이 있음

페이징은 느리다?

하드웨어에 페이지 테이블 베이스 레지스터(page table base register)는 페이지 테이블의 시작 위치를 저장하고 있다. 페이징을 사용한 메모리 접근하는 수도 코드를 살펴보면 아래와 같다.
//가상 주소에서 VPN 추출 VPN = (virtualAddress & VPN_MASK) >> SHIFT // 페이지 테이블 항목(PTE)의 주소 만들기 PTEAddr = PTBR + (VPN * sizeof(PTE)) //PTE 반입 PTE = AccessMemory(PTEAddr) //프로세스가 페이지를 접근할 수 있는지 확인 if (PTE.Valid == False) RaiseException(SEGMENTATION_FAULT) else if (CanAccess(PTE.ProtectionBits) == False) RaiseException(PROTECTION_FAULT) else offset = VirtualAddress & OFFSET_MASK PhyAddr = (PFE.PFN << PFN_SHIFT) | offset Register = AccessMemory(PhysAddr)
C++
복사
모든 메모리 참조에 대해 먼저 페이지 테이블에서 변환 정보를 반입 해야하기 때문에 한번의 추가적인 메모리 참조가 필요하게 된다. 메모리 참조는 비용이 비싸기 때문에 프로세스가 느려지게 된다.
페이징에는 위에서 알아본 것처럼 두가지 큰 단점이 있다.
1.
페이지 테이블 자체가 큰 메모리를 차지 한다.
2.
주소 변환을 위한 추가적인 메모리 참조로 인해 느려진다.
이후에는 위의 두 단점을 어떻게 해결하였는지 알아보고자 한다.