페이징은 잘못 설계하면 상당한 성능 저하를 가져올 수 있다.
핵심 질문: 주소 변환 속도를 어떻게 향상할까?
- 주소 변환을 어떻게 빨리 할 수 있을까?
- 페이징에서 발생하는 추가 메모리 참조를 어떻게 피할 수 있을까?
- 어떤 하드웨어가 추가로 필요할까?
- 운영체제는 어떤 식으로 개입?
운영체제의 실행 속도를 개선하려면 하드웨어의 도움을 받아야 한다. 따라서 주소 변환을 빠르게 하기 위한 Translation-Lookaside Buffer (TLB)를 도입할 것이다.Translation-Lookaside Buffer (TLB)
- TLB는 칩의 메모리 관리부(MMU)의 일부이며, 자주 참조되는 가상 주소-실주소 변환 정보를 저장하는 하드웨어 캐시이다.
- 주소-변환 캐시(address-translation cache)가 좀 더 적합한 명칭
- 가상 메모리 참조 시, 하드웨어는 먼저 TLB에 원하는 변환 정보가 있는지 확인
- 만약 있다면 페이지 테이블에서 검색을 하지 않고 변환을 빠르게 수행
아래의 TLB 동작 과정에서 주소 변환부는 단순한 선형 페이지 테이블로, TLB는 하드웨어로 관리되는 TLB로 구성되어 있다.
//가상 주소에서 VPN 추출
VPN = (VirtualAddress & VPN_MASK) >> SHIFT
// TLB에 VPN 있는지 확인
(Success , TlbEntry) = TLB_Lookup(VPN)
if (Success == True) { // TLB 히트
if (CanAccess(TlbEntry.ProtectBits) == True) {
Offset = VirtualAddress & OFFSET_MASK
// TLB Entry에 있는 PFN 추출 가능, 물리 주소로 만들기
PhysAddr = (TlbEntry.PFN << SHIFT) | Offset
// 메모리 접근
AccessMemory(PhysAddr)
}
else
RaiseException(PROTECTION_FAULT)
}
else { // TLB 미스
// 페이지 테이블 항목(PTE)의 주소 형성
PTEAddr = PTBR + (VPN * sizeof(PTE))
// 페이지 테이블에 접근
PTE = AccessMemory(PTEAddr) // <- 많은 시간 소요!
if (PTE.Valid == False)
RaiseException(SEGMENTATION_FAULT)
else if (CanAccess(PTE.ProtectBits) == False)
RaiseException(PROTECTION_FAULT)
else {
// 해당 변환 정보를 TLB로 삽입
TLB_Insert(VPN, PTE.PFN, PTE.ProtectBits)
// TLB 갱신되었으므로 명령어 재실행
RetryInstruction()
}
}
TLB 역시 "주소 변환 정보가 대부분의 경우 캐시에 있다"는 가정을 전제로 만들어졌다.
- TLB는 프로세싱 코어와 가까운 곳에 위치
- 매우 빠른 하드웨어로 구성되기 때문에, 주소 변환 작업은 그다지 부담스러운 작업이 아님
- 반면, TLB 미스가 발생하면 페이징 비용 커지므로, TLB 미스가 발생하는 경우를 최대한 피해야 한다.
TLB 작동 과정을 좀 더 명확히 알아보자. 이 예제에서는 간단한 가상 주소 트레이스를 대상으로 TLB로 인한 성능 개선을 알아볼 것이다.
a[0]
은 VPN=06, 오프셋=04
에서 시작 for (i = 0; i < 10; i++)
sum += a[i];
a[0]
에 접근a[1]
, a[2]
에 접근할 때는 TLB 히트 (a[0]
과 같은 페이지)a[3]
에 접근할 때에는 TLB 미스a[4~6]
에 접근할 때에는 TLB 히트다른 캐시와 마찬가지로, TLB의 성공 여부는 프로그램의 공간 지역성과 시간 지역성 존재 여부에 달려있다.
1. 하드웨어에서 처리 (CISC)
2. 소프트웨어에서 처리 (RISC)
시스템 콜 호출 트랩 핸들러 vs TLB 미스 처리 트랩 핸들러
TLB 미스 핸들러를 실행할 때, TLB 미스가 무한 반복되지 않도록 주의
하드웨어 TLB의 구성
VPN | PFN | other bits
other bits
TLB를 사용하게 되면 프로세스 간 (주소 공간들로 인해) 문맥 교환 시, 새로운 문제가 등장한다.
VPN=10 -> PFN=100
VPN=10 -> PFN-170
VPN | PFN | valid | prot |
---|---|---|---|
10 | 100 | 1 | rwx |
-- | --- | 0 | --- |
10 | 170 | 1 | rwx |
-- | --- | 0 | --- |
핵심 질문: 문맥 교환 시 TLB 내용을 어떻게 관리?
문맥 교환 시 실행될 프로세스에게는 이전 프로세스가 사용한 TLB 정보는 의미가 없다.
문맥 교환 시 기존 TLB 내용을 비우는 방법
주소 공간 식별자(address space identiier, ASID) 필드를 추가
VPN | PFN | valid | prot | ASID |
---|---|---|---|---|
10 | 100 | 1 | rwx | 1 |
- | - | 0 | - | - |
10 | 170 | 1 | rwx | 2 |
- | - | 0 | - | - |
공유 페이지
VPN | PFN | valid | prot | ASID |
---|---|---|---|---|
10 | 101 | 1 | r-x | 1 |
- | - | 0 | - | - |
50 | 101 | 1 | r-x | 2 |
- | - | 0 | - | - |
모든 캐시가 그러하듯이 TLB에서도 캐시 교체(cache replacement) 정책이 매우 중요하다. TLB에 새로운 항목을 탑재할 때, 현재 존재하는 항목 중 하나를 교체 대상으로 선정해야 한다. 어느 것을 선택해야 할까?
핵심 질문 : TLB 교체 정책은 어떻게 설계하는가
TLB에 새로운 항목을 추가할 때 어떤 항목을 교체해야 할까? 목표는 미스율을 줄여 (또는 히트 비율을 증가시켜서) 성능을 개선하는 것이다.
최저 사용 빈도(least-recently-used, LRU)
- 지역성을 최대한 활용하는 것이 목표
- 사용되지 않은지 오래된 항목일수록, 앞으로 사용될 가능성 낮음 = 교체 대상으로 적합
랜덤 정책- 교체 대상을 무작위로 정함
- 잘못된 결정을 내리기도 하지만, 예상치 못한 예외 상황의 발생을 피함
- LRU 같은 경우에, 용량 n인 TLB에 n+1개의 페이지들에 대해 반복문 수행하면 최악의 TLB 미스 생성
- 그에 반해 랜덤의 경우 훨씬 잘 작동
MIPS R4000이라는 프로세서를 예로 삼아 실제 TLB가 어떻게 생겼는지 알아보자
TLBP
: 특정 변환 정보 존재하는지 탐색TLBR
: TLB 항목의 내용을 레지스터로 읽는데 사용TLBWI
: 특정 TLB 항목 교체TLBWR
: 임의의 TLB 항목 교체