9. Main Memory

이 장에서는 메모리 관리 방법을 다룬다. 메모리 관리 알고리즘은 직접 기계와 맞닿는 접근법부터 페이징을 쓰는 방법까지 여러 가지이다. 각 접근법은 각각의 장단점이 있다. 특정 시스템에 대한 메모리 관리 방법을 선택하는 것은 여러 인자에 달렸는데 대개 하드웨어 디자인에 달려 있다. 많은 알고리즘은 하드웨어 지원을 필요로 하므로 운영체제는 하드웨어와 밀접하게 연계되어 있다.

9.1. Background

메모리는 현대 운영 체제의 중심이다. CPU는 메모리에서 명령어를 가져온다. 이러한 명령어들을 사용하기 위해서는 특정 메모리 주소에 대해 저장과 로드를 해야 한다. 여기서는 프로그램이 메모리 주소를 어떻게 생성하는지는 신경쓰지 말고 그 메모리 주소 자체에 대해서만 논해 보도록 하자. 기본 하드웨어, 가상 메모리 주소와 실제 물리적 메모리 주소간의 바인딩, 논리적 주소와 물리적 주소간의 구분, 동적 링킹과 공유 라이브러리에 대해 다룬다.

9.1.1. Basic Hardware

CPU가 직접적으로 접근할 수 있는 일반 용도 저장소는 메인 메모리와 레지스터뿐이고, 기계 명령어는 디스크 주소를 인자로 갖지 않는다. CPU 코어에 있는 레지스터는 CPU 클럭의 한 사이클 안에 접근 가능하다. 메인 메모리는 그렇지 않으므로 프로세서는 메모리 접근 시에는 대기하게 된다. 그래서 이를 해결하기 위해 CPU와 메인 메모리 사이에 (대개 CPU 칩에) 캐시를 둬서 메모리 접근을 빠르게 할 수 있다. 시스템 동작의 정확성을 보장하기 위해, 사용자 프로세스의 접근으로부터 운영 체제를 보호해야 하는데, 운영 체제는 CPU의 메모리 접근을 간섭하지 않기 때문에 (그러면 성능 저하가 일어나므로) 이는 하드웨어에 의해 제공되어야 한다. 먼저 각 프로세스가 각각의 메모리 공간을 갖도록 해야 한다. 이는 기본 레지스터한계 레지스터에 의해 정의되는 메모리 구간을 갖는다. 허용되지 않은 메모리를 접근하려는 시도는 운영 체제의 트랩을 불러일으켜서 다른 프로세스나 운영 체제를 보호한다. 기본 레지스터와 한계 레지스터 설정은 운영 체제만이 가능하다. 운영 체제는 운영 체제 메모리와 사용자 메모리에 대한 제한 없는 접근 권한을 가짐으로써 사용자 프로그램을 사용자 메모리에 로드하고, 프로그램을 에러 시 덤프하고, 시스템 호출의 인자에 접근/수정을 하고, 입출력을 수행하고, 컨텍스트 스위칭을 하고, 이외의 많은 서비스를 수행할 수 있다.

9.1.2. Address Binding

대개 프로그램은 디스크에 바이너리 실행 파일로 존재하며, 실행되기 위해서는 메모리에 로딩되어 프로세스의 컨텍스트에 위치해야 한다. 프로그램이 실행될 때엔 메모리에서 명령어와 데이터를 접근한다. 프로세스가 종료되면 메모리를 반납하여 다른 프로세스가 사용할 수 있게 한다. 많은 시스템은 사용자 프로세스가 물리적 메모리의 어떤 부분에도 머무를 수 있게 한다. 소스 프로그램 내의 주소값은 변수에 의해 나타내어지는 상징적 값인데, 대개 컴파일러가 이를 재배치 가능한 주소로 바인딩한다. 링커나 로더는 이 재배치 가능한 주소를 절대 주소로 바인딩한다. 명령어와 데이터의 이러한 메모리 주소로의 바인딩은 다음 단계에 이루어진다.

  • 컴파일 시점. 프로세스가 메모리 상 어디에 자리잡을 지 컴파일 시점에 알 수 있다면 절대 코드가 생성될 수 있다.
  • 로드 시점. 프로세스가 메모리 상 어디에 자리잡을 지 컴파일 시점에 알 수 없다면 컴파일러는 재배치 가능한 코드를 생성해야 한다. 이 경우 마지막 바인딩은 로드 시간까지 지연된다.
  • 실행 시점. 프로세스가 실행 중 다른 메모리 부분으로 이동할 수 있다면 바인딩은 실행 시점까지 지연되어야 한다. 대부분의 운영 체제는 이 방법을 사용한다.

이 장에서는 여러 바인딩 방법을 알아본다.

9.1.3. Logical Versus Physical Address Space

CPU에 의해 생성되는 주소는 논리적 주소메모리 주소 레지스터에 로드되는 주소는 물리적 주소이다. 컴파일 시점이나 로드 시점에 주소가 바인딩되면 논리적 주소와 물리적 주소가 같지만, 실행 시점에 바인딩되면 논리적 주소는 가상 주소가 된다. 프로그램의 논리적 주소 집합은 논리적 주소 공간이라 하고, 이에 대응하는 물리적 주소 집합을 물리적 주소 공간이라 한다. 실행 시점에 주소가 바인딩되면 이 둘은 다르며, 하드웨어 기기에 의한 실행 시점 바인딩은 메모리 관리 유닛(MMU)에 의해 이루어진다. 이 때 기본 레지스터는 재배치 레지스터로 불린다. 사용자 프로그램은 절대 실제 물리적 주소에 접근하지 않고, 논리적 주소만 다룬다.

9.1.4. Dynamic Loading

프로세스가 실행되려면 프로그램과 프로세스의 데이터가 물리적 메모리에 로딩되어야 하므로, 프로세스의 크기는 물리적 메모리의 크기보다 작아야 한다. 메모리 공간 활용을 높이기 위해서는 동적 로딩을 사용해 루틴을 호출 시점까지는 로딩되지 않게 한다. 모든 루틴은 재배치 가능한 로드 포맷으로 디스크에 존재하여, 메인 프로그램이 호출 시에 메모리에 로드되어 프로그렘의 주소 테이블은 이를 반영한다. 이는 프로그램의 크기가 크더라도 사용 메모리는 크지 않도록 한다. 동적 로딩은 운영 체제의 특수한 지원을 필요로 하지 않으며, 이 방법의 이득을 보게 하는 것은 프로그램 제작자의 몫이다.

9.1.5. Dynamic Linking and Shared Libraries

동적 링크 라이브러리 (DLLs)은 사용자 프로그램이 실행 중일 때 링크되는 시스템 라이브러리이다. 어떤 운영 체제들은 시스템 라이브러리가 다른 오브젝트 모듈과 똑같이 취급되어 로더에 의해 프로그램에 병합되는 정적 링킹만 지원한다. 이에 비해 동적 링킹의 링크는 실행 시점까지 지연된다. 이런 특성은 대개 시스템 라이브러리들에 대해 지원되며, 이것 없이는 실행 파일의 크기가 커질 뿐만 아니라 메인 메모리를 낭비하게 된다. 또한 동적 링킹은 하나의 라이브러리가 여러 프로세스에 의해 사용될 수 있다는 장점도 있다. 이로 인해 DLL은 공유 라이브러리라고도 하며, 윈도우와 리눅스 시스템에서 폭넓게 쓰인다.

프로그램이 동적 라이브러리에 있는 루틴을 참조할 때는 로더는 DLL을 필요하다면 메모리에 불러오고 동적 라이브러리 내의 참조된 함수들의 주소를 DLL이 로드된 메모리 주소에 맞게 조정한다. 동적 링크된 라이브러리는 라이브러리 업데이트로 확장될 수 있고 새 버전으로 대체될 수 있다. 동적 로딩과 다르게 동적 링킹과 공유 라이브러리는 운영 체제의 도움을 필요로 한다. 프로그램의 메모리에 로딩해야 하기 때문이다.

9.2. Contiguous Memory Allocation

메인 메모리는 운영 체제와 여러 사용자 프로세스를 위한 공간을 제공해야 하므로 메모리를 효율적으로 할당해야 한다. 대개 운영 체제는 높은 메모리 주소에 할당되며, 연속된 메모리 할당에서는 각 프로세스가 다음 프로세스와 인접해 연속적으로 할당된다.

9.2.1. Memory Protection

프로세스는 배정된 메모리만 사용해야 한다. CPU 스케쥴러가 실행될 프로세스를 고를 때 디스패쳐는 재배치와 한계 레지스터를 컨텍스트 스위치 시에 알맞은 값으로 설정한다. 이는 운영 체제의 크기를 동적으로 효율적으로 변경될 수 있게 한다.

9.2.2. Memory Allocation

프로세스를 위해 메모리를 할당하는 가장 간단한 방법은 프로세스를 메모리에 가변 크기 분할로 할당하는 가변 분할이다. 이 때 운영 체제는 메모리의 어떤 부분이 사용 가능한지/사용 중인지를 지시하는 테이블을 유지한다. 초기에는 가용 메모리의 큰 단일 블록 ()로 구성된다. 프로세스의 요청을 수용할 만한 메모리가 없으면 프로세스는 기각되거나 대기 큐로 배치된다. 이를 어떻게 배치할지에 대한 동적 저장소 할당 문제는 여러 해가 있다.

  • 최초 적합. 충분히 큰 첫 번째 홀을 할당한다.
  • 최고 적합. 충분히 큰 홀들 중 가장 작은 것을 할당한다.
  • 최악 적합. 가장 큰 홀을 할당한다.

최초 적합이나 최고 적합이 낫다. 둘 중에서는 딱히 무엇이 더 낫지는 않지만 최초 적합이 대개 더 빠르다.

9.2.3. Fragmentation

최초 적합과 최고 적합은 모두 외부 파편화 문제를 겪는다. 프로세스가 메모리에 로드되고 해제됨으로써 가용 메모리 공간은 연속적이지 않은 작은 조각들로 나뉘어진다. 최초 적합의 경우 N 할당 블록에 대해 0.5N 블록이 파편화로 인해 손실될 수 있음을 보이는데, 이를 50퍼센트 규칙이라 한다. 메모리 파편화는 분할 내부에서 존재할 수도 있는데 이를 내부 파편화라 한다. 외부 파편화에 대한 하나의 해답은 컴팩트화로, 메모리를 뒤섞어서 가용 메모리를 하나의 큰 블록으로 합치는 것이다. 재배치가 정적이고 어셈블리나 로드 타임에 될 경우 이는 가능하지 않다. 동적으로 주소가 재배치된다면 이는 가능하다. 컴팩트화가 가능한 경우에도 그 비용을 잘 따져봐야 한다. 또 다른 방법은 프로세스의 논리적 주소 공간을 불연속적으로 하는 페이징 방법으로, 가장 흔한 메모리 관리 방법이다.

9.3. Paging

여기서는 프로세스의 물리적 메모리 주소가 비연속적이 되도록 허용하는 페이징을 다룬다. 이는 외부 파편화를 막고 컴팩트화의 필요성도 없애므로 널리 쓰인다.

9.3.1. Basic Method

페이징을 구현하는 기본적 방법은 물리적 메모리를 프레임이라는 고정 크기 블록으로 분해하고 논리적 메모리를 페이지라는 같은 크기 블록으로 분해하는 것으로 이루어진다. 프로세스가 실행될 때 그 페이지는 가용 메모리 프레임에 로딩된다. CPU에 의해 생성되는 모든 주소는 페이지 번호(p)와 페이지 오프셋(d)으로 이루어져 있다. 페이지 번호는 프로세스별 페이지 테이블의 인덱스로 쓰인다. MMU는 CPU에 의해 생성된 논리적 주소를 물리적 주소로 다음과 같이 바꾼다:

  1. 페이지 번호 p를 추출해 페이지 테이블의 인덱스로 쓴다.
  2. 페이지 테이블에서 해당하는 프레임 번호 f를 추출한다.
  3. 논리적 주소 내 페이지 번호 p를 프레임 번호 f로 치환한다.

오프셋 번호는 치환되지 않는다. 페이지 크기는 하드웨어에 의해 결정되며 대개 2의 승수로, 4KB~1GB 사이이다. 페이징은 그 자체로 동적 재배치이다. 페이징을 쓰면 외부 파편화를 걱정할 필요가 없지만, 내부 파편화의 가능성은 존재한다. 이 기대값은 페이지 크기의 절반 정도이므로, 페이지 크기는 작은 것이 좋지만, 페이지 테이블 번호의 오버헤드를 줄이고 디스크 입출력을 효율화하기 위해서는 페이지 크기가 큰 것이 좋으므로, 적절한 균형이 필요하다. 그래서 운영 체제는 기본 페이지 크기와 큰 페이지 크기를 지원한다. 페이지 내에서 담고 있어야 하는 정보들이 있으므로 페이지 내 가용 메모리는 페이지 크기보다 작다.

프로세스가 시스템에 실행을 위해 도착하면 페이지 크기로 나타내어진 프로세스의 크기가 조사되어 그 페이지 수만큼의 프레임이 할당된다. 페이징의 중요한 점은 프로그래머의 관점에서의 메모리와 실제 물리적 메모리를 분리한다는 것이다. 이 물리적 메모리의 할당 세부 요소는 운영 체제가 알고 있어야 하며, 이는 프레임 테이블에 저장된다. 각 프로세스의 페이징 정보를 운영 체제가 알고 있어야 하므로, 페이징은 컨텍스트 스위치 시간을 증가시킨다.

9.3.2. Hardware Support

페이지 테이블에 대한 포인터는 각 프로세스의 프로세스 제어 블록에 다른 레지스터들과 함께 저장된다. 페이지 테이블의 하드웨어 구현은 여러 방법으로 될 수 있다. 이는 빠른 레지스터로 구현될 수도 있지만, 컨텍스트 스위치를 증가시키고 큰 페이지 테이블에 대해서는 불가능하다. 그러므로 그 대신 페이지 테이블을 메인 메모리에 유지시키고, 페이지 테이블 기본 레지스터(PTBR)가 페이지 테이블을 가리키게 한다. 이는 페이지 테이블을 바꿀 때 한 레지스터만 바꾸면 되므로 컨텍스트 스위치 시간을 감소시킨다.

9.3.2.1. Translation Look-Aside Buffer

페이지 테이블을 메인 메모리에 저장하면 컨텍스트 스위칭 시간은 빨라지지만 메모리 접근 시간은 2배로 느려진다. 이에 대한 해법은 변환 색인 버퍼(TLB)라는 하드웨어 캐시를 이용하는 것이다. 현대 하드웨어에서 변환 색인 버퍼에 대한 탐색은 명령어 파이프라인의 일부분이므로 성능 저하가 없으며, 이를 위해서는 변환 색인 버퍼의 크기는 작아야 한다. 페이지 번호가 변환 색인 버퍼에 없으면 (TLB 미스) 메모리에 접근한 뒤 그 페이지 번호와 프레임 번호를 변환 색인 버퍼에 추가한다. 변환 색인 버퍼가 꽉 차있으면 그 중 하나가 대체된다. 이 때 키 커널 코드 같은 경우는 묶여서 대체되지 않는다.

어떤 변환 색인 버퍼는 주소 공간 식별자(ASIDs)를 각각 변환 색인 버퍼 엔트리에 저장하기도 한다. 이는 각 프로세스를 식별해 주소 공간을 보호한다. 변환 색인 버퍼가 이를 지원하지 않는다면 새 페이지 테이블이 선택될 때마다 플러시되어 다음 프로세스가 잘못된 변환 정보를 참조하지 않도록 보장해야 한다. 변환 색인 버퍼에서 요구 페이지 번호가 찾아지는 비율을 히트율이라 한다. 이를 이용해 유효 메모리 접근 시간을 계산할 수 있다. 현대 CPU는 복수 계층의 변환 색인 버퍼를 제공한다. 주소 공간 식별자는 하드웨어의 특성이지만 운영체제의 페이징 구현과도 밀접하게 연관되어 있다.

9.3.3. Protection

페이지 환경의 메모리 보호는 각 프레임에 연관된 보호 비트에 의해 이루어진다. 이는 읽기-쓰기 가능인지 읽기 전용인지를 정의한다. 읽기 전용 페이지에 쓰기를 시도하면 트랩이 일어난다. 보호 비트의 값 종류를 더 다변화시킬 수도 있다. 또한, 페이지 테이블 내 각 엔트리에 유효-무효 비트가 존재하여 연관 페이지가 프로세스의 논리적 주소 공간에 있는지를 결정한다. 이는 내부 파편화를 야기하기도 한다. 어떤 시스템은 페이지 테이블 길이 레지스터(PTLR)의 형태로 하드웨어를 제공해 페이지 테이블의 크기를 나타내기도 한다. 이는 주소가 프로세스의 허용 범위 내에 있는지를 판정한다.

9.3.4. Shared Pages

페이징의 이점은 여러 프로세스간에 libc 등의 재진입 가능 코드를 공유시킬 수 있다는 것이다. 이는 읽기 전용이어야 하며 운영 체제가 이것을 강제한다.

9.4. Structure of the Page Table

페이지 테이블의 구조를 알아보자.

9.4.1. Hierarchical Paging

큰 주소 공간을 지원하는 현대 컴퓨터 시스템에서는 페이지 테이블 자체가 커질 수 있으므로 이를 계층화한다. 이를 전방 매핑된 페이지 테이블이라 한다. 그러나 64비트 아키텍쳐에서는 계층화된 페이지 테이블은 적절하지 않다.

9.4.2. Hashed Page Tables

32비트보다 큰 주소 공간을 다루는 하나의 방법은 해시 페이지 테이블을 이용하는 것이다. 이는 가상 페이지 번호를 해시 값으로 사용한다. 이 외에도 해시 테이블 내 각 엔트리가 단일 페이지 대신 여러 페이지를 가리키는 클러스터된 페이지 테이블도 사용한다. 이는 희박한 주소 공간에 대해 유용하다.

9.4.3. Inverted Page Tables

각 페이지 테이블은 많은 엔트리를 가질 수 있기 때문에 물리적 메모리 사용을 추적하기 위해서만으로도 큰 크기만큼의 물리적 메모리를 필요로 한다. 이를 위해 반전 페이지 테이블을 사용하는데, 이는 메모리 내 각 페이지에 대해 한 엔트리를 갖는다. 그러므로 시스템 내에 하나의 페이지 테이블만이 존재한다. 이는 각 페이지 테이블을 저장하기 위한 메모리의 크기는 감소시키지만, 페이지 참조 때마다 테이블을 탐색하는 시간은 증가한다는 단점이 있다. 반전 페이지 테이블은 물리적 주소로 정렬을 하지만, 탐색은 가상 주소로 탐색을 하기 때문이다. 이를 위해 해시 테이블을 사용하고는 한다.

반전 페이지 테이블의 흥미로운 특성은 공유 메모리에 대한 것이다. 반전 페이지 테이블에서 물리적 페이지는 둘 이상의 공유 가상 주소를 가질 수 없으므로 메모리를 공유하는 다른 프로세스에 의한 참조는 페이지 폴트를 낳고 다른 가상 주소로의 매핑을 필요로 한다.

9.4.4. Oracle SPARC Solaris

SPARC에서 구동되는 Solaris는 해시 페이지 테이블을 잘 이용한 64비트 운영 체제의 사례로, 중간에 변환 색인 버퍼를 두는 변환 색인 버퍼 탐색을 쓴다.

9.5. Swapping

프로세스나 그 일부분은 메모리 밖의 보조 기억으로 교환될 수 있다. 이는 전체 물리적 주소 공간을 크게 할 수 있게 한다.

9.5.1. Standard Swapping

표준 교환은 전체 프로세스를 메인 메모리에서 보조 저장소로 교환한다. 이 보조 저장소는 바른 2차 저장소이며, 크기가 충분히 커야 한다. 유휴 프로세스는 교환의 좋은 대상이다.

9.5.2. Swapping with Paging

현대 운영 체제에서 표준 교환은 대개 잘 사용되지 않는다. 전체 프로세스를 옮기는 비용이 크기 때문이다. 그 대신에 대개 프로세스의 페이지만 페이지 아웃페이지 인을 이용해 교환한다.

9.5.3. Swapping on Mobile Systems

모바일 운영 체제는 페이지 교환을 쓰지 않고 플래시 메모리를 사용한다. 가용 메모리가 적고 플래시 메모리에 쓰는 빈도가 낮기 때문이다. 안드로이드는 애플리케이션 상태를 플래시 메모리에 쓴다. 그러므로 모바일 환경에서의 메모리 관리는 중요하다.

9.6. Example: Intel 32- and 64-bit Architectures

이 절에서는 IA-32와 x86-64 아키텍쳐에서의 주소 변환을 알아본다.

9.6.1. IA-32 Architecture

IA-32에서의 메모리 관리는 세그멘테이션과 페이징으로 나뉘어진다. CPU는 논리적 주소를 세그멘테이션 유닛으로 생성하고 이는 각 논리적 주소에 대한 선형 주소를 생성한다. 이 선형 주소는 페이징 유닛에 주어져 물리적 주소를 생성한다.

9.6.1.1. IA-32 Segmentation

IA-32 아키텍쳐는 세그먼트 크기를 4GB까지 허용하며 프로세스별 최대 세그먼트 수는 16000이다. 처음 8000개의 세그먼트는 그 프로세스에 귀속된 것이며 정보는 지역 설명자 테이블(LDT)에 저장된다. 다음 8000개의 세그먼트는 모든 프로세스에 공유될 수 있는 것이며 정보는 전역 설명자 테이블(GDT)에 저장된다. IA-32에서의 선형 주소의 길이는 32비트이며, 세그먼트 레지스터는 LDT/GDT 내의 적절한 엔트리를 가리킨다. 해당 세그먼트의 기저와 한계 레지스터는 선형 주소를 만드는 데 쓰인다.

9.6.1.2. IA-32 Paging

IA-32 아키텍쳐는 페이지 크기를 4KB나 4MB로 잡는다. 4KB 페이지에 대해서는 페이지 디렉토리를 통한 2단계 페이징을 사용한다. IA-32 페이지 테이블은 디스크로 교환될 수 있다. 32비트 아키텍쳐에서의 4GB 메모리 제한을 해제하기 위해, 인텔은 페이지 주소 확장(PAE)을 다뤄 페이징을 3단계로 확장한다. 이 때 최상위 2개의 비트는 페이지 디렉토리 포인터 테이블을 참조한다. 페이지 주소 확장을 쓰려면 운영 체제의 지원이 필요하다.

9.6.2. x86-64

64비트 아키텍쳐에서 인텔은 IA-64(이타늄) 아키텍쳐를 최초로 했으나, 이는 AMD에 의해 점유되어 AMD64, Intel 64, 즉 x86-64 아키텍쳐가 널리 쓰이게 되었다. 현재는 48비트 가상 주소를 지원하며 4단계 페이지 계층을 사용해 4KB, 2MB, 1GB의 페이지 크기를 제공한다.

9.7. Example: ARMv8 Architecture

모바일 기기들의 칩은 ARM 프로세서에서 주로 가동된다. 여기서는 ARMv8 아키텍쳐를 다룬다. ARMv8은 3개의 다른 변환 미립자를 갖고 있다: 4KB, 16KB, 64KB. 이는 각각 서로 다른 페이지 크기와 연속된 메모리의 섹션인 영역을 제공한다. 페이지 계층은 각각 2, 2, 3단계이다.현재 스레드의 0단계 테이블을 가리키는 레지스터는 변환 테이블 기저 레지스터라 한다. ARM 아키텍쳐는 2단계의 변환 색인 버퍼를 지원하는데, 하나는 마이크로 TLB이고 하나는 메인 TLB이다.

9.8. Summary

  • 메모리는 현대 컴퓨터 시스템 동작의 중심이고 각각의 주소가 할당된 바이트의 큰 배열로 이루어져 있다.
  • 주소 공간을 프로세스에 할당하는 하나의 방법은 기저와 한계 레지스터를 사용하는 것이다. 기저 레지스터는 가장 작은 물리적 메모리 주소를 담고, 한계는 범위의 크기를 특정한다.
  • 상징적 주소 참조를 실제 물리적 주소에 바인딩하는 것은 컴파일, 로드, 실행 시점 중 하나에 일어날 수 있다.
  • CPU에 의해 생성되는 주소는 논리적 주소로, 메모리 관리 유닛이 이를 메모리 내 물리적 주소로 변환한다.
  • 메모리에 할당하는 하나의 접근법은 서로 다른 크기의 연속된 메모리로 나눠 할당하는 것이다. 이는 최초 적합, 최고 적합, 최악 적합의 셋 중 하나 방법으로 이루어질 수 있다.
  • 현대 운영 체제는 메모리 관리에 페이징을 사용한다. 이 과정에서 물리적 메모리는 프레임이라는 고정 크기 블록으로 나뉘어지며 논리적 메모리는 페이지라는 같은 크기의 블록으로 나뉘어진다.
  • 페이징이 쓰였을 때 논리적 주소는 2 부분으로 나뉜다. 페이지 번호와 페이지 오프셋. 페이지 번호는 프로세스별 페이지 테이블에서의 인덱스 역할을 한다. 이 페이지 테이블은 페이지를 담는 물리적 메모리의 프레임을 담는다. 오프셋은 프레임이 참조되는 장소를 특정한다.
  • 변환 색인 버퍼(TLB)는 페이지 테이블의 하드웨어 캐시이다. 각각의 TLB는 페이지 번호와 대응되는 프레임을 갖고 있다.
  • 페이징 시스템의 주소 변환에서 TLB를 쓰는 것은 논리적 주소로부터 페이지 번호를 얻는 것과 해당 페이지에 대한 프레임이 TLB에 있는지를 체크한다. 존재한다면 프레임을 해당 TLB로부터 얻어온다. 존재하지 않는다면 페이지 테이블에서 얻어와야 한다.
  • 계층 페이징은 논리적 주소를 복수의 부분으로 나뉘어 각각이 서로 다른 계층의 페이지 테이블을 참조하도록 한다. 주소가 32비트 이상으로 확장되면 계층의 수가 커질 수 있다. 이를 해결하는 두 가지 방법은 해시 페이지 테이블과 반전 페이지 테이블이 있다.
  • 교환은 시스템이 프로세스에 속한 페이지를 디스크로 교환시켜 멀티프로그래밍의 정도를 높인다.
  • 인텔 32비트 아키텍쳐는 2단계의 페이지 테이블과 4KB/4MB 페이지 크기를 지원한다. 이 아키텍쳐는 페이지 주소 확장을 제공해 32비트 프로세서가 4GB보다 큰 물리적 주소 공간을 쓸 수 있도록 한다. x86-64와 ARMv9 아키텍쳐는 계층적 페이징을 사용하는 64비트 아키텍쳐이다.

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google photo

Google의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중