빙응의 공부 블로그

[OSTEP 가상화(virtualization)]페이징 : 더 빠른 변환(TLB) 본문

CS/운영체제

[OSTEP 가상화(virtualization)]페이징 : 더 빠른 변환(TLB)

빙응이 2025. 4. 25. 22:29

📝서론 

페이징은 전에서 설명하듯이 상당한 성능 저하가 올 수 있다. 페이징은 페이지 테이블을 통해 매핑 저장 정보를 가져온다. 이것은 매번 메모리에 접근한다는 것으로 시간적으로나 공간적으로나 모두 손해가 심각한다.

우리는 페이징의 주소 변환 속도를 향상 시켜야 한다.

📝TLB

운영체제의 실행 속도 개선을 위해 우리는 대부분의 경우 하드웨어로부터 도움을 받는다.

주소 변환을 빠르게 하기 위해서 변환-색인 버퍼 또한 TLB라고 부르는 메모리 관리부(MMU)를 두기 시작한다.

 

TLB의 기본 알고리즘

TLB는 쉽게 말하면 캐시와 비슷하다. TLB에 변환 정보를 저장하여 만약 TLB에 들어있다면 메모리에 접근하지 않고 정보를 얻을 수 있다.

 

흐름을 살펴보자

  1. 가상 주소에서 페이지 번호만 뽑아낸다.
    • 어느 페이지에 있지?
  2. TLB에서 그 페이지 번호가 있는지 확인한다.
    • 캐시에 저장된 정보가 있나?
  3. 있으면 TLB 히트 성공이다.
    • 권한 검사 -> 이 데이터 읽어도 되는지?
    • 권한 검사가 끝나고 가상 주소의 오프셋과 PFN을 조합해서 물리 주소를 만든다.
  4. 없다면 TLB 미스이다.
    • 이 경우 페이지 테이블을 열어서 메모리 검색을 진행한다.
    • 그리고 TLB에 그걸 새로 저장한다.
더보기

팁 : 가능하면 캐싱을 사용하자.

 

캐싱은 컴퓨터 시스템에서 사용되는 가장 근본적인 성능 개선 기술 중 하나이다.

캐시의 기본 취지는 명령과 데이터 참조에 있어서 지역성을 활용하는 것이다.

 

📝TLB 미스는 누가 처리할까?

TLB 미스의 처리는 어디서 담당할까? 2가지 방법이 존재한다.

 

1. 하드웨어가 처리하는 방식

-> CISC (complex instructionsetcomputers) 구조를 사용한다(예 : x86 CPU)

  • CPU 하드웨어가 직접 페이지 테이블에서 필요한 정보를 가져와 TLB를 갱신한다.
  • 그리고 TLB 미스를 일으킨 명령어를 다시 실행한다.
    • TLB 미스를 일으킨 명령어는, 해당 가상 주소에 대한 변환 정보가 없었기 때문에 다시 실행된다
  • 페이지 테이블 위치는 PTBR 레지스터로 확인
  • 빠르지만, 하드웨어가 복잡해지며 유연성이 떨어진다.
2. 운영체제가 처리하는 방식

-> RISC (reducedinstructionsetcomputing) 구조를 사용한다(예 : MIPS, SPARC)

  • 하드웨어는 단순히 "TLB_MISS" 예외를 발생시킨다.
  • 운영체제(소프트웨어)가 트랩 핸들러를 통해 :
    • 페이지 테이블에서 변환 정보를 찾아온다.
    • TLB에 넣는다.
    • 원래 명령어를 다시 실행한다.
  • 이 방식은 하드웨어는 단순하게, 대신 OS가 더 복잡하게 작동한다.
  • 유연성도 높고, 페이지 테이블 구조를 자유롭게 바꿀 수 있어요.

 

요약

 

  • TLB 미스를 처리한 후엔해당 명령어를 다시 실행해야한다.
  • 트랩 핸들러 실행 도중 또 미스 나면 안 되니까, 트랩 핸들러는 항상 TLB 히트 나게끔 처리해야 한다 (예: 물리 주소 사용 or TLB에 고정된 영역 할당)
  • 하드웨어 방식은 빠르지만 복잡, 소프트웨어 방식은 느릴 수 있지만 유연하고 간단하다.

 

 

📝TLB의 문제점

앞서 설명했듯이 TLB는 가상 주소를 물리 주소로 변환할 대 캐싱해서 빠르게 변환하도록 돕습니다.

TLB는 프로세스 고유의 주소 공간을 반영합니다. 그렇기에 문제가 발생합니다.

만약 문맥 교환 시에 이전 프로세스의 주소 변환 정보가 다음 프로세스에 잘못 사용된다면 어떻게 될까요?

 

예시를 들어봅시다.

  • P1의 VPN 10 → PFN 100
  • P2의 VPN 10 → PFN 170
  • 같은 VPN이라도 프로세스가 다르면 의미가 다릅니다. -> 혼란 발생 가능

 

문제 해결 방법

1. TLB 비우기 (Flush)

  • 문맥 교환 시, TLB의 valid bit를 모두 0으로 설정한다. → 캐시 무효화
  • 모든 주소 변환 캐시가 사라짐 → 안전하지만 성능 저하합니다. (TLB miss 증가)

2. ASID (Address Space Identifier) 사용

  • TLB 항목마다 ASID 필드 추가
  • 각 프로세스마다 고유 ASID를 할당 → TLB가 프로세스 별로 변환 정보를 구분 가능
  • 문맥 교환 시, ASID 레지스터만 변경하면 되므로 TLB flush 없이도 안정적

 

📝TLB의 교환 정책

이렇게 문맥 교환을 하는 방법을 알아보았다. 이제 TLB에서 데이터를 넣고 빼는 방법에 대해 알아보자.

쉽게 생각해보면 우리는 FIFO, LRU, Random을 생각할 수 있다.

일반 정책
  • LRU (Least Recently Used): 가장 오랫동안 사용되지 않은 항목 제거
    • 지역성 원칙에 기반
  • Random: 무작위 교체
    • 구현 간단, 특정 worst-case 피할 수 있음

 

📝요약 - 주소 변환의 하드웨어 가속과 TLB의 역할

 

  • TLB(Translation Lookaside Buffer)는 주소 변환 속도를 높이기 위한 작은 전용 캐시로, 대부분의 메모리 접근을 페이지 테이블 없이 처리할 수 있게 한다.
  • 이 덕분에 프로그램은 가상 메모리 사용의 오버헤드 없이 거의 동일한 성능을 낼 수 있으며, 페이징 시스템의 필수 요소가 되었다.
⚠️ TLB의 한계
  • TLB 용량을 초과하는 많은 수의 페이지에 짧은 시간 내 접근하면, TLB 미스가 자주 발생하여 성능이 급격히 저하될 수 있다.
  • 이를 TLB 범위(TLB Coverage)를 벗어난다고 표현하며, 특정 프로그램(예: DBMS 등 대규모 랜덤 접근을 하는 시스템)에서는 중요한 성능 이슈가 된다.
  • 해결책 중 하나는 더 큰 페이지 크기를 지원하는 것 → TLB가 더 넓은 주소 범위를 커버할 수 있게 된다.
🔧 TLB와 캐시의 병목
  • 물리적으로 인덱스된 캐시는 TLB를 먼저 접근해야 하므로, 캐시 접근 전 주소 변환이 병목이 될 수 있다.
  • 이를 해결하기 위해 가상 주소 기반 캐시(virtually indexed cache) 도 사용되지만, 하드웨어 설계 복잡성을 동반한다.

 

 

더보기

💡 구현 팁: "RAM은 항상 RAM이 아니다" (Culler’s Law)

  • RAM은 일반적으로 임의 접근 메모리(random access memory) 로 불리지만, 주소에 따라 접근 속도가 다를 수 있다.
  • 특히 TLB 미스가 발생하면 페이지 테이블 접근이 필요해지고, 기대보다 훨씬 느릴 수 있다.
  • 그래서 David Culler 교수는 “RAM은 항상 RAM이 아니다”는 개념을 강조했고, 이를 Culler's Law라고 부른다.