8 분 소요

이번 포스트는 OS의 Tranlstaion Lookaside Buffer와 Advanced Page Tables 에 대해 다룬다.

Translation Lookaside Buffer

TLB

  • MMU (Memory Management Unit)안에 있는 고속 캐시
  • 목적 : 가장 자주 사용되는 VA -> PA (virtual -> physical) 변환 정보를 빠르게 제공
    • 페이지 테이블 전체를 매번 메모리에 읽지 않도록 하기 위한 하드웨어 캐시 역할
  • 구조
CPU → Logical Address 생성
      ↓
     MMU
        ↳ TLB Lookup
           ● Hit → 바로 Physical Address 반환
           ● Miss → Page Table 접근 후 변환을 찾고, TLB에 저장
      ↓
Physical Memory 접근

우선 TLB에서 변환을 찾는다.

  • 있으면 (TLB Hit) : page table 접근 없이 즉시 물로 주소를 획득한다.

  • 없으면 (TLB Miss) : MMU가 페이지 테이블을 메모리에서 읽어 PFN을 얻고, 그 결과를 TLB에 넣고 다시 instruction을 재실행

TLB는 캐시의 캐시 같은 역할

TLB 기본 알고리즘

  • Virtual Page Number 추출
    • 가상주소 상위 비트 구간을 VPN으로 사용
    • page table indexing 용도
VPN = (VirtualAddress & VPN_MASK) >> SHIFT
  • TLB Lookup
    • TLB 내부에 VPN과 동일한 entry 가 있는지 검색
(Success, TlbEntry) = TLB_Lookup(VPN)
  • TLB Hit 처리
    • 보호 비트 (읽기/쓰기/실행)가 허용되면 정상 접근
    • PFN (page frame number)을 가져와 offset 과 합쳐 물리 주소 생성
if(Success){
    if(CanAccess(TlbEntry.ProtectBit)){
        offset = VirtualAddress & OFFSET_MASK;
        PhysAddr = (TlbEntry.PFN << SHIFT) | offset;
        AccessMemory(PhysAddr);
    }
    else RaiseException(PROTECTION_ERROR);
}

아래는 TLB Miss 처리

  • 한 번은 반드시 페이지 테이블 액세스가 필요
  • 이후 같은 주소 접근 시 TLB Hit로 빠르게 처리
  • TLB Table Entry 위치 계산
    • Page Table Base Register (PTBR)는 page table의 시작 주소를 나타냄
    • VPN을 인덱스로 하여 PTE로 주소를 계산
PTEAddr = PTBR + (VPN * sizeof(PTE))
  • Page Table Access
    • Valid bit = 0
    • VPN이 유효하지 않다. -> Segmentation Fault
PTE = AccessMemory(PTEAddr)
if(PTE.Valid == False)
    RaiseException(SEGFAULT)
  • 새로운 변환을 TLB에 삽입
    • 방금 얻은 변환 (VPN -> PFN)을 TLB에 저장
    • instruction 재실행 (이제 TLB Hit 발생)

Locality

TLB가 잘 작동할 수 있는 이유 = 프로그램의 지역성 (Locality) 때문

Temporal Locality (시간 지역성)

  • 최근에 접근한 페이지는 곧 다시 접근할 확률이 높다.
    • 예: 같은 변수 반복 참조, 반복문 내 변수

Spatial Locality (공간 지역성)

  • 주소 x를 접근했다면, 근처 주소도 곧 접근 가능성이 높다.
    • 예 : 배열 순차 접근 a[i], a[i + 1]

Who handles TLB Miss?

  • TLB miss 발생하면 누가 처리하는지는 CPU 아키텍처에 따라 다르다.

CISC

  • Intel x86 (하드웨어-managed TLB)
  • TLB miss 시 CPU 하드웨어가 직접 page table walk 수행
  • CPU가 메모리에서 page table 찾아보고 PFN 가져와서 TLB 갱신

과정

  1. TLB miss
  2. 하드웨어가 page table에서 PTE를 읽음
  3. TLB 업데이트
  4. Instruction 재실행
  • OS 의 개입이 거의 없다. (성능이 높음)
  • CPU가 메모리에서 page table을 직접 찾아보고 PFN에서 가져와서 TLB를 갱신

RISC

  • ARM, MIPS 등 (소프트웨어-managed TLB)
  • TLB Miss 시 hardware는 trap만 발생
  • 실제 페이지 테이블 lookup은 OS 코드 (trap handler)가 수행

과정

  1. TLB Miss
  2. 하드웨어가 TLB_Miss Exception 발생
  3. OS Trap Handler 발생
  4. OS가 Page Table Lookup 수행
  5. TLB에 넣고 instruction을 재실행

장점 : 하드웨어가 간단

단점 : OS trap -> context swtich 성능 저하

코드 구현

VPN = Extract(VirtualAddress)

(Success, Entry) = TLB_Lookup(VPN)

if (Success == TRUE) {        // TLB Hit
    if (AccessAllowed(Entry.ProtectBits)) {
        offset = VA & OFFSET_MASK
        PA = (Entry.PFN << SHIFT) | offset
        AccessMemory(PA)
    } else {
        RaiseException(PROTECTION_FAULT)
    }
}

이 중에서

else {       // TLB Miss
    RaiseException(TLB_MISS)
}
  • TLB Miss를 OS에 넘기는 것 = ARM/RISC 스타일

OS trap Handler에서 할 일:

  1. Page Table에서 PTE 찾음.
  2. 권한 체크
  3. 유효하지 않으면 segfault
  4. 유효하면 해당 VPN -> PFN 을 TLB에 넣음
  5. faulting instruction retry

TLB Entry

  • TLB는 Fully Associative 방식으로 관리된다.
    • 어떤 번역 (translation)도 TLB 의 어느 위치에나 저장될 수 있다.
    • 하드웨어가 모든 엔트리를 병렬 탐색하여 원하는 VPN을 찾는다.

구성 요소

  • VPN (Virtual Page Number) : 가상 페이지 번호
  • PFN (Page Frame Number) : 실제 물리 프레임 번호
  • Other Bits
    • valid bit
    • protection bits
    • dirty bits
    • address-space identifier (ASID) 등

Issue : Context Switching

  • 프로세스가 전환할 때,
    • TLB에 남아있는 이전 프로세스의 엔트리 때문에
    • 잘못된 PFN을 사용하여 메모리를 접근할 위험이 있다.

TLB는 VPN만 보고 찾기 때문에, 동일 VPN을 가진 다른 프로세스의 엔트리를 구분을 못한다.

TLB의 엔트리로만 어떤 프로세스의 번역인지 판별이 불가능

해결 방법 : ASID

ASID (Address Space Identifier)

  • TLB 엔트리에 ASID 필드를 추가하여 같은 VPN이라도 프로세스별로 구분이 가능하게 한다.
  • 장점 :
    • Context switching 시 TLB Flush 를 완전히 할 필요가 없다.
    • 같은 번호의 VPN이라도 프로세스마다 따로 관리된다.

Another Case

두 프로세스가 페이지를 공유하는 경우

  • 서로 다른 프로세스라도 같은 물리 페이지(PFN)을 공유할 수 있다.
  • VPN이 다르지만 PFN이 동일한 상황
    • 페이지 공유는 물리 메모리 사용량을 줄이는 장점이 있어서 사용

LRU (Least Recently Used)

  • TLB가 꽉 찼을 때 가장 오랫동안 사용되지 않은 엔트리부터 교체
  • Locality (시간, 공간 지역성)를 활용하는 정책

LRU

실제 TLB 엔트리의 구성 (64-bit)

필드 역할
19-bit VPN 가상 페이지 번호
24-bit PFN 물리 페이지 번호 (64GB 주소공간 지원)
Global bit (G) 여러 프로세스가 공유하는 페이지 표시
ASID TLB 항목의 소유 프로세스를 구분
Coherence bit (C) 캐시 일관성(캐시 전략) 관련 설정
Dirty bit (D) 페이지가 수정되었는지 여부(Write-back에 사용)
Valid bit (V) TLB 엔트리가 유효한지 여부
  • 실제 시스템의 TLB는 매우 다양한 메타데이터를 포함
  • 이 비트들 덕분에 TLB는 보안, 공유, 캐싱, 변경 여부까지 모두 관리가 가능

Advanced Page Table

Paging : Linear Tables

  • 모든 프로세스는 자신만의 페이지 테이블을 가진다.
  • 32-bit 주소 공간, 4KB 페이지, PTE 4바이트라고 가정하면:
    • 페이지 개수 = 2^20 = 약 100만개
    • 페이지 테이블 크기 = 4MB
  • 문제점
    • 각 프로세스마다 페이지 테이블이 4MB나 필요하다
    • 프로세스 100개면 페이지 테이블만 400MB -> 너무 크다.
    • 물리 메모리를 낭비한다.

Smaller Tables

시도 : 페이지 크기를 키우자 (4KB -> 16KB)

  • 페이지 개수가 줄어들어 페이지 테이블도 줄어든다.
    • 새 페이지 개수 = 2^18 = 약 26만개
    • 페이지 테이블 크기 = 1MB
  • 장점 : 페이지 테이블 사이즈가 4MB -> 1MB로 감소되면서 메모리 절약
  • 문제점
    • 내부 단편화 (internal fragmentation) 발생이 커진다.
    • 1KB만 사용해도 16KB 페이지 하나 전체를 차지해야 함.
    • 작은 메모리 요청이 큰 페이지를 낭비시키는 구조

Single Page Table Problem

상황

  • 16KB 가상 주소 공간, 페이지 크기 1KB -> 총 16개의 VPN (0~15)
  • 프로세스는 code/heap/stack 등 특정 페이지만 실제 물리 메모리와 매핑됨.

문제

  • 전체 페이지 테이블 (16개 엔트리)을 만들어야 한다.
  • 하지만 실제 사용하는 페이지(매핑된 페이지)는 몇 개뿐
  • 나머지 엔트리는 다음과 같이 invalid

즉, unused entries 가 대부분을 차지한다.

  • 메모리 사용량이 불필욯아게 커짐. (페이지 테이블의 대부분이 낭비됨)

Hybrid Approach : Paging and Segments

아이디어 : 프로세스의 가상 주소 공간은 보통 여러 ‘segment’로 나뉜다.

예:

  • code segment (01)
  • heap segment (10)
  • stack segment (11)

각 세그먼트마다 필요한 만큼만 page table을 따로 만든다.

가상 주소 구성

Bits 의미
31–30 Segment Number (SN)
29–12 VPN (세그먼트 내부 페이지 번호)
11–0 Offset

장점

  • 각 세그먼트에 대해 작고 필요한 만큼만 페이지 테이블 생성
  • 불필요한 Huge linear page table 생성 X
  • 메모리 절약 효과가 크다.

TLB Miss on Hybrid Approach

TLB miss가 발생하면, HW는 다음 단계를 수행한다.

1. SN 추출

SN = (VirtualAddress & SEG_MASK) >> SN_SHIFT
  • 가상 주소의 상위 2비트를 보고 어떤 segment인지 판단
    • 예: 01=code , 10 = heap, 11 = stack

2. VPN 추출

VPN = (VirtualAddress & VPN_MASK) >> VPN_SHIFT

3. 해당 Segment Page Table에서 PTE 주소 생성

AddressOfPTE = Base[SN] + (VPN * sizeof(PTE))
  • 여기서 Base[SN] = ‘해당 세그먼트 page table의 시작 물리 주소’

Problem of Hybrid Approach

Heap 문제

  • 예를 들어 heap 세그먼트의 크기를 아주 크게 잡았는데, 실제로는 몇 페이지만 사용하는 경우
  • 이 세그먼트에 대해 페이지 테이블 하나를 만들면
    • 사용하지 않는 가상 페이지들에 대해서도 페이지 테이블 엔트리가 존재한다.
    • 대부분이 valid = 0 인 무효 엔트리인데도 메모리를 차지한다.
  • 즉 세그먼트 단위로 페이지 테이블을 쪼갰지만, 세그먼트 안에서의 희소성 (sparsity) 문제 때문에 여전히 페이지 테이블 낭비가 크다.

외부 단편화 (external fragmentation) 재발

  • 세그먼트 방식이 들어오면, 각 세그먼트를 위한 페이지 테이블 자체가 물리 메모리에서 연속적인 공간을 필요로 할 수 있다.
  • 세그먼트 크기가 커지고 쪼개졌다 늘어났다 하면, 물리 메모리 안에 조각난 빈 공간들이 생기게 되고, 이것이 외부 단편화이다.

Multi-level Page Tables

  • 기존 1차원 배열인 페이지 테이블 -> 다단계 (트리 비슷한 구조로 변경)
  • 페이지 테이블 전체를 여러 개의 페이지 단위 조각으로 나눈다.
    • 각각의 조각은 페이지 테이블의 한 페이지라고 생각하면 된다.
  • Invalid 엔트리만 있는 페이지는 아예 안 만든다.
    • 전부 invalid인 엔트리가 있으면, 그 페이지 자체를 물리 메모리에 할당하지 않는다.
    • 사용하지 않는 가상영역에 대한 테이블 페이지는 아예 생성하지 않아서 메모리 절약이 가능
  • Page Directory
    • 어떤 페이지 테이블 조각이 존재하는지 안하는지를 추적하는 역할
    • 각 페이지에 대한 포인터 + 유효 비트를 가진 상위 테이블

Advantage

  1. 사용한 주소 공간에 비례해서만 페이지 테이블 공간 사용
    • 프로세스가 실제로 사용하는 가상 주소 범위에 해당하는 부분의 PTE 페이지만 존재
    • sparse 가상 주소 공간에서 특히 장점
      • code, stack, heap 사이에 큰 빈 구간이 있어도 그 구간에 대한 페이지 테이블 페이지는 생성하지 않음.
  2. OS가 필요할 때마다 다음 빈 페이지를 가져다 씀
    • 새로운 영역 (ex : 힙 확장, 스택 성장)을 위해 페이지 테이블이 필요해지면, OS가 다음 빈 물리 페이지를 할당해서 새 페이지 테이블 페이지로 쓰면 된다.
    • On-demand로 페이지 테이블 확장이 가능함.

Disadvantage

  1. Time-sapce trade-off

    • 공간은 절약했지만, 주소 변환 과정이 더 복잡함.
    • 따라서 추가적인 메모리 참조 횟수 때문에 성능을 어느정도 희생하게 됨.
  2. Complexity

    • 하드웨어 (MMU) 와 OS 코드가 더 복잡해짐.
    • 페이지 디렉터리 / tree 인덱싱 계산
    • TLB 미스 처리 시 여러 단계 테이블을 따라가야 함

    • 구현 난이도 증가

Page Directory

Page Directory

  • Page Directory는 Page Table의 각 페이지당 1개의 엔트리를 가진다.

  • 각 엔트리는 PDE (Page Directory Entry)라고 부른다.

    • valid bit : 해당 페이지 테이블 페이지가 실제 메모리에 존재하는지
    • PFN (Page Frame Number) : 그 페이지 테이블 페이지가 높은 프레임 번호

    결국 그 아래 단계 페이지 테이블이 어디에 있는지 가리키는 포인터

Indirection

  • 이러한 multi-level 구조 : Indirection 참조 레벨을 조정할 수 있다
    • 먼저 page directory에서 PDE를 찾아 페이지 테이블 페이지의 위치를 얻고,
    • 그 다음 그 페이지 테이블에서 실제 PTE를 찾는 2단계 접근 방식
  • 페이지 테이블의 각 페이지를 물리 메모리 아무 곳에나 둘 수 있다.
    • 필요한 부분만 페이지 단위로 늘려가며 할당이 가능

전체 동작 흐름

  1. Vritual Address 분리
    • Offset = 6bit
    • VPN = 8 bit -> 다시 PD index + PT index로 분리
  2. Page Directory lookup
    • PD index로 PDE 읽기
    • invalid -> exception / valid -> page-table-page의 PFN 획득
  3. Page Table lookup
    • PFN + PT index로 실제 PTE 읽기
  4. PTE 의 Valid/Protection 확인
  5. PFN + Offset -> Physcial Address 생성

Inverted Page Tables

기존 방식 (Page Table per Process)의 문제점

  • Virtual Pages 수가 매우 많음.
  • 프로세스마다 page table을 만들면 낭비가 심해짐.
    • 대부분의 페이지는 비어 있고, Page Table entry가 엄청 많다.

Inverted Page Table

  • Physical Page : 어느 프로세스의, 어느 Virtual Page인지를 저장
  • 시스템 전체에 단 하나만 존재
  • 엔트리 수 = Physical Page 수 만큼만 존재

태그:

카테고리:

업데이트: