[Daily morning study] TLB와 MMU 동작 원리 — 가상 주소 변환 과정
#daily morning study
가상 주소 변환이 필요한 이유
프로세스는 자신만의 독립된 주소 공간(가상 주소 공간)을 가진다. CPU가 명령어를 실행할 때 참조하는 주소는 가상 주소(Virtual Address)이고, 실제 메모리에 접근하려면 이를 물리 주소(Physical Address)로 변환해야 한다. 이 변환을 담당하는 하드웨어가 MMU(Memory Management Unit) 다.
MMU와 페이지 테이블
가상 주소 → 물리 주소 변환은 페이지 테이블(Page Table) 을 통해 이루어진다.
- 가상 주소는 두 부분으로 나뉜다: VPN(Virtual Page Number) + Offset
- MMU는 VPN을 페이지 테이블에서 찾아 PFN(Physical Frame Number) 으로 바꾼다
- 물리 주소 = PFN + Offset
가상 주소: [ VPN (상위 비트) | Offset (하위 비트) ]
↓ 페이지 테이블 조회
물리 주소: [ PFN (프레임 번호) | Offset (동일) ]
페이지 테이블은 메인 메모리(RAM)에 저장되어 있어, 매 메모리 접근마다 페이지 테이블을 한 번 더 읽어야 한다. 결국 메모리 접근 1번에 실제로는 2번의 메모리 접근이 필요하다는 문제가 생긴다.
TLB(Translation Lookaside Buffer)
이 오버헤드를 줄이기 위해 TLB 라는 고속 캐시를 CPU 내부(또는 MMU 내부)에 둔다.
TLB는 최근에 사용된 VPN → PFN 매핑을 저장해 두는 하드웨어 캐시다. 페이지 테이블 조회 없이 바로 물리 주소를 얻을 수 있어 훨씬 빠르다.
TLB 동작 흐름
CPU가 가상 주소 생성
↓
TLB 조회 (VPN 검색)
├── TLB Hit → PFN 즉시 획득 → 물리 주소 계산 → 메모리 접근
└── TLB Miss → 페이지 테이블 조회 → PFN 획득 → TLB 업데이트 → 메모리 접근
| 상황 | 동작 | 메모리 접근 횟수 |
|---|---|---|
| TLB Hit | TLB에서 바로 변환 | 1회 (실제 데이터만) |
| TLB Miss | 페이지 테이블 조회 후 TLB 업데이트 | 2회 이상 |
TLB 구조와 특성
TLB는 완전 연관(Fully Associative) 또는 집합 연관(Set Associative) 방식으로 구성된다. 엔트리 수는 보통 64~1024개 수준이다.
각 TLB 엔트리는 다음 정보를 포함한다.
| 필드 | 설명 |
|---|---|
| VPN | 가상 페이지 번호 |
| PFN | 물리 프레임 번호 |
| Valid bit | 엔트리 유효 여부 |
| Protection bits | 읽기/쓰기/실행 권한 |
| ASID | Address Space ID (프로세스 구분용) |
| Dirty bit | 페이지 수정 여부 |
ASID(Address Space ID) 는 컨텍스트 스위칭 시 TLB를 전부 무효화(flush)하지 않아도 되도록 프로세스를 구분하는 태그다. ASID가 없으면 프로세스가 바뀔 때마다 TLB를 전부 비워야 해서 오버헤드가 크다.
TLB Miss 처리 방식
TLB Miss가 발생했을 때 페이지 테이블을 누가 순회하는지에 따라 두 가지 방식이 있다.
Hardware-managed TLB (x86 계열)
MMU 하드웨어가 자동으로 페이지 테이블을 순회(Page Table Walk)해서 PFN을 찾아 TLB에 적재한다. 운영체제 개입이 없어 빠르지만, 페이지 테이블 구조가 하드웨어에 고정된다.
Software-managed TLB (MIPS, SPARC 계열)
TLB Miss가 발생하면 TLB Miss 예외(Exception) 가 발생하고, OS 핸들러가 페이지 테이블을 직접 조회해서 TLB를 갱신한다. 유연하지만 예외 처리 비용이 있다.
다단계 페이지 테이블
32비트 시스템에서 4KB 페이지를 쓰면 페이지 테이블 엔트리가 최대 2^20 = 1,048,576개 필요하다. 모든 프로세스가 이 테이블을 메모리에 유지하면 낭비가 심해진다.
이를 해결하기 위해 다단계 페이지 테이블(Multi-level Page Table) 을 사용한다.
가상 주소 (32비트 기준):
[ L1 인덱스 (10bit) | L2 인덱스 (10bit) | Offset (12bit) ]
L1 페이지 디렉토리 → L2 페이지 테이블 → 물리 프레임
실제로 사용되는 영역의 L2 테이블만 메모리에 유지하면 되므로 공간을 크게 절약할 수 있다. x86-64는 4단계(PGD → PUD → PMD → PTE) 구조를 사용한다.
TLB Miss 시 하드웨어는 이 다단계 구조를 순서대로 순회(Page Table Walk)한다.
TLB와 컨텍스트 스위칭
프로세스가 교체될 때 TLB 처리 방법은 두 가지다.
TLB Flush (전체 무효화)
전환 시 TLB를 비운다. 간단하지만 새 프로세스가 초기에 TLB Miss를 많이 겪는다.
ASID 방식 (부분 유지)
각 엔트리에 ASID를 태깅해 프로세스가 바뀌어도 다른 프로세스의 TLB 엔트리를 보존한다. 프로세스가 다시 스케줄되면 이전 TLB 엔트리를 재활용할 수 있다.
지역성(Locality)과 TLB 적중률
TLB가 효과적인 이유는 프로그램이 시간적 지역성(Temporal Locality) 과 공간적 지역성(Spatial Locality) 을 가지기 때문이다.
- 시간적 지역성: 최근에 접근한 페이지에 다시 접근할 가능성이 높다
- 공간적 지역성: 특정 페이지에 접근하면 인접 페이지에도 곧 접근할 가능성이 높다
일반적인 워크로드에서 TLB 적중률은 95~99% 수준이다. 적중률이 높을수록 페이지 테이블 접근 오버헤드가 줄어들어 전체 메모리 접근 성능이 향상된다.
정리
| 개념 | 역할 |
|---|---|
| MMU | 가상 주소 → 물리 주소 변환 담당 하드웨어 |
| 페이지 테이블 | VPN → PFN 매핑 정보 저장 (메모리에 위치) |
| TLB | 최근 변환 결과 캐싱 (CPU 내부 고속 메모리) |
| ASID | TLB 엔트리에 프로세스 태그를 달아 불필요한 Flush 방지 |
| 다단계 페이지 테이블 | 페이지 테이블 메모리 사용량 절감 |
가상 메모리는 프로세스 격리와 효율적인 메모리 활용을 가능하게 하고, TLB는 그 변환 비용을 현실적인 수준으로 낮춰 준다. 두 개념은 항상 함께 이해해야 한다.