이 포스팅은 Operating Systems: Three Easy Pieces, Remzi H. Arpaci-Dusseau & Andrea C. Arpaci-Dusseau을 읽고 개인 학습용으로 정리한 글입니다.
지금까지 가상 주소 공간이 비현실적으로 작아서 모두 물리 메모리에 탑재가 가능한 것으로 가정하였음
실행 중인 프로세스의 전체 주소 공간이 메모리에 탑재된 것으로 가정하였음
이제 가정을 완화하여 다수의 프로세스들이 동시에 각자 큰 주소 공간을 사용하는 상황을 가정한다
편리함 & 사용 용이성
주소 공간이 충분히 크면, 프로그램의 자요 구조들을 위한 충분한 메모리 공간이 있는지 걱정 X
-> 필요 시 메모리 할당을 운영체제에게 요청하기만 하면 됨
과거 시스템에서 사용되던 메모리 오버레이(memory overlay)
-> 프로그래머가 코드 또는 데이터의 일부를 수동으로 메모리에 탑재/제거
스왑 공간(swap space): 디스크에 페이지를 저장할 수 있도록 확보된 일정 공간
-> 메모리에서 페이지를 읽어서 스왑 공간에 씀(swap out)
-> 스왑 공간에서 페이지를 읽어서 메모리에 씀(swap in)
운영체제는 스왑 공간에 있는 모든 페이지들의 디스크 주소를 기억해야
스왑 공간의 입출력 단위는 페이지로 가정
스왑 공간은 매우 크다고 가정
3개의 프로세스(Proc 0, Proc 1, Proc 2)가 물리 메모리를 공유하고 있음
-> 몇 개의 유효한 페이지들만 메모리에 올려둠
-> 나머지 페이지들은 디스크에 스왑 아웃 되어있음
4번째 프로세스(Proc 3)의 모든 페이지들은 디스크로 스왑 아웃 되어있음
-> 현재 실행 중이 아니다
하드웨어가 PTE에서 해당 페이지가 물리 메모리에 존재하는지 존재하지 않는지 표현해야
present bit = 0: 물리 메모리에 해당 페이지가 존재
present bit = 0: 물리 메모리에 해당 페이지가 존재 X
페이지 폴트(page fault): 물리 메모리에 존재하지 않는 페이지를 접근하는 행위
-> 페이지 폴트가 발생하면 운영체제로 제어권이 넘어간다
-> 페이지 폴트 핸들러(page-fault handler)가 실행된다
TLB 미스 처리 방법에 따른 두 종류의 시스템
-> 하드웨어 기반의 TLB: HW가 페이지 테이블을 검색하여 원하는 변환 정보를 찾음
-> 소프트웨어 기반의 TLB: 운영체제가 처리함
둘 중 어느 것이던, 페이지 폴트가 발생하면, 운영체제가 처리한다
-> 페이지 폴트 핸들러가 그 처리 메커니즘을 규정
많은 시스템은 페이지의 스왑 공간 상의 위치를 페이지 테이블에 저장
-> PFN과 같은 PTE비트들을 페이지의 디스크 주소를 나타내는 데 사용
만약 요청된 페이지가 메모리에 없고, 디스크로 스왑된 경우
-> 운영체제는 페이지 테이블에서 해당 페이지의 디스크 상의 위치 파악
-> 해당 페이지를 메모리로 스왑해온다
디스크 I/O가 완료되면 운영체제는 해당 페이지의 PTE의 PFN값을 탑재된 페이지의 메모리 위치로 갱신
작업 완료되면 페이지 폴트를 발생시킨 명령어 재실행
명령어 재실행으로 인해 TLB 미스 다시 발생
-> TLB 미스 처리 과정에서 TLB 값 갱신
-> TLB 미스를 발생시킨 명령어 재실행
(이를 피하기 위해 페이지 폴트 처리 시 함께 TLB를 갱신하도록 할 수도 있음)
마지막 재실행 시에 TLB 히트 발생
-> TLB에 저장된 주소 변환 정보를 이용하여 물리 주소에서 원하는 데이터/명령어 가져옴
스왑 공간으로 부터 페이지를 가져오기 위한(page-in) 여유 메모리가 충분하다는 것을 가정했음
그러나, 메모리에 여유 공간이 없거나 거의 다 찼을 수도 있음
-> 공간을 확보하기 위해 하나 또는 그 이상의 페이지들을 먼저 페이지 아웃(page-out)해야 함
-> 페이지 교체 정책(page-replacement policy)
페이지 교체 정책은 프로그램 성능에 큰 영향
-> 잘못된 선택을 할 경우, 프로그램이 메모리 속도로 실행되지 않고 디스크와 비슷한 속도로 실행됨
TLB 미스 발생 기 세 가지 중요한 경우 존재
페이지가 존재하며 유효한 경우(valid = 1, present = 1)
-> TLB 미스 핸들러가 PTE에서 PFN을 가져와 명령어 재실행 -> TLB 히트
페이지가 유효하지만 존재하지 않는 경우(valid = 1, present = 0)
-> 페이지 폴트 핸들러 실행
페이지가 유효하지 않는 경우(valid = 0)
-> PTE의 다른 비트 의미 X
-> 운영체제의 트랩 핸들러에 의해 처리
운영체제는 탑재할 페이지를 위한 물리 프레임 확보
-> 만약 여유 프레임 없다면, 교체 알고리즘 실행하여 메모리 확보
물리 메모리를 확보한 후, I/O 요청을 통해 스왑 영역에서 페이지 읽어옴
I/O 작업 완료 후, 운영체제는 PTE 갱신, 명령어 재실행
-> 재실행 시 TLB 미스 발생
-> 또 한번의 재실행 시 TLB 히트
이제까지 메모리에 여유 공간이 고갈된 후에 교체 알고리즘이 작동하는 것으로 가정
-> 그러나, 운영체제는 항상 어느 정도의 여유 메모리 공간 확보하고 있어야
-> 운영체제는 여유 공간에 관련된 최댓값(high watermark, HW)과 최솟값(low watermark, LW)을 설정
여유 공간의 크기가 LW보다 작아지면 여유 공간 확보를 담당하는 백그라운드 쓰레드 실행
-> **스왑 데몬(swap demon) / 페이지 데몬(page demon)
-> 여유 공간의 크기가 HW에 이를 때까지 페이지 제거
-> 충분한 여유 메모리가 확보되면 슬립 모드로 들어감
일시에 여러 개의 페이지를 교체하면 성능 개선
(디스크의 탐색과 회전 지연에 대한 오버헤드 경감)
-> 많은 시스템은 다수의 페이지들을 클러스터나 그룹으로 묶어 한 번에 스왑
Foreground 쓰레드는 메인 쓰레드가 종료되더라도 Foreground 쓰레드가 살아 있는 한, 프로세스가 종료되지 않고 계속 실행된다
백그라운드 쓰레드는 메인 쓰레드가 종료되면 바로 프로세스를 종료한다
메모리에 특정 페이지가 존재하는지 알리기 위한 present bit 사용
운영체제는 페이지 폴트를 처리하기 위해 페이지 폴트 핸들러 실행
-> 원하는 페이지를 디스크에서 메모리로 전송
-> 스왑되어 들어올 페이지를 위한 메모리 공간을 확보를 위해 일부 페이지들을 먼저 교체해둔다
이 모든 작업은 프로세스가 인지하지 못하는 상황에서 처리된다