3 minute read

스왑 공간

  • 디스크에 페이지들을 저장할 수 있는 일정공간을 확보해둔 공간을 스왑 공간(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. 쓰레드가 페이지들을 비운 후에 원래의 쓰레드를 다시 깨워 원하는 페이지를 불러들일 수 있도록 하며 계속 작업을 진행한다.