개발 공부

손승열(Son Seungyeol)

[운영체제][OSTEP] 변환 색인 버퍼

변환 색인 버퍼를 통해 주소 변환 속도를 향상시키는 방법에 대해 공부해봅니다.

손승열(Son Seungyeol)
[운영체제][OSTEP] 변환 색인 버퍼

🚪 들어가며

앞선 페이징 기법은 상당한 성능 저하를 가져올 수 있다.
➡️ 따라서 주소 변환 속도를 향상시킬 방법을 고민해보아야 한다.

운영체제의 실행 속도를 개선하려면 도움이 필요하다.
➡️ 대부분의 경우 하드웨어로부터 도움을 받는다.

주소 변환을 빠르게 하기 위해 변환-색인 버퍼(translation-lookaside buffer) 또는 TLB라는 것을 도입한다.

TLB는 칩의 메모리 관리부(memory-management unit, MMU)의 일부다.

TLB는 자주 참조되는 가상 주소-실주소 변환 정보를 저장하는 하드웨어 캐시로, 주소-변환 캐시(address-translation cache)라고도 불린다.

하드웨어는 먼저 TLB에 원하는 변환 정보가 있는지 확인한다.
➡️ 있는 경우 페이지 테이블을 통하지 않고 변환을 빠르게 수행한다.

실질적으로 TLB는 페이징 성능을 엄청나게 향상시킨다.
➡️ TLB를 도입함으로써, 페이징이 "사용 가능"한 가상 메모리 기법이 된다.


1️⃣ TLB의 기본 알고리즘

아래의 코드는 가상 주소 변환이 이루어지는 과정을 대략적으로 나타내고 있다.

c
VPN = (VirtualAddress & VPN_MASK) >> SHIFT
(Success, TlbEntry) = TLB_Lookup(VPN)
if (Success == True) // TLB ⯩✙
  if (CanAccess(TlbEntry.ProtectBits) == True)
    Offset = VirtualAddress & OFFSET_MASK
    PhysAddr = (TlbEntry.PFN << SHIFT) | Offset
    AccessMemory(PhysAddr)
  else
    RaiseException(PROTECTION_FAULT)
else // TLB 미스
  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_Insert(VPN, PTE.PFN, PTE.ProtectBits)
    RetryInstruction()

위의 예시에서는 주소 변환부가 단순한 선형 페이지 테이블(linear page table)하드웨어로 관리되는 TLB(하드웨어가 페이지 테이블 접근에 대한 대부분의 책임을 관리)로 구성되어 있다.

하드웨어 부분의 알고리즘의 동작은 다음과 같다.

  1. 가상 주소(line 1)에서 VPN 추출

  2. 해당 VPN의 TLB 존재 여부를 검사(line 2)

  3. 만약 존재하면 TLB 히트 = TLB가 변환 값을 갖고 있음.(line 3)

    1. 해당 TLB 항목에서 PFN를 추출할 수 있음.

    2. 해당 페이지에 대한 접근 권한 검사가 성공 시(line 4)

      1. 원래 가상 주소의 오프셋과 합쳐서 원하는 물리 주소(PA) 구성(line 5-6)

      2. ✅ 메모리에 접근(line 7)

  4. 만약 존재하지 않으면 TLB 미스 = TLB에 변환 정보 존재X(line 10)

    1. 하드웨어가 변환 정보를 찾기 위해 페이지 테이블에 접근(line 11-12)

    2. 프로세스가 생성한 가상 메모리 참조가 유효하고 접근 가능 시(line 17)

      1. ✅ 해당 변환 정보를 TLB로 읽어들임.(line 18)

        ➡️ ⚠️ 매우 시간이 많이 소요되는 작업

위에서 매우 시간이 많이 소요되게 되는 경우 그 이유는 페이지 테이블 접근을 위한 메모리 참조 때문임.(line 12)

TLB가 갱신되면 하드웨어는 명령어를 재실행한다.(line 19)
➡️ TLB에 변환 정보가 존재하므로 메모리 참조가 빠르게 처리됨.

💡 TLB 설계 철학
"주소 변환 정보가 대부분의 경우 캐시에 있다"(즉, 캐시에서 히트)라는 가정을 전제

TLB는 프로세싱 코어와 가까운 곳에 위치 & 매우 빠른 하드웨어로 구성
➡️ 주소 변환 작업은 그다지 부담스러운 작업X
➡️ ⚠️ 미스가 발생하는 경우, 페이징 비용이 커짐.

메모리 접근 연산은 다른 CPU연산에 비해 매우 시간이 오래 걸림.
➡️ TLB 미스가 발생하는 경우를 최대한 피해야 함.


2️⃣ 예제: 배열 접근

간단한 가상 주소 트레이스 예시를 통해 TLB로 인한 성능 개선을 알아보자.

이 예시에서는 가상 주소 100번지부터 10개의 4바이트 크기의 정수 배열이 존재한다고 가정하자.

가상 주소 공간은 8비트이며, 페이지 크기는 16바이트이다.

가상 주소는 4비트 VPN(16개의 가상 페이지 표현)과 4비트 오프셋(각 페이지는 16바이트 크기를 가짐)으로 구성된다.

아래는 이러한 16개의 페이지로 구성된 가상 주소 공간을 나타내고 있다.

                    Offset
        00     04     08     12     16
         ┌───────────────────────────┐
VPN = 00 │                           │ 
         ├───────────────────────────┤
VPN = 01 │                           │ 
         ├───────────────────────────┤
VPN = 02 │                           │ 
         ├───────────────────────────┤
VPN = 03 │                           │ 
         ├───────────────────────────┤
VPN = 04 │                           │ 
         ├───────────────────────────┤
VPN = 05 │                           │ 
         ├──────┬──────┬──────┬──────┤
VPN = 06 │      │ a[0] │ a[1] │ a[2] │ 
         ├──────┼──────┼──────┼──────┤
VPN = 07 │ a[3] │ a[4] │ a[5] │ a[6] │ 
         ├──────┼──────┼──────┼──────┤
VPN = 08 │ a[7] │ a[8] │ a[9] │      │ 
         ├──────┴──────┴──────┴──────┤
VPN = 09 │                           │ 
         ├───────────────────────────┤
VPN = 10 │                           │ 
         ├───────────────────────────┤
VPN = 11 │                           │ 
         ├───────────────────────────┤
VPN = 12 │                           │ 
         ├───────────────────────────┤
VPN = 13 │                           │ 
         ├───────────────────────────┤
VPN = 14 │                           │ 
         ├───────────────────────────┤
VPN = 15 │                           │ 
         └───────────────────────────┘

배열의 첫 항목(a[0])은 (VPN=06, 오프셋=04)에서 시작한다.

세 개의 4바이트 정수가 페이지에 들어갈 수 있다.

다음으로 배열 원소의 합을 구하는 간단한 코드를 살펴보자.

c
int sum = 0;
for (i = 0; i < 10; i++) {
  sum += a[i];
}

메모리 접근을 단순화하기 위해 변수 i, sum, 명령어를 위한 메모리 접근은 무시하자.

또한 TLB는 완전히 초기화되어 있다고 가정하자.

배열의 첫 번째 항목(a[0]) 접근: 가상 주소 100번
➡️ 하드웨어는 VPN 추출: VPN=06
➡️ 하드웨어는 TLB에서 해당 VPN을 검색: ⚠️ TLB 미스 발생
➡️ VPN=06에 대한 물리 페이지 번호를 찾아 TLB 갱신

배열의 두 번째 항목(a[1]) 접근
➡️ 하드웨어는 VPN 추출: VPN=07
➡️ 하드웨어는 TLB에서 해당 VPN을 검색: ✅ TLB 히트 발생(a[0]와 같은 페이지)

배열의 세 번째 항목(a[2]) 접근 ➡️ ✅ TLB 히트 발생(a[0], a[1]과 같은 페이지)

배열의 네 번째 항목(a[3]) 접근 ➡️ ⚠️ TLB 미스 발생

a[4] ~ a[6] 접근 ➡️ ✅ TLB 히트 발생(a[3]과 같은 페이지)

a[7] 접근 ➡️ ⚠️ TLB 미스 발생

a[8] ~ a[9] 접근 ➡️ ✅ TLB 히트 발생(a[7]과 같은 페이지)

즉, 정리하면 미스, 히트, 히트, 미스, 히트, 히트, 히트, 미스, 히트, 히트가 된다.

여기서 TLB 히트 비율(히트 횟수 / 총 접근 횟수)는 70%가 된다.
➡️ 배열이 처음으로 접근되었지만, TLB는 공간 지역성(spatial locality)으로 인해 성능을 개선할 수 있다.

배열의 항목들이 페이지 내에서 서로 인접해 있음.
➡️ 페이지에서 첫 번째 항목을 접근할 때만 TLB 미스가 발생

위의 예시를 통해 페이지의 크기는 TLB의 효용성에 매우 중요한 역할을 함을 알 수 있다.

일반적인 경우 페이지는 4KB임.

예시처럼 정수 배열을 연속적으로 접근하는 프로그램의 경우, TLB 사용은 큰 성능 개선 효과를 가져옴.

만약 예시의 프로그램이 루프 종료 후에도 배열을 사용한다면?
➡️ 모든 주소 변환 정보가 TLB에 탑재되어 있으므로 성능은 더욱 개선됨.

시간 지역성(temporal locality)으로 인해 TLB의 히트율이 높아짐.
🔖 시간 지역성: 한 번 참조된 메모리 영역이 짧은 시간 내에 재 참조되는 현상

다른 캐시와 마찬가지로 TLB의 성공 여부프로그램의 공간 지역성과 시간 지역성 존재 여부에 달려있음.
➡️ 실제로 많은 프로그램들이 공간 지역성이나 시간 지역성을 띄고 있음.


3️⃣ TLB 미스는 누가 처리할까

TLB 미스의 처리에는 두 가지 방법이 있다.

  1. 하드웨어

  2. 소프트웨어(운영체제)

과거 하드웨어는 복잡한 명령어들로 구성되어 있었음.
➡️ CISC(complex instruction set computers)라고 통칭했음.

TLB 미스를 하드웨어가 처리하도록 설계하는 경우 하드웨어가 페이지 테이블에 대한 명확한 정보를 가지고 있어야 함.

하드웨어로 관리되는 TLB로 구성된 1️⃣의 가상 주소 변환 코드의 11번째 줄의

c
PTEAddr = PTBR + (VPN * sizeof(PTE))

page-table base register를 통해서 메모리 상 위치와 정확한 형식을 파악해야 한다.

미스 발생 시 하드웨어는 다음과 같은 과정을 수행한다.

  1. 페이지 테이블에서 원하는 페이지 테이블 엔트리를 찾는다.

  2. 필요한 변환 정보를 추출한다.

  3. TLB를 갱신한다.

  4. TLB 미스가 발생한 명령어를 재실행한다.

인텔 x86 CPU가 하드웨어로 관리되는 TLB의 대표적인 예이다.
➡️ 멀티 레벨 페이지 테이블(multi-level page table)을 사용

CR3 레지스터가 페이지 테이블 주소를 갖고 있다.

RISC(reduced instruction set computing)는 CISC보다 최근에 등장한 컴퓨터 구조이다.
➡️ MIPS R10K나 Sun의 SPARC v9이 대표적인 예

RISC 기반 컴퓨터는 소프트웨어 관리 TLB(software-managed TLB)를 사용한다.

아래와 같이 운영체제가 관리하는 TLB 제어 흐름 알고리즘이 있을 때,

c
VPN = (VirtualAddress & VPN_MASK) >> SHIFT
(Success, TlbEntry) = TLB_Lookup(VPN)
if (Success == True) // TLB 히트
  if (CanAccess(TlbEntry.ProtectBits) == True)
    Offset = VirtualAddress & OFFSET_MASK
    PhysAddr = (TlbEntry.PFN << SHIFT) | Offset
    Register = AccessMemory(PhysAddr)
  else
    RaiseException(PROTECTION_FAULT)
else // TLB 미스
  RaiseException(TLB_MISS)

RISC 기반 컴퓨터에서 TLB 미스를 처리하는 과정은 다음과 같다.

  1. TLB에서 주소 찾는 것이 실패 ➡️ 하드웨어는 예외(exception) 시그널 발생(line 11)

  2. 시그널을 받은 운영체제는 명령어 실행을 잠정 중지

  3. 실행 모드를 커널 모드로 변경하여 커널 코드 실행을 준비

    1. 커널 주소 공간을 접근할 수 있도록 특권 레벨(privilege level)로 상향 조정

  4. 커널 모드로 변경되면 트랩 핸들러(trap handler)를 실행

    1. 이때 실행되는 트랩 핸들러는 TLB 미스의 처리를 담당하는 운영체제 코드

    2. 페이지 테이블을 검색하여 변환 정보 탐색

    3. TLB 접근이 가능한 "특권" 명령어(privileged instruction)을 사용하여 TLB 갱신

    4. 리턴

  5. 하드웨어가 명령어를 재실행

트랩 핸들러가 TLB를 갱신했으므로 이제는 TLB 히트가 발생

중요한 두 가지 사항을 다시 짚고 넘어가자!

[1] TLB 미스를 처리하는 트랩 핸들러는 시스템 콜 호출 시 사용되는 트랩 핸들러와 차이가 있다.

  • 시스템 콜 호출: 트랩 핸들러에서 리턴 후 시스템 콜을 호출한 명령어의 "다음" 명령어를 실행

    ➡️ 일반적인 프로시저 콜과 동일

  • TLB 미스 처리: 트랩에서 리턴 후 트랩을 발생시킨 명령을 "다시" 실행해야 함.

    ➡️ 재실행 시 TLB에서 히트 발생

트랩 발생 시 운영체제는 트랩 핸들러가 종료되었을 때 다시 실행을 계속할 명령어 주소(Program Counter 값)를 저장
➡️ 운영체제는 트랩 발생 원인에 따라 현재 명령어의 PC값 혹은 다음 명령어의 PC값을 저장해야 함.

[2] TLB 미스 핸들러를 실행할 때, TLB 미스가 무한 반복되지 않도록 주의해야 한다.

이는 TLB 미스 핸들러를 접근하는 과정에서 TLB 미스가 발생하는 상황이다.

이를 위한 해결책들을 살펴보자.

  • TLB 미스 핸들러를 물리 메모리에 위치시킨다.

    • TLB 미스 핸들러의 주소는 핸들러의 '물리' 주소로 표시됨.

    • 이 경우 해당 TLB 미스 핸들러는 unmap되어 있으며 주소 변환이 필요없음.

  • TLB의 일부를 핸들러 코드 주소를 저장하는 데 영구히 할당

    • TLB 핸들러는 항상 TLB에서 히트됨

      ➡️ 이를 연결(wired) 변환이라고 함.

✅ TLB를 소프트웨어로 관리하는 주된 장점1 = 유연성
➡️ 운영체제는 하드웨어 변경없이 페이지 테이블 구조를 자유로이 변경 가능

✅ TLB를 소프트웨어로 관리하는 주된 장점2 = 단순함
➡️ 1️⃣의 하드웨어 방식 코드(line 11-19)와 3️⃣의 소프트웨어 방식 코드(line 11)를 살펴보면 3️⃣에서 미스가 발생하였을 때 하드웨어는 별로 할 일이 없다.(운영체제의 TLB 미스 핸들러가 나머지 일을 처리)


4️⃣ TLB의 구성: 무엇이 있나?

일반적인 TLB는 32, 64, 또는 128개의 엔트리를 가지며, 완전 연관(fully associative) 방식으로 설계된다.

완전 연관 방식에서 변환 정보는 TLB 내에 어디든 위치할 수 있음.

원하는 변환 정보를 찾는 검색은 TLB 전체에서 병렬적으로 수행됨.

TLB의 구성은 아래와 같다.

VPN | PFN | 다른 비트들

변환 정보 저장 위치에 제약이 없도록 각 항목마다 VPN과 PFN가 있음.

하드웨어 측면에서 TLB는 완전 연관 캐시임.
➡️ 변환 주소를 찾을 때, 하드웨어는 TLB의 각 항목을 동시에 검색

TLB의 "다른 비트들"에는 다음과 같은 비트들이 포함된다.

  • Valid bit: 특정 항목이 유효한 변환 정보를 갖고 있는지 여부 표시

  • Protection bit: 페이지가 어떻게 접근될 수 있는지 표시

    ➡️ 페이지 테이블과 쓰임이 같음.

  • 주소 공간 식별자(address-space identifier)

  • 더티 비트(dirty bit)

⚠️ TLB valid bit ≠ 페이지 테이블 valid bit

페이지 테이블에서 어떤 페이지 테이블 항목(page-table entry, PTE)이 "무효"로 표시되어 있음.
➡️ 해당 페이지는 프로세스에 할당되지 않았다는 것을 의미
➡️ 정상적인 프로그램은 해당 페이지를 접근하지 않음.(접근 시 운영체제는 트랩 발생)

TLB의 valid bit는 TLB에 탑재되어 있는 해당 변환 정보가 유효한지를 나타냄.
➡️ 시스템 시작 시 어떤 변환 정보도 아직 캐시되지 않았으므로 일반적으로 TLB의 모든 항목은 "무효"로 초기화되어 있음.
➡️ 가상 메모리가 초기화되고 프로그램들이 실행 시작되면, TLB는 서서히 채워짐.
➡️ 문맥 전환 시 상당히 유용: 문맥 전환 시, 시스템은 모든 TLB 항목을 "무효"로 세팅하여 새로운 프로세스가 이전 프로세스의 변환 정보를 사용하는 것을 원천적으로 차단


5️⃣ TLB의 문제: 문맥 교환

TLB 사용 시 프로세스 간(주소 공간들로 인해) 문맥 교환 시 새로운 문제 등장

TLB에 있는 가상 주소 ↔️ 실제 주소 간 변환 정보 ➡️ 그것을 탑재시킨 프로세스에서만 유효

⚠️ 새로운 프로세스에서는 이전에 실행하던 프로세스의 변환 정보를 사용하지 않도록 주의해야 함.

하나의 프로세스(P1)가 실행 중인 다음의 예시를 살펴보자.

  • TLB는 P1의 페이지 테이블 내용을 캐싱하고 있음.

  • P1의 10번째 가상 페이지가 물리 프레임 100에 매핑되어 있음.

  • 또 다른 프로세스(P2)의 10번째 가상 페이지는 물리 프레임 170에 매핑되어 있음.

  • 두 프로세스의 항목들이 TLB에 존재함.

이때, 운영체제가 P1에서 또 다른 프로세스(P2)로 문맥 교환을 수행하는 경우 TLB의 내용은 다음과 같이 될 것이다.

VPN   PFN   valid   prot
────────────────────────
10    100     1     rwx
--    ---     0     ---
10    170     1     rwx
--    ---     0     ---

⚠️ 즉, VPN 10에 대한 변환 정보가 두 개 존재하는 문제가 있다.
➡️ VPN이 PFN 100(P1)과 PFN 170(P2)으로 변환될 수 있음.

하지만 어떤 프로세스를 위한 항목인지 알 길이 없다.
➡️ TLB가 정확하고 효율적으로 멀티 프로세스 간의 가상화를 지원하기 위해서는 추가적인 기능이 필요

이 문제에 대한 여러가지 해법 중 한 가지를 살펴보자.

💡 문맥 교환을 수행 시, 다음 프로세스가 실행되기 전에 기존 TLB의 내용을 비우기

소프트웨어 기반의 시스템에서는 특별한(& 특권을 갖는) 하드웨어 명령어를 사용하여 이를 달성할 수 있음.

하드웨어로 관리되는 TLB페이지 테이블 베이스 레지스터가 변경될 때 비우기를 시작할 수 있음.
➡️ 운영체제는 문맥 교환을 할 때 PTBR을 어쨌든 변경해야 함.

두 경우 모두 모든 valid bit를 0으로 설정하여 내용을 비움.

⚠️ 이 방법의 경우 새로운 프로세스가 실행될 때, 데이터와 코드 페이지에 대한 접근으로 인한 TLB 미스가 발생하게 됨.

⚠️ 문맥 교체가 빈번히 발생한다면, 이 또한 성능에 큰 부담을 가져올 수 있음.

✅ 이 부담을 개선하기 위해 몇몇 시스템에서는 문맥 교환이 발생하더라도 TLB의 내용을 보존할 수 있는 하드웨어 기능을 추가
➡️ TLB 내에 주소 공간 식별자(address space identifier, ASID) 필드를 추가

ASID는 프로세스 식별자(process identifier, PID)와 대략적으로 유사
➡️ ASID는 좀 더 적은 비트를 가짐.

위의 TLB 예시에 ASID 정보를 추가하면 프로세스들이 TLB 공간을 공유할 수 있다.

다음은 ASID 필드를 추가한 TLB의 모습을 나타낸다.

VPN   PFN   valid   prot   ASID
───────────────────────────────
10    100     1     rwx     1
--    ---     0     ---     -
10    170     1     rwx     2
--    ---     0     ---     -

주소 공간 식별자를 사용할 경우, 프로세스 별로 TLB 변환 정보를 구분할 수 있다.

올바른 주소 변환을 위해서 하드웨어는 현재 어떤 프로세스가 실행 중인지 파악해야 함.
➡️ 문맥 전환 시, 운영체제는 새로운 ASID 값을 정해진 레지스터에 탑재

다음의 예시처럼 TLB의 두 항목이 매우 유사한 경우를 생각해 볼 수도 있다.

VPN   PFN   valid   prot   ASID
───────────────────────────────
10    101     1     r-x     1
--    ---     0     ---     -
50    101     1     r-x     2
--    ---     0     ---     -

이러한 경우는 두 개의 프로세스들이 하나의 페이지(코드 페이지 등)를 공유하고 있을 때 발생할 수 있음.

바이너리에서든 공유 라이브러리든 코드 페이지를 공유하는 것은 사용되는 물리 페이지의 수를 줄일 수 있기 때문에 유용함.

공유 페이지를 사용하면 메모리 부하도 줄일 수 있음.


6️⃣ 이슈: 교체 정책

다른 모든 캐시처럼 TLB에서도 캐시 교체(cache replacement) 정책이 매우 중요

TLB에 새로운 항목 탑재 시, 현재 존재하는 항목 중 하나를 교체 대상으로 선정해야 한다.
➡️ 목표는 교체 시 미스율을 줄이거나 히트 비율을 증가시켜서 성능을 개선하는 것

다음의 두 가지 정책을 살펴보자.

[1] 최저 사용 빈도(least-recently-used, LRU) 항목을 교체하는 것

LRU는 메모리 참조 패턴에서 지역성을 최대한 활용하는 것이 목적

사용되지 않은지 오래된 항목일수록 앞으로도 사용될 가능성이 작으므로 교체 대상으로 적합하다는 가정에 근거

[2] 랜덤(random) 정책

교체 대상을 무작위로 정한다.
➡️ 때때로 잘못된 결정을 내릴 수도 있지만, 구현이 간단하고 예상치 못한 예외 상황의 발생을 피할 수 있다는 장점이 있다.

예를 들어, n개의 변환 정보를 저장할 수 있는 TLB가 n+1 페이지들에 대해서 반복문을 수행하는 프로그램의 경우

  • LRU 정책: 최악의 TLB 미스를 생성(모든 접근에 대해 미스를 유발)

  • 랜덤 정책: 이러한 경우 훨씬 더 잘 동작


7️⃣ 실제 TLB

MIPS R4000을 통해 실제 TLB가 어떻게 생겼는지 간략히 알아보자.

MIPS R4000은 소프트웨어로 관리되는 TLB를 사용한다.
➡️ TLB를 갱신하기 위한 명령어가 필요

MIPS는 네 개의 명령어를 제공

  • TLBP: 어떤 특정 변환 정보가 존재하는지 탐색하는 데 사용

  • TLBR: TLB 항목의 내용을 레지스터로 읽어들이는데 사용

  • TLBWI: 특정 TLB 항목을 교체

  • TLBWR: 임의의 TLB 내용을 교체

운영체제는 이 명령어들을 사용하여 TLB의 내용을 관리

이 명령어들은 특별한 실행권한(privileged)을 갖고 있어야 함.
➡️ 사용자 프로세스의 TLB 내용 변경을 방지

MIPS의 간략화된 TLB 항목은 다음과 같다.

0 ... 2 ... 18 19  20 ... 23 24 25 26 27 28 29  30   31 
┌─────────────┬───┬─────────┬──────────────────────────┐
│     VPN     │ G │*********│          ASID            │
├────┬────────┴───┴─────────┴─────┬────────┬───┬───┬───┤
│****│            PFN             │    C   │ D │ V │***│
└────┴────────────────────────────┴────────┴───┴───┴───┘

MIPS R4000은 32비트 주소 공간에 4KB 페이지를 지원한다.

VPN이 20비트를 가질 것이라는 예측과 달리 전체 주소 공간의 절반만 사용자 주소 공간으로 할당되어 있고 나머지 반은 커널이 사용하기 때문에 VPN에는 19비트가 할당되어 있다.

물리 프레임 번호(PFN)로 24비트가 할당되어 있어서 64GB (물리) 주 메모리(2^24개의 4KB 페이지들) 지원이 가능하다.

MIPS의 TLB에 존재하는 몇 가지 중요한 비트들을 살펴보자.

  • 전역(global) 비트 (G): 프로세스들 간 공유되는 페이지들을 위해 사용

    ➡️ 전역 비트가 설정되어 있으면 ASID는 무시됨.

  • ASID 필드(8비트): 운영체제가 이를 통해 주소 공간들을 서로 구분

    ➡️ 만일 256(2^8)개 이상의 프로세스들이 동시에 실행된다면?

  • 일관성(coherence, C) 비트(3비트): 페이지가 하드웨어에 어떻게 캐시되어 있는지 판별

  • 더티(dirty, D) 비트: 페이지가 갱신되면 세팅됨.

  • 유효(valid, V) 비트: 항목에 유효한 변환 정보가 존재하는지 표시

  • 페이지 마스크(page mask) 필드(위에 표시X): 여러 개의 페이지 크기를 지원할 때 사용

  • 마지막 *** 처리된 64번째 비트는 사용X

MIPS의 TLB들은 일반적으로 32개 또는 64개의 항목으로 구성됨.
➡️ 대부분은 사용자 프로세스들이 사용 & 몇 개는 운영체제를 위해서 예약

예약된 항목은 운영체제에 의해서 연결된(wired) 레지스터가 설정될 수도 있음.

운영체제는 몇 개의 TLB를 예약할지를 하드웨어에게 알림.

운영체제는 예약된 매핑 영역을 TLB 미스 핸들러 등 TLB 미스가 발생해서는 안 되는 코드와 데이터를 위해서 사용


🧺 변환 색인 버퍼 정리 하기

TLB를 통해 대부분의 메모리 참조들은 메인 메모리 상의 페이지 테이블을 읽지 않고도 처리가 가능

TLB의 사용으로 일반적인 경우에 프로그램은 메모리 가상화 기능이 없는 것과 동일한 성능 보임.
➡️ 운영체제 입장에서 훌륭한 성과 & 현대 시스템에서 페이징을 사용하기 위한 필수 요소

⚠️ TLB가 모든 프로그램에서 항상 제대로 작동하는 것은 아님.
➡️ 특히, (프로그램이 짧은 시간 동안 접근하는 페이지들의 수 > TLB에 들어갈 수 있는 수)의 경우 해당 프로그램은 많은 수의 TLB 미스를 발생시키고 느리게 동작

이와 같은 현상을 TLB 범위(TLB coverage)를 벗어난다고 함.
➡️ 특정 프로그램들에서는 중요한 문제가 될 수도 있음.

더 큰 페이지들을 사용할 경우 TLB의 유효 범위가 늘어날 수 있음.
➡️ 이러한 지원은 DBMS와 같은 프로그램에 의해서 주로 사용됨.
➡️ 이러한 프로그램의 자료 구조들은 클 뿐만 아니라 임의적으로 접근됨.

⚠️ CPU 파이프라인에서 TLB 접근은 병목이 될 수 있음.
➡️ 물리적으로 인덱스된 캐시(physically-indexed cache)가 사용될 경우 특히 문제가 됨.

위 캐시에서는 주소 변환이 캐시 접근 전에 이루어져야 함 ➡️ 상당히 느려질 수 있음.

따라서 가상 주소로 캐시를 접근하는 다양한 방법들이 고안됨.
➡️ 캐시 히트가 발생한 경우, 비용이 많이 드는 변환을 하지 않도록 함.

가상적으로 인덱스된 캐시(virtually indexed cache)는 일부 성능 문제를 해결
➡️ ⚠️ 새로운 하드웨어 설계 문제들을 수반


📚 참고 문헌

Operating Systems: Three Easy Pieces ― 19: Paging: Faster Translations (TLBs)

운영체제 아주 쉬운 세 가지 이야기 ― 22: 페이징: 더 빠른 변환 (TLB)

관련있는 게시물


Made with React, Gatsby and DatoCMS by @smastrom

Contribute or star on GitHub

© 2022-2023 손승열 for 🅒🅞🅝🅣🅔🅝🅣🅢

모두 좋은 하루 보내세요! 😊