컴퓨터 구조 & 운영체제/운영체제

[운영체제] 페이징을 통한 가상 메모리 관리

ReBugs 2023. 7. 7.

이 글은 혼자 공부하는 컴퓨터 구조 + 운영체제 (저자 : 강민철)의 책과 유튜브 영상을 참고하여 개인적으로 정리하는 글임을 알립니다.


연속 메모리 할당의 문제점은 아래와 같다.

  • 외부 단편화
  • 물리 메모리의 크기보다 크기가 큰 프로세스 실행 불가

예를 들어 램 용량이 4GB인데 프로세스 크기가 5GB면 실행할 수 없는 것이다.

하지만 가상 메모리(virtual memory)를 이용하면 이게 가능하다. 또한 외부 단편화 문제도 해결할 수 있다.

가상 메모리는 실행하고자 하는 프로그램을 일부만 메모리에 적재하여 실제 물리 메모리 크기보다 더 큰 프로세스를 실행할 수 있게 하는 기술이다.

가상 메모리 관리 기법에는 페이징과 세그멘테이션이 있지만, 페이징 기법이 일반적으로 더 많이 사용된다.

따라서 이 글에서는 페이징 관리 기법만 다루겠다.

 

페이징(Paging)

  • 메모리 연속 할당에서 외부 단편화가 발생했던 근본적 이유는 각기 다른 크기의 프로세스가 메모리에 연속적으로 할당되었기 때문이다.
  • 아래의 그림처럼 메모리와 프로세스를 일정한 단위로 자르고, 이를 메모리에 불연속적으로 할당할 수 있다면 외부 단편화는 발생하지 않는다.

페이징의 기본 개념

  • 프로세스의 논리 주소 공간을 페이지(page)라는 일정 단위로 자르고,
  • 메모리의 물리 주소 공간을 프레임(frame)이라는 페이지와 동일한 일정한 단위로 자른 뒤
  • 페이지를 프레임에 할당하는 가상 메모리 관리 기법

 

페이징에서 스와핑

  • 페이징에서도 스와핑 사용 가능
  • 페이징을 사용하는 시스템에서는 프로세스 전체가 스왑 인/아웃이 아닌, 페이지 단위로 스왑 인/아웃이 된다.
  • 메모리에 적재될 필요가 없는 페이지들은 보조기억장치로 스왑 아웃
  • 실행에 필요한 페이지들은 메모리로 스왑 인

이렇게 스와핑을 함으로써 한 프로세스를 실행하기 위해 프로세스 전체가 메모리에 적재될 필요가 없게 된다.

즉, 프로세스를 이루는 페이지 중 실행에 필요한 일부 페이지만을 메모리에 적재하고, 당장 실행에 필요하지 않은 페이지들은 보조기억장치에 남겨둘 수 있다.

이와 같은 방식을 통해 물리 메모리보다 더 큰 프로세스를 실행할 수 있다.

 


 

페이지 테이블(Page Table)

페이징을 사용하면 아래의 문제를 해결해야 한다.

  • 프로세스를 이루는 페이지가 어느 프레임에 적재되어 있는지 CPU가 일일이 알기가 어렵다.
  • 프로세스가 메모리에 불연속적으로 배치되어 있다면 CPU 입장에서 이를 순차적으로 실행할 수가 없다.
  • CPU 입장에서 다음에 실행할 명령어 위치를 찾기가 어려워진다.

 

이를 해결하기 위해 페이지 테이블이라는 개념을 도입한다.

페이지 테이블이란 물리 주소(실제 메모리 주소)에 불연속적으로 배치되더라도 논리 주소(CPU가 인식하는 주소)에는 연속적으로 배치되도록 하는 방법이다.

즉, 페이지 번호와 프레임 번호를 매핑시킨 것을 나타낸 표이다. 또한 프로세스마다 페이지 테이블이 있다.

이렇게 하면 물리 주소상에서는 프로세스들이 분산되어 저장되어 있더라도 CPU입장에서는 연속적으로 보일 수 있다.

즉 프로세스들이 메모리에 분산되어 저장되어 있더라도 CPU는 논리 주소를 그저 순차적으로 실행하면 된다.

페이징은 외부 단편화는 해결하지만, 내부 단편화는 막을 수 없다.
페이징은 프로세스의 논리 주소공간을 페이지라는 일정한 크기로 자른다. 하지만 모든 프로세스가 페이지 크기에 딱 맞게 잘리는 것은 아니다.
예를 들어, 페이지 크기가 10KB인데 프로세스 크기가 108KB라면 마지막 페이지는 2KB가 남는다.
이러한 메모리 낭비는 페이징에서는 해결할 수 없다.

페이지 테이블 베이스 레지스터(PTBR)

프로세스들은 각기 페이지 테이블이 있고, 각 페이지 테이블은 CPU 내의 PTBR이 가리킨다.

즉, PTBR은 각 프로세스의 페이지 테이블이 적재된 주소를 가리킨다.

각 프로세스들의 페이지 테이블 정보들은 각 프로세스 PCB에 기록된다. 그리고 프로세스의 문맥 교환이 일어날 때 다른 레지스터와 마찬가지로 함께 변경된다.

Translation Lookaside Buffer(TLB)

페이지 테이블을 메모리에 두면 메모리 접근 시간이 두 배로 늘어난다.

  1. 메모리에 있는 페이지 테이블을 보기 위해
  2. 테이블을 통해 알게 된 프레임에 접근하기 위해

이렇게 총 두 번의 메모리 접근이 필요하기 때문이다.

이와 같은 문제를 해결하기 위해 TLB를 사용한다.

  • TLB : CPU 근처에 있는 페이지 테이블의 캐시 메모리
  • 참조 지역성에 근거해 페이지 테이블의 일부를 가져와 저장

 

TLB 히트 : CPU가 발생한 논리 주소에 대한 페이지 번호가 TLB에 있을 경우

  • 이 경우는 페이지가 적재된 프레임을 알기 위해 메모리에 접근할 필요가 없다.

TLB 미스 : CPU가 발생한 논리 주소에 대한 페이지 번호가 TLB에 을 경우

  • 이 경우는 페이지가 적재된 프레임을 알기 위해 메모리 내의 페이지 테이블에 접근해야 한다.

 


 

페이징에서의 주소 변환(Mapping)

하나의 페이지 혹은 프레인은 여러 주소를 포괄하고 있다. 그렇기 때문에 특정 주소에 접근하려면 아래와 같은 정보가 필요하다

  • 어떤 페이지 혹은 프레임에 접근하고 싶은지
  • 접근하려는 주소가 그 페이지 혹은 프레임으로부터 얼마나 떨어져 있는지

이렇기 때문에 페이징 시스템에서는 모든 논리 주소가 기본적으로 페이지 번호(page number)와 변위(offset)로 이뤄져 있다.

예를 들어
CPU가 32비트 주소를 보냈다면 이 중 N비트는 페이지 번호, 32-N비트는 변위로 이뤄져 있다

 

  • <페이지 번호, 변위>로 이뤄진 논리 주소는 페이지 테이블을 통해 <프레임 번호, 변위>로 이뤄진 물리 주소로 변환된다.
페이지와 프레임은 단위가 같기 때문에
논리 주소의 변위와 물리 주소의 변위 값은 같다.

예를 들어
논리주소 <5,2>는 <1,2>로 변환되고 CPU는 10번지에 접근하게 된다.

 


 

페이지 테이블 엔트리(PTE:Page Table Entry)

페이지 테이블 안에 있는 각각의 행(row)들을 페이지 테이블 엔트리라고 한다.

페이지 테이블 엔트리에 담기는 정보로 페이지 번호, 프레임 번호뿐만 아니라 유효 비트, 보호 비트, 참조 비트, 수정 비트 등이 담긴다.

 

유효 비트(valid bit)

유효 비트는 현재 해당 페이지에 접근 가능한지 여부를 나타낸다.

  • 프레임 번호 다음으로 중요한 정보
  • 현재 페이지가 메모리에 적재되어 있는지 보조기억장치에 있는지를 알려주는 비트(스와핑)
  • 유효 비트가 1 : 페이지가 메모리에 적재되어 있음
  • 유효 비트가 0 : 페이지가 메모리에 적재되어 있지 않음

페이지 폴트(page fault)
CPU가 유효 비트가 0인 메모리(메모리에 적재되어 있지 않은 페이지)에 접근하려고 하면 페이지 폴트라는 예외(Exception)가 발생한다.
CPU가 페이지 폴트를 처리하는 과정은 하드웨어 인터럽트를 처리하는 과정과 유사하다

 

보호 비트(protection bit)

  • 페이지 보호 기능을 위해 존재하는 비트
  • 읽고 쓰기가 모두 가능한 페이지인지, 읽기만 가능한 페이지인지를 나타냄
  • 보호 비트가 0 : 읽기만 가능한 페이지를 뜻함
  • 보호 비트가 1 : 읽고 쓰기가 모두 가능한 페이지를 뜻함

프로세스를 이루는 요소 중 코드 영역은 읽기 전용 영역이다.

이러한 읽기 전용 페이지에 쓰기 시도를 하면 운영체제가 이를 막아준다.

이와 같은 방식으로 페이지들을 보호한다.

 

보호 비트는 세 개의 비트로 조금 더 복잡하게 구현할 수도 있다.

읽기(Read)를 나타내는 r, 쓰기(Write)를 나타내는 w, 실행(eXecute)을 나타내는 x의 조합으로 읽기, 쓰기, 실행하기 권한의 조합을 나타낸다.

 

참조 비트(reference bit)

  • CPU가 이 페이지에 접근한 적이 있는지 여부를 나타냄
  • 참조 비트가 1 : 적재 이후 CPU가 읽거나 쓴 페이지를 뜻함
  • 참조 비트가 0 : 적재 이후 CPU가 한 번도 읽거나 쓴 적이 없는 페이지를 뜻함

 

수정 비트(modified bit)(=dirty bit)

  • 해당 페이지에 데이터를 쓴 적이 있는지 없는지 수정 여부를 나타냄
  • 페이지가 메모리에서 사라질 때 보조기억장치에 쓰기 작업을 해야 하는지, 할 필요가 없는지를 판단
  • 수정 비트가 1 : 변경된 적이 있는 페이지를 뜻함
  • 수정 비트가 0 : 변경된 적이 없는 페이지를 뜻함

CPU는 메모리를 읽는 것뿐만 아니라 메모리에 값을 쓰기도 하는데, 한 번도 수정된 적이 없는 페이지가 스왑 아웃될 경우 아무런 추가 작업을 하지 않아도 된다.

어차피 같은 페이지가 보조기억장치에 저장되어 있기 때문이다.

반대로 수정된 적이 있는 경우, 페이지가 스왑 아웃될 경우 변경된 값을 보조기억장치에 기록하는 작업이 추가되어야 하기 때문에 이러한 작업이 필요한지 아닌지를 판단하기 위해 수정 비트가 존재하는 것이다.

댓글