https://os2024.jeju.ai/week09/vm-paging.html
https://os2024.jeju.ai/week09/vm-tlbs.html
https://os2024.jeju.ai/week09/vm-swap.html
https://os2024.jeju.ai/week09/summary.html
주소 공간을 효율적으로 사용하는 방법?
페이징을 알아야 되는 이유가 뭘까?
- 세상에 나갔을 때 시스템들이 실제로 어떻게 동작하는지 알 수 있다.
- 가상 메모리가 어떻게 동작하는지에 대한 모델을 잘 이해하고 있으면 여러 종류의 흥미로운 성능 관련 문제들을 진단하는 데 도움이 된다.
- 어떻게 동작하는지 개념적 모델을 만들 수 있다. 개념적 모델을 만들면 시스템이 예상과 다르게 동작하더라도 놀라지 않을 수 있고, 시스템이 어떻게 동작할지를 생각만으로도 예상을 할 수 있게 된다.
페이징에서는 프로세스의 주소 공간을 가변 크기의 논리 세그멘트로 나누는 대신, 고정 크기의 단위인 페이지(Page)로 나눕니다. 이에 상응하여 물리 메모리도 페이지 프레임(Page Frame)이라고 불리는 고정 크기의 슬롯 배열로 간주합니다. 각 페이지 프레임은 하나의 가상 메모리 페이지를 저장할 수 있습니다.
핵심 질문: 페이징을 사용하여 어떻게 메모리를 가상화할 수 있을까요? 세그멘테이션의 문제점을 해결하기 위해 페이징을 어떻게 활용할 수 있을까요? 기본 기법은 무엇이며, 공간과 시간 오버헤드를 최소화하면서 그 기법을 잘 동작하게 만들기 위한 방법은 무엇일까요?
아래 그림은 총 64바이트이며 4개의 16바이트 페이지로 구성된 작은 주소 공간의 예를 보여줍니다.

물리 메모리는 고정 크기의 슬롯들로 구성되며, 이 예에서는 8개의 페이지 프레임으로 이루어진 총 128바이트의 비현실적으로 작은 물리 메모리를 가정합니다.

가상 주소 공간(Address Space, AS)의 페이지들이 페이지 프레임에 분산 배치되어 있음을 알 수 있습니다. 또한 운영체제가 자기 자신을 위해 물리 메모리의 일부를 사용하는 것도 볼 수 있습니다.
또 다른 장점은 단순함입니다. 운영체제가 64바이트의 가상 주소 공간을 8페이지 물리 메모리에 배치하려면, 단순히 비어 있는 4개의 페이지만 찾으면 됩니다. 이를 위해 운영체제는 빈 페이지 리스트를 유지하고, 리스트의 첫 네 개 페이지를 선택할 수 있습니다.
위의 예시에서는 가상 페이지(VP) 0은 물리 페이지 프레임(PF) 3에, VP 1은 PF 7에, VP 2는 PF 5에, VP 3은 PF 2에 매핑되어 있습니다. 페이지 테이블은 프로세스마다 존재한다는 점을 기억해야 합니다. 다른 프로세스를 실행한다면, 그 프로세스를 위한 별도의 페이지 테이블이 필요할 것입니다.
페이지 테이블은 매우 커질 수 있습니다. 예를 들어, 4KB 크기의 페이지를 가지는 전형적인 32비트 주소 공간을 생각해 보겠습니다. 이 가상 주소는 20비트 VPN과 12비트 Offset으로 구성됩니다(2^12 = 4KB, 나머지는 VPN).
20비트의 VPN은 운영체제가 각 프로세스를 위해 관리해야 하는 변환의 개수가 2^20개라는 것을 의미합니다. 물리 주소로의 변환 정보와 기타 필요한 정보를 저장하기 위해 페이지 테이블 항목(Page Table Entry, PTE)마다 4바이트가 필요하다고 가정하면, 각 페이지 테이블을 저장하기 위해 4MB(4바이트 * 2^20)의 메모리가 필요합니다.
만약 100개의 프로세스가 실행 중이라면 400MB의 메모리가 필요하다는 것을 의미합니다. 현재와 같이 GB 단위의 메모리를 갖고 있는 상황에서도 주소 변환을 위해 이렇게 많은 메모리가 필요하다는 것은 다소 비정상적입니다.
프로그램을 하나 실행할 때마다 4byte를 먹는 비정상적인 상황
페이징을 사용할 때 페이지 테이블의 크기가 메모리 상에서 매우 크게 증가할 가능성이 있고, 이로 인해 처리 속도가 저하될 수 있습니다.
movl 21, %eax
이 명령어는 21번 메모리 주소에서 데이터를 가져와 eax 레지스터에 저장합니다. 여기서는 명령어 자체의 반입은 고려하지 않고, 데이터 21에 대한 참조만 살펴보겠습니다.
데이터를 가져오기 위해서는 먼저 가상 주소 21을 물리 주소 117로 변환해야 합니다. 주소 117에서 데이터를 가져오기 전에 시스템은 다음과 같은 단계를 거쳐야 합니다:
이를 위해 하드웨어는 현재 실행 중인 프로세스의 페이지 테이블 위치를 알고 있어야 합니다.
가장 큰 문제는 모든 메모리 참조마다 페이지 테이블에서 주소 변환 정보를 읽어와야 한다는 점입니다. 이로 인해 메모리 접근이 최소 한 번 더 발생하게 되는데, 메모리 접근은 비용이 높은 연산이므로 프로그램의 실행 속도가 크게 저하될 수 있습니다.
주소 변환 과정에서 추가적인 메모리 접근이 발생한다. 프로세스가 메모리에 접근할 때마다 페이지 테이블을 읽어야 하므로, 매 메모리 접근마다 두 번의 메모리 연산(페이지 테이블 읽기 + 실제 데이터 읽기/쓰기)이 필요하게 됩니다. 이는 심각한 성능 저하를 초래할 수 있습니다.
핵심 질문:
TLB : Translation Lookaside Buffer
TLB의 목적은 최근에 사용된 가상 주소와 물리 주소 간의 매핑 정보를 저장하여, 주소 변환 속도를 향상시키는 것입니다.
프로세스가 가상 주소를 사용하여 메모리에 접근하면, 하드웨어는 먼저 TLB에서 해당 가상 주소의 변환 정보를 찾아봅니다. 만약 TLB에 정보가 있다면 (TLB Hit), 곧바로 물리 주소를 얻어 메모리에 접근할 수 있습니다. 이 경우, 페이지 테이블을 읽는 추가 작업 없이 주소 변환을 완료할 수 있으므로 매우 빠릅니다.
반면에, 원하는 정보가 TLB에 없는 경우 (TLB Miss)에는 기존대로 페이지 테이블을 참조하여 주소 변환을 진행해야 합니다. 이 과정에서 얻은 변환 정보는 향후 재사용을 위해 TLB에 저장됩니다.
아직도 잘 이해가 안되는데 가상 주소 → 물리 주소로 변환하는 과정에서 PTE를 생성해서 변환하는 것과 TLB를 이용해서 변환하는 것의 차이를 잘 모르겠어… PTE를 만들어서 변환하든 TLB(작은 하드웨어 캐시)를 이용하든 똑같은 과정 아닌가?
- 페이지 테이블은 크고 느린 메모리에 존재하기 때문에 메모리 접근 비용이 높은 연산이다(PTE - RAM, TLB - CPU 내부의 고속 메모리)
- 페이지 테이블의 크기가 커질 수 있고, 모든 메모리 참조마다 페이지 테이블을 통한 주소 변환이 필요하다.
- 자주 사용되는 일부 PTE 정보만 저장하므로 크기가 작고 빠르다.
int main() {
int array[100];
array[50] = 10; // 배열의 특정 위치에 데이터 쓰기
return 0;
이 코드에서 array[50]에 값을 할당하려면 다음과 같은 과정이 필요합니다.
프로세스가 메모리에 존재하지 않는 페이지에 접근하려는 경우 발생하는 예외 상황
처리 과정
영향: 페이지 폴트는 메모리 접근 지연을 야기하여 성능 저하를 초래한다.
개념: 페이지 테이블에 존재하는 각 엔트리에 설정되는 플래그 비트
기능: 해당 페이지가 현재 물리 메모리에 존재하는지 여부를 나타냄
활용
물리 메모리가 부족하면 사용하지 않는 페이지를 하드 디스크의 특정 영역(스왑 공간)에 백업하고, 필요하면 다시 메모리로 불러오는 기술
가상 메모리 공간이 부족하면 사용하지 않는 페이지를 스왑 공간으로 백업하고, 필요하면 다시 메모리로 불러온다.

단점으로 하드 디스크는 메모리보다 훨씬 느려 페이지 폴트 발생 시 성능 저하
낚곰님^^ 안녕하세요 ! 잘보고갑니다 . 낚곰님이 남겨주신 질문에( TLB와 PTE 차이 ) 제 생각을 적어보자면
TLB와 페이지 테이블(PTE)의 역할은 비슷하지만, 저장 위치가 달라서 접근 속도와 비용이 크게 다르다고 생각했어요.
메모리접근은 많은 비용이 들기 때문에 cpu에 캐싱함으로써 접근 비용 및 속도가 개선되기 때문에 사용한다고 생각했습니다.
즉 가상=>물리 변환이라는 역할은 비슷하지만 위치의 차이때문에 효율이 달라지는거 아닐까요 흠