스왑 공간
- 디스크에 페이지들을 저장할 수 있는 일정공간을 확보해둔 공간을 스왑 공간(swap space)라고 한다.
- 스왑 공간이라고 불리는 이유는 메모리 페이지를 읽어서 이곳에 쓰고(swap out), 여기서 페이지를 읽어 메모리에 탑재(swap in)시키기 때문이다.
- 운영체제는 스왑 공간에 있는 모든 페이지들의
디스크 주소
를 기억해야 한다.
- 스왑 공간에만 스왑을 할 수 있는 것은 아니다.
- 실행 프로그램들은 디스크에 존재한다.
- 프로그램이 실행되면 각 페이지들은 메모리로 탑재된다.
- 물리 메모리에 추가 공간을 확보해야 할 때,
코드 영역
의 페이지들이 차지하는 물리 페이지는 즉시 다른 페이지가 사용할 수 있다.
- 코드가 저장되어 있는 파일 시스템 영역이 스왑 목적으로 사용되는 셈이다. (페이지들은 디스크에 원본이 있으므로)
Present Bit
- 하드웨어 기반 TLB를 사용하는 시스템을 가정하자.
- 페이지가 디스크로 스왑되는 것을 가능케 하려면, 하드웨어가 PTE에서 해당 페이지가 물리 메모리에 존재하지 않는다는 것을 표현해야 한다.
- present bit를 사용하여 각 페이지 테이블 항목에 어떤 페이지가 존재하는지를 표현한다.
- present bit가 1로 설정되어 있으면, 물리 메모리에 해당 페이지가 존재한다는 것이다.
- 만약 그 비트가 0이라면 물리 메모리에 존재하지 않고, 디스크 어딘가에 존재한다는 것이다.
- 물리 메모리에 존재하지 않는 페이지를 접근하는 행위를 일반적으로 페이지 폴트(page fault)라고 한다.
- 페이지 폴트가 발생하면, 페이지 폴트를 처리하기 위해 제어권이 운영체제로 넘어간다.
페이지 폴트 핸들러(page fault hanlder)
가 실행된다.
페이지 폴트
- 만약 요청된 페이지가 메모리에 없고 디스크로 스왑되었다면 운영체제는 해당 페이지를 메모리로 스왑해온다.
- 해당 페이지의 스왑 공간상에서의 위치를 페이지 테이블에 저장한다.
- 운영체제는 PFN과 같은 PTE비트들을 페이지 디스크 주소를 나타내느 데 사용할 수 있다.
- 페이지 폴트 발생 시 운영체제는 페이지 테이블 항목에서 해당 페이지의 디스크 상 위치를 파악하여, 메모리로 탑재한다.
- 디스크 I/O가 완료가 되면 운영체제는 해당 페이지 테이블 항목(PTE)의 PFN 값을 탑재된 페이지의 메모리 위치로 갱신한다.
- 이 작업이 완료되면 페이지 폴트를 발생시킨 명령어가 재실행된다.
- 재실행으로 인해 TLB 미스가 발생될 수 있다.
- TLB미스 처리 시에 TLB값이 갱신된다.
- 마지막 재실행 시에 TLB에서 주소 변환 정보를 찾게 되고, 이를 이용하여 물리 주소에서 원하는 데이터나 명령어를 가져온다.
메모리에 빈 공간이 없으면?
- 탑재하고자 하는 새로운 페이지를 위한 공간을 확보하기 위해 하나 또는 그 이상의 페이지들을 먼저 페이지 아웃(page out)하려고 할 수 있다.
- 교체 페이지를 선택하는 것을
페이지 교체 정책(page replacement policy)
라고 한다.
프로그램이 메모리에서 데이터를 가져올 때 어떤 일이 발생하는가?
페이지 오류 제어 흐름의 알고리즘(하드웨어)
VPN = (VirtualAddress & VPN_MASK) >> SHIFT
(Success. TlbEntry) = TLB_Lookup(VPN)
if (Success == True)
if (CanAccess(TlbEntry.ProtectionBits) == True)
Offset = VirtualAddress & OFFSET_MASK
PhysAddr = (TlbEntry.PFN << SHIFT) | Offset
Register = \gndx{AccessMemory}{\gndx{PhysAddr})
else
RaiseException(PRoTECTION_FAULT)
else
PTEAddr = PTBR + (VPN * sizeof(PTE))
PTE = \gndx{AccessMemory}(\gndx(PTEAddr))
if (PTE.Valid == False)
RaiseException(SEGMENTATION_FAULT)
else
if (CanAccess(PTE.ProtectBits) == False)
RaiseException(PRoTECTION_FAULT)
else if (PTE.present == True)
TLB_Insert(VPN, PTE.PFN, PTE.ProtectBits)
RetryInstruction()
else if (PTE.Present == False)
RaiseException(PAGE_FAULT)
- TLB 미스 처리시 세 가지의 경우
- 1. 페이지가 존재하며 유효한 경우(PTE.present == True)
- TLB 미스 핸들러가 PTE에서 PFN을 가져와서 (여러 차례) 명령어를 재시도 한다.
- 2. 페이지가 유효하지만 존재하지 않는 경우(PTE.present == False)
- 페이지 폴트 핸들러가 반드시 실행되어야 한다.
- 프로세스가 사용할 수 있는 제대로 된 페이지이기는 하지만 물리 메모리에 존재하지 않기 때문이다.
- 3. 페이지가 유효하지 않는 경우(PTE.valid == False)
- 이 경우 PTE의 다른 비트는 의미가 없다.
- 하드웨어는 이 무효한 접근이 운영체제의 트랩 핸들러에 의해 처리되도록 한다.
- 동작 과정
- 1. 운영체제는 탑재할 페이지를 위한 물리 프레임을 확보한다.
- 2. 만약 여유 프레임이 없다면, 교체 알고리즘을 실행하여 메모리에서 페이지를 내보내고 여유 공간을 확보한다.
- 3. 물리 프레임을 확보한 후, I/O 요청을 통해 스왑 영역에서 페이지를 읽어 온다.
- 4. 이 느린 작업이 완료되면 운영체제는 페이지 테이블을 갱신하고 명령어를 재시도한다.
- 5. 재시도를 하면 TLB 미스가 발생하며, 또 한 번의 재시도를 할 때 TLB 히트가 된다.
페이지 오류 제어 흐름의 알고리즘(소프트웨어)
PFN = FindFreePhysicalPage()
if (PFN == -1) // 비어있는 페이지 못 찾음
PFN = Evictpage() // 교체 알고리즘 실행
\gndx{DiskRead}(\gndx{PTE.DiskAddr, pfn}) // 대기(I/O 기다리기)
PTE.present = True // 존재한다고 페이지 테이블에 갱신
PTE.PFN = PFN // 비트와 변환(PFN)
RetryInstruction() // 명령어 재시도
교체는 언제 일어나는가?
- 메모리에 여유 공간이 고갈된 후에 교체 알고리즘이 작동하는 것은 효율적이지 않다. 다양한 이유로 운영체제는 항상 어느 정도의 여유 메모리를 확보하고 있어야 한다.
- 운영체제는 여유 공간에 관련된
최댓값(high watermark, HW)과 최솟값(low watermark, LW)
을 설정하여 교체 알고리즘 작동에 활용한다.
- 운영체제가 여유 공간의 크기가 최솟값보다 작아지면 여유 공간 확보를 담당하는 백그라운드 쓰레드가 실행된다.
- 이 쓰레드는 여유 공간의 크기가 최대값에 이를 때까지 페이지를 제거한다.
- 이 백그라운드 쓰레드를
스왑 데몬(swap demon)
또는 페이지 데몬(page demon)
이라고 불린다. 충분한 여유 공간이 확보되면 이 쓰레드는 다시 슬립 모드로 돌아간다.
- 일시에 여러 개를 교체하면 성능 개선이 가능하다. 많은 시스템들은
클러스터(cluster)
나 그룹(group)
으로 묶어서 한 번에 스왑 파티션에 저장함으로써 디스크의 효율을 높인다.
- 동작 과정
- 1. 교체를 직접 수행하는 대신 알고리즘은 사용할 수 있는 페이지들이 있는지 단순히 검사만 한다.
- 2. 만약 없다면 백그라운드 페이징 쓰레드에게 여유 페이지들이 필요하다고 알려준다.
- 3. 쓰레드가 페이지들을 비운 후에 원래의 쓰레드를 다시 깨워 원하는 페이지를 불러들일 수 있도록 하며 계속 작업을 진행한다.