13 April 2024

가상 메모리와 물리 메모리

by 꽈배기

가상메모리 물리메모리

가상 메모리

가상 메모리를 얼핏 들으면 새로운 공간으로 착각하기 쉽지만, 프로그램 실행에 필요한 일부분만 램에 적재하며 나머지 메모리는 디스크에 저장해두며 필요에 따라 교체하며 사용하는 방식이다. x86 환경에서 가상메모리 주소 대역폭은 0~ 2^32^ -1, x64 환경에서 주소 대역폭은 0~ 2^64^-1 이다.

가상 메모리의 등장 배경

예전 프로그램들은 하나의 메모리 공간을 전부 할당받아 사용한다는 전제하에 만들었기에 동시성을 보장하기 어려웠다. 멀티태스킹의 필요성이 대두되며 각 프로세스마다 메모리 공간 할당에 대한 효율적인 방안이 요구되었고, 해당 결과로 가상 메모리가 등장하게 된다.

가상메모리의 역할은 다양하게 있는데, 주요 이유로는 보안 안정성, 큰 프로세스 사용 가능, 불연속적 공간을 연속적 메모리 공간으로 가정할 수 있다는 것이다. 서로 다른 프로세스가 같은 메모리를 공유하는 상황을 가정하면 가상 메모리의 역할을 확실히 알 수 있다. 만약 프로세스 A에 할당된 영역을 벗어나 접근하려 한다면 어떻게 될까? 널 에러를 반환하거나 심하다면 다른 프로세스의 메모리를 참조하여 오류를 불러올 것이다. 이를 가상 주소와 물리 메모리 주소를 매핑하는 과정을 거쳐 메모리 가상화를 통해 서로 배타적인 메모리 공간을 사용함으로 안정성을 확보하게 된다.

그렇다면 어떻게 가상메모리는 실제 메모리 공간보다 큰 프로세스를 실행할 수 있을까? 예를 들어 램 용량이 16인데 반해 프로세스의 총합이 20이라면 모든 메모리를 로드하여 실행할 수 없을것이다. 그렇기에 프로세스 실행에 필요한 특정 메모리 부분만 로드하여 필요시 하드 디스크와의 스왑을 통해 더 많은 공간을 사용할 수 있는것이다. 즉 추가적인 공간을 만들어주는것은 아니고, 필요할 때마다 가져와 사용하니 공간을 더 효율적으로 사용할 수 있다는 말이다.

image

실제 물리 메모리엔 파편화되어 있지만, 가상 메모리에선 연속적으로 취급할 수 있다.

물리메모리

실제 데이터가 존재하는 메모리를 물리메모리라 하며 이곳의 고유 주소를 물리 주소라 한다. CPU가 가상주소 요청을 받는다면 이 논리주소를 물리주소로 변환시켜주어야 하는데, 이 매핑 과정을 다루는 것이 메모리 관리자이다.

메모리 관리자 MMU

image

fetch

프로세스가 필요로하는 데이터 메모리를 가져오도록 결정한다. 빠른 작업을 위해 이를 캐싱하기도 함.

배치

프로세스 조각을 메모리의 어떤 곳에 위치 시킬지 결정하는 정책이다.

가상메모리와 물리메모리 매핑 방식

1. 페이징

가상 메모리를 일정한 크기로 분할하고 그 크기에 프로세스를 파편화 하여 저장하는 기법을 페이징이라 한다. 해당 과정을 통해 비연속적인 물리 메모리 공간을 페이징하여 연속적으로 저장해 사용할 수 있다.

1.1 페이지 & 프레임

페이지 : 프로세스가 가리키는 논리 주소 공간을 나눈 것. 프레임 : 물리 메모리를 일정한 크기로 나눈 블록으로 페이지와 대응된다.

1.2 페이지 테이블

페이지가 연속적으로 저장되며 프레임과 페이지의 대응을 관리한다.

image

페이지 테이블을 이루는 요소를 페이지 테이블 엔트리라고 한다. 엔트리는 페이지 정보와 연관되는 프레임 정보를 가지며 여러 비트들에 대한 정보를 포함한다.

CPU에서 페이지 테이블을 어떻게 접근할까?

CPU가 요청에 따라 메모리에 적재된 데이터를 접근하려면 페이지 테이블 정보의 위치를 봐야 할 것이다. 그렇다면 CPU는 이 페이지 테이블 위치를 어떻게 알 수 있을까? 페이지 테이블 베이스 레지스터 (PTBR) 라는 레지스터가 페이지 테이블에 대한 정보를 가리키고 있다.


1.3 페이지와 프레임의 크기

일반 4KB 대용량 4MB

32비트 가상 주소에서 페이지 디렉토리/ 테이블 에 10비트 * 2 로 나머지 12 비트가 4kb의 용량을 가지게된다.

논리 주소 - 물리 주소간의 변환을 수행한다.

특징

  1. 물리 메모리가 연속적으로 저장 될 필요가 없어 외부단편화 가 해결된다. (내부 단편화 존재)
  2. 프로세스 요청이 들어오면 메모리에 접근해 데이터를 가져온다. 만약 주기억장치에 있다면 바로 가져오며 없다면 페이지의 정보를 받아 프레임에 해당하는 공간과 swap을 진행한다.
  3. 프로세스가 변경됨에 따라 페이지 테이블을 문맥 교환하게 되며 교환 시간이 증가하게 된다.

메모리 접근 시간의 문제

프로세스의 요청에 따라 특정 메모리에 접근해 변수를 가져오기 위해서는 우선 페이지 테이블이 있는 메모리에 먼저 접근 해야한다. 페이지 테이블 데이터를 가져 온 후 이를 참조해 논리 주소 -> 물리 주소간 변환이 이루어지면 실제 메모리에 접근해 변수를 가져온다.

결국 2번의 메모리 접근이 발생하기에 페이징 성능에 영향을 준다.

TLB (Translation Look aside Buffer)

가상 주소에서 실제 주소 조회를 위한 캐시로 빠른 데이터 접근과 캐시 지역성을 위해 사용한다. TLB는 프로세스의 요청에 의해 CPU가 처음 메모리를 페이지 테이블에서 가져오고, 최근 사용된 데이터를 캐시에 적재한다. 다음 프로세스의 요청이 있을때 TLB를 우선적으로 탐색해 TLB Hit이 이루어진다면 캐시 메모리로 접근하는 방식이다.

MMU는 이런 페이지 테이블 캐싱을 위해 TLB라고 하는 페이지 테이블만 전용으로 캐싱하는 별도의 캐시 메모리를 두게 된다. (최근에는 TLB가 CPU 내부에 존재한다고 한다? 음…)

가상 메모리 주소매핑 흐름

enter image description here

가상 메모리의 접근 흐름도를 한번 살펴보자.

  1. CPU에 가상 메모리 접근에 대한 요청이 들어온다.
  2. 원하는 메모리 정보가 TLB에 적재되어있는지 살펴본다.
  3. 있다면 Hit으로 캐시에 접근한다. miss라면 프로세스의 페이지 테이블을 탐색한다.
  4. 페이지 테이블에 Hit 하면 TLB의 정보를 최신화시키고 메모리를 가져온다.
  5. 페이지 테이블에 정보가 없으면 MMU에 접근해 페이지 테이블을 최신화한다.

TLB에서 Hit이 되었는데 캐시는 미스가 나는 경우?

캐시 지역성 문제, 적재된 캐시 내부에서 모든 메모리가 사용되진 않는다. 캐시 라인

페이지 폴트

의문점이 들수도 있을것이다. 분명 페이지 테이블에 대한 정보는 요청된 프로세스에 모두 저장되어 있는데 어떻게 페이지 폴트가 뜨는걸까?

하드 페이지 오류
프로세스가 실행되면 가상주소 공간에 메모리 일부가 할당되는데 추가 메모리(힙 영역)에 해당하는 부분은 운영체제에 요청해야 하므로 이러한 비어있는 주소에 접근시 페이지 폴트가 뜬다고 한다. 만약 포인터를 해당 영역으로 가리키고 실행한다면 page fault가 뜬다는 것. 이처럼 시스템에서 예상치 못한 오류가 나타날때 하드 페이지 오류라 한다.

소프트 페이지 오류
가상 주소 요청에 의해 메모리에 접근할 때 페이지 테이블에 해당되는 내용이 없을 때 출력된다. 이러한 경우 가상메모리의 페이지와 저장소의 프레임간 스왑 과정을 통해 프로세스에 필요한 메모리 영역을 가상메모리에 적재한다. 이러한 소프트 페이지 오류는 페이지 인터럽트를 발생시키고 OS에 의해 핸들링 되기에 프로그램을 계속 실행하도록 지원한다.
copy on write

만약 부모 프로세스를 fork 하였을때 메모리를 어떻게 관리할 수 있을까? 기존처럼 별도의 메모리 공간에 부모 프로세스를 복제한다면 메모리 낭비, 프로세스 생성 시간이 오래 걸릴것이다. 이를 위해 copy on write가 있다. 부모 프로세스 / 자식 프로세스가 동일한 페이지와 프레임을 공유하다 둘 중 하나라도 페이지에 쓰기 작업 수행 시 해당 페이지를 별도의 공간으로 복제한다. (프로세스 생성 시간 절약, 메모리 절약)

페이지 테이블 관리 방법

계층적 페이징

페이지 테이블 마저 페이지 단위로 나누어서 실제 메모리에 연속되지 않게 배치한다는 것을 의미한다. 페이지 테이블을 구성하는 페이지 시작 위치를 알아야 인덱스에서 원하는 값을 찾아낼 수가 있게 된다. 이를 사용하는 이유는 프로세스의 크기에 따라 페이지 테이블 또한 커질텐데, 이 큰 용량을 모두 메모리에 올리는 건 비효율적이기에 당장 사용될 페이지 테이블 영역만 적재하는 것이다.

image

그래서 이러한 방식으로 페이지 테이블을 운영하기 위해서는 (페이지 테이블을 페이징한 정보를 담을 추가 페이지 테이블 < 말이 참 어렵다 )이 필요하게 된다.

이럴경우 4MB의 페이지 테이블은 2^20^으로 구성되는데, 4KB 페이지 테이블 2^10^으로 구성될 수 있다는 뜻이다. 64비트 환경에서는 계층적 페이지가 더 증가하게 되며 유효한 페이지 테이블을 탐색하는 방법이 고안되었다.

해시 페이지 테이블

논리 주소의 페이징에 해시값을 사용한다. 해시값이 동일해 충돌이 발생한다. 이를 위해 Linked list로 구현된다.

역 페이지 테이블

기존 페이지 테이블 방식은 프로세스당 페이지 테이블을 가지고 있기에 사용되지 않음에도 페이지의 최대 수 만큼 테이블을 지니고 있어야 한다.

역페이지 테이블은 물리 주소를 논리 주소로 바꿔주는 테이블이다. 모든 프로세스가 페이지 테이블을 참조한다. 이로 인해 페이지 테이블의 entry 수와 물리 메모리 frame 수가 동일하게 적용된다. 모든 프로세스가 역페이지 테이블을 참조하기 때문에, 프로세스 정보 구분을 위한 pid가 존재한다.

기존 테이블 참조 방식과 달리, pid와 페이지 넘버를 비교하며 탐색을 진행하기에 시간 복잡도가 추가로 소모된다.

이러한 문제를 해결하기 위해 등장한 개념이 Inverted page table입니다.

요구 페이징

처음부터 모든 페이지를 적재하지 않고 필요한 페이지만 메모리에 적재하는 기법

순수 요구 페이징

처음부터 아무런 페이지를 적재하지 않지만, 페이지 요청에 따라 적재하게 되며 시간이 지날수록 페이지 폴트가 줄어드는 방식

페이지 교체 알고리즘

페이지를 모두 적재하게되면 메모리가 가득 찰 것이다. 이때 어떤 페이지를 보내야할지 판단해야한다. 페이지 교체 알고리즘은 페이지 폴트가 적을수록 좋다.

페이지 참조열

CPU가 참조하는 페이지들 중 연속된 페이지를 생략한 페이지열이다.

FIFO 알고리즘

가장 우선적으로 적재된 페이지를 교체 대상으로 선정

image

스래싱과 프레임 할당

페이지 폴트가 자주 발생하는 이유?

  1. 페이지 교체 알고리즘의 효율성
  2. 프로세스가 사용할 수 있는 프레임 자체가 적어서

2. 세그멘테이션

프로세스 크기에 맞춰 물리 메모리와 가상 메모리를 자르는 방식이다. 기존 페이징 방법과는 달리, 메모리 크기 단위가 다르기에 항상 시작 메모리 주소가 매핑 테이블에 포함되어있어야 한다.

특징

  1. 내부 단편화를 해결할 수 있다.
  2. 페이지 테이블이 단순하게 표현된다.
  3. 메모리 구조가 복잡해질 수 있다. (외부단편화 발생) 3-2. 프로세스 크기에 맞춰 메모리를 적재, 삭제하며 큰 프로세스가 적재될 공간이 부족해지는 외부 단편화가 발생한다.

세그멘테이션 - 페이징 혼용 기법

메모리 접근 권한

메모리 접근 권한은 읽기, 쓰기, 실행, 추가등이 존재하는데 크게 읽기, 쓰기, 실행의 권한을 사용한다.

페이징 및 세그멘테이션 기법은 매핑 테이블에 메모리 접근 권한 정보를 가지고 주소 변환이 일어날때 유용한 접근인지 검사한다. 만약 권한이 없는 메모리에 해당 동작들을 수행하면 오류가 발생하게 된다.

혼용 기법 도입

페이징에서는 페이지마다 접근 권한이 다르기에 페이지 테이블 행에 접근 권한에 대한 정보를 가지는 권한 비트가 추가 된다. 메모리 관리자는 주소 변환이 일어날 때마다 페이지 테이블의 권한 비트로 판단한다.

하지만 페이지 테이블에 권한 비트가 추가됨에 따라 크기가 커지는데, 인접한 페이지의 경우 비슷한 접근 권한을 가지는 반면 페이지마다 권한 비트를 설정하기에 메모리 낭비가 발생한다.

세그멘테이션 테이블

페이지로 분할된 가상 주소 공간중 서로 연관있는 영역을 세그먼트로 묶어 테이블로 관리하고, 각 세그먼트를 구성하는 페이지를 해당하는 페이지 테이블로 관리한다. 이렇듯 중복되는 권한 비트를 세그멘테이션 테이블로 옮겨 와 테이블의 크기를 줄일 수 있다.

프로세스 컨텍스트 스위칭과의 상관관계

일반 스레드 간의 컨텍스트 스위칭과 프로세스간의 컨텍스트 스위칭을 비교한다면 당연하게도 프로세스간 스위칭이 느리다는것을 알 수 있다. 스레드간 컨텍스트 스위칭은 저장, 호출을 반복하는 반면 프로세스간 컨텍스트 스위칭시 한 단계가 추가로 들어가게 된다.

  1. 기존 작업을 저장하고 새로운 요청을 호출한다.
  2. 해당 과정을 수행하게 되면 CPU에 가상주소 요청이 들어오게된다.
  3. 요청에 따라 MMU가 CPU에게 가상주소 접근을 위한 프로세스 메모리 포인터 정보를 변경시켜주는 과정을 거친다.
  4. 프로세스가 변경되었기에 TLB 캐시를 정리하는 과정을 거친다

프로세스 컨텍스트 스위칭이 MMU를 무효화 하는가

tags: ComputerScience