[OS] Virtual Memory

가상 메모리 (Virtual Memory)

물리 메모리 크기 한계를 극복하기 위해 생긴 것이다. 예를 들어 물리 메모리보다 큰 프로세스를 실행시켜야할 경우 등이다.

CPU, 메모리, 보조기억장치가 있다. 메인메모리는 100mb라고 하는데, 메인메모리의 크기보다 더 큰 프로세스를 올리고 싶은 경우에, 보조기억장치에 특정 크기가 큰 프로세스를 올릴 때, 해당 프로세스(코드 + 데이터 + 스택)를 전체 다 올리지 않는다. 오류 루틴 등의 쓸 확률이 적은 루틴들은 제외하게 된다. 이런식으로 프로세스의 크기를 줄여서 당장 필요한 것만 메모리에 올리게 된다.

위의 얘기와 같은 논리로, 프로세스를 페이지 단위로 자르고, 현재 필요한 페이지만 메모리에 올리도록 하는 것이다. 이것을 요구 페이징이라고 한다.

요구 페이징

  • Demand Paging

현재 메모리에 올려놓은 페이징들은 MMU에 페이지 주소를 적어놓고, 메모리에 올려놓지 않은 페이지가 있으면 비트 하나를 더 두어 valid bit로 유효하지 않음을 표시한 후에, 해당 올려놓지 않은 페이지를 요구하게 될 경우 그제서야 보조기억장치에서 해당 페이지를 들고 와서 실행시키는 것이다. 이를 요구 페이징이라고 한다. 이런 방식으로 메모리를 절약하도록 한다.

가상 메모리의 논리는 요구 페이징을 사용하여 가상 메모리를 만든다.

페이지 결함(부재)

  • Page Fault

페이지가 부재한다는 뜻으로 쓰이는 용어이다. 즉, 접근하려는 페이지가 메모리에 없는 경우를 말한다. 접근하려는 페이지가 없으면 CPU는 하던 일을 중지하고(인터럽트), OS의 page fault를 처리하는 루틴을 실행시키도록 한다.

그렇게 되면 OS에서 해당 페이지를 메모리의 빈 곳에 가져오도록 하여 실행된다.(Backing store에서 해당 페이지를 가져온다.) 이를 Steps in handling a page fault라고 한다.

  • pure demanding page

지금 당장 필요한 페이지만을 들고와서 실행시킨다. 그렇게 되면 처음 프로그램이 시작될 때부터 page fault가 지속적으로 일어나게 된다. 그렇게 되면 지속적으로 backing store에서 해당 페이지를 들고오는 작업을 하기 때문에 속도가 느리다. 하지만 메모리 절약을 잘 할 수 있다. (페이지 단위로 왔다갔다한다. swapping)

  • prepaging

지금 당장 필요한 페이지가 아니더라도 필요할만한 페이징을 미리 들고온다. 메모리 낭비가 어느정도 일어날 수 있지만, 그만큼 page fault가 일어나는 빈도수는 적을 거기 때문에 속도가 빠를 것이다. (프로세스 단위로 메모리와 backing store를 왔다갔다한다. swapping)

Effective access time

메모리에 유효한 페이지가 있어서 바로 가져오거나, 메모리에 유효하지 않은 페이지라서 하드웨어에 갔다가 가는 경우 두 가지를 평균을 내어서 내는 시간을 유효 접근 시간(Effective Access Time)이라고 한다.

대부분의 걸리는 시간은 하드웨어에서 해당 페이지를 가져올 때 걸리는 시간을 말한다.(TP) 유효 접근 시간을 구하는 것은 page fault가 일어날 확률을 구하는 것이다.(비율)

유효 접근 시간을 구하는 방법은, 메모리를 읽는 시간, page fault가 일어나는 시간, 하드디스크를 읽는 시간(대부분이 여기서 시간이 많이 소요된다.) 이 시간을 shift time 이라고 한다. 디스크의 헤더까지 오는 시간을 lotation time이고, transfer time까지 있다. 대부분은 shift time이 가장 오래 걸린다.

page fault가 자주 일어날수록 속도가 너무 오래 걸리기 때문에 자주 일어나지 않도록 해야한다.

locality of reference

CPU가 참조하는 주소를 의미한다.(reference) CPU가 참조하는 주소가 지역성을 가진다는 의미를 가지고 있다.

한 번 하드디스크에서 page fault가 일어나서 가져오게되면, 다시 읽을 확률이 높기 때문에(지역성) 메모리에 두게 된다. 그리고 page fault가 일어나서 해당 페이지를 들고 올때, 근처 페이지들을 같이 가져온다. 근처 페이지가 쓰일 확률이 크기 때문이다.

즉, 메모리 접근은 시간적, 공간적 지역성을 가지게 된다.

이런 식으로 메모리에 특정 페이지만 두게 될 경우, page fault가 일어날 확률은 매우 낮다.

또 다른 방법으로, HDD는 접근 시간이 너무 길어서 swap device로 부적합하다. 그래서 SSD나, 느린 저가 DRAM을 사용하게 된다.

페이지 교체

victim page (메모리상에서 하드디스크로 쫓겨나는 페이지를 말한다.)

  • 어떤 페이지를 몰아낼 것인가?

하드디스크에 몰아낼 때, 되도록 수정이 이루어지지 않은 페이지를 몰아내도록 한다. (CPU가 해당 페이지를 읽고 나서 수정이 이루어지지 않은 것) 수정이 됐는지 여부를 따지는 방법은 modify index를 따로 두어 구별한다.

수정이 이루어진 페이지를 하드디스크로 보내게 되면, 하드디스크상에서 해당 페이지를 다시 write해주어야 하므로 속도가 느려지게 된다. 그래서 메모리 상에서 페이지를 하드디스크로 보낼 때, 수정이 안된 페이지를 하드디스크로 보내도록 한다.

그렇게 되면 하드디스크에서 해당 페이지를 다시 write 해줄 필요가 없으므로 속도상에 문제가 되지 않는다.(I/O 시간 절약)

modify 안된 것 중에서 어떤 페이지를 보낼 것인가?

한다면, 랜덤으로 보내는 경우가 있다. 두 번째로, 먼저 메모리에 올라온 페이지를 먼저 하드디스크로 보내는 방법도 있다.

이를 페이지 교체 알고리즘이라고 한다.

페이지 교체 알고리즘

  • Page reference string

페이지 참조열이라고 한다. CPU가 내는 주소(메모리를 읽는 순서)가 있고, 페이지 사이즈가 특정 바이트로 정해져 있다면, 해당 페이지 번호는 페이지와 displacement로 나누어지는데, 페이지 번호는 CPU주소 / 페이지 사이즈로 계산이 되어진다. 여기서 page reference string은 해당 페이지 번호중에 중복되는(이어지는) 경우를 제외하고 page fault가 일어나는 줄을 페이지 참조 열이라고 한다.

  • Page Replacement Algorithms
    • FIFO
    • OPT
    • LRU