크래프톤정글/운영체제

[OSTEP] CH21 물리 메모리 크기의 극복 - 메커니즘

아람2 2024. 11. 11. 19:33
반응형

발표 일자 2024.11.12 TUE 10시a.m. 

CH21 물리 메모리 크기의 극복 - 메커니즘 

다수 프로세스들이 동시에 각자 큰 주소 공간을 사용하고 있다고 가정할 때 메모리 계층에 레이어의 추가가 필요하다 

큰 주소 공간을 지원하기 위해서 주소 공간 중에 현재는 크게 필요하지 않은 일부를 보통은 하드 디스크 드라이브에 보관한다 

메모리 계층에서 크고 느린 하드 디스크 드라이브가 가장 하부에 위치하고, 그 위에 메모리가 있다 

핵심 질문 - 물리 메모리 이상으로 나아가기 위해서 어떻게 할까 
운영체제는 어떻게 크고 느린 장치를 사용하면서 마치 커다란 가상 주소 공간이 있는 것처럼 할 수 있을까? 

과거에 사용되던 메모리 오버레이 Memory Overlay 라는 시스템은 프로그래머가 코드 or 데이터의 일부를 수동으로 메모리에 탑재/ 제거했다, 현재는 이와 대비되게, "가상" 환경을 사용하여 프로그램의 자료 구조들을 위한 충분한 메모리 공간이 있는지 걱정하지 않아도 된다 

🐣 프로세스에게 "큰" 주소 공간을 제공해야 하는 이유는 편리함과 사용 용이성 때문이다 

 

스왑 공간이 추가되면 운영체제는 실행되는 각 프로세스들에게 큰 가상 메모리가 있는 것 같은 환상을 줄 수 있다 

멀티프로그래밍 시스템이 발명되면서 많은 프로세스들의 페이지를 물리 메모리에 전부 저장하는 것이 불가능하게 되었고, 이로 인해 일부 페이지들을 스왑 아웃하여 추가적인 메모리 공간을 확보할 필요가 생겼다, 이것이 Virtual Memory 가상 메모리의 역할이다 

21.1 스왑 공간

디스크에 페이지들을 저장할 수 있는 일정 공간을 스왑 공간 Swap Space 라고 한다 

메모리 페이지를 읽어서 이곳에 쓰고 Swap Out, 페이지를 읽어 메모리에 탑재시키기 Swap In 때문에 스왑 공간이라고 불린다 

+ 페이지 인, 페이지 아웃 이라고 할 수도 있다 

+ 스왑 공간은 이미 한번 메모리에 로드됐던 페이지를 내리고 올리는 공간으로, 처음 프로그램이 실행될 때 메모리로 데이터가 로드되는 과정은 스왑 공간과는 무관하다

스왑 공간의 입출력 단위는 페이지라고 가정하고, 운영체제는 모든 페이지들의 디스크 주소를 기억해야 한다 

시스템이 사용할 수 있는 메모리 페이지의 최대수를 결정하기 때문에, 스왑 공간의 크기는 매우 중요하다 

스왑 공간에만 스왑을 할 수 있는 것은 아니다 (여기 부분 이해가 안 간다)

🐣 추가 공간이 필요할 때 코드 영역의 페이지들이 차지하는 물리 페이지를 다른 페이지가 사용할 수 있다는 부분이 이해가 안 갔는데

방금 찍먹스터디에서 같이 토론하다가 결과를 도출해냈다 

VM 에 Code, Data, Heap, Stack 영역이 있을 때, 프로세스가 실행되면서 Code 를 제외한 다른 부분들은 변경이 될 수 있어서

Swap Out 하면서 해당 값을 저장하기 위해 쓰기 작업을 해줘야 하는데, 코드는 변경이 될 수 없는 부분이고 (Read-Only 임) 원본은 디스크에 있어서 언제든지 꺼내올 수 있기 때문에, 해당 프로세스를 사용하지 않을 때는 잠깐 삭제해도 괜찮다고 이해했다 🐣

21.2 Present Bit 

메모리가 참조되는 과정은, 프로세스가 가상 메모리 참조를 생성하고, 하드웨어는 메모리에서 원하는 데이터를 가져오기 전에 우선 가상 주소를 물리 주소로 변환한다 

하드웨어는 가상 주소에서 VPN 을 추출한 후에 TLB 에 해당 정보가 있는지 검사하고 (TLB 히트) 만약 히트가 되면 물리 주소를 얻은 후에 메모리로 가져온다 (추가적인 메모리 접근이 필요 없다)

만약 VPN 을 TLB 에서 찾을 수 없다면 (TLB 미스) 하드웨어는 페이지 테이블 베이스 레지스터를 사용하여 페이지 테이블의 메모리 주소를 파악하고, VPN 을 인덱스로 하여 원하는 페이지 테이블 항목 PTE 을 추출하여, 해당 페이지 테이블 항목이 유효하고 관련 페이지가 물리 메모리에 존재하면 PTE 에서 PFN 정보를 추출해서 TLB 에 탑재한다, TLB 탑재 후 명령어를 재실행하면 TLB 에서 히트된다 

페이지가 디스크로 스왑되는 것을 가능하게 하려면, 특히 하드웨어가 PTE 에서 해당 페이지가 물리 메모리에 존재하지 않는다는 것을 표현해야 한다, 하드웨어는 Present Bit 를 사용하여 각 페이지 테이블 항목에 어떤 페이지가 존재하는지를 표현한다 

Present Bit 가 1 로 설정되어 있다면, 물리 메모리에 해당 페이지가 존재한다는 것이고

0 으로 설정되어 있다면, 메모리에 해당 페이지가 존재하지 않고 디스크 어딘가에 존재한다는 것이다

물리 메모리에 존재하지 않는 페이지를 접근하는 행위를 페이지 폴트 Page Fault 라고 한다 

페이지 폴트가 발생하면 운영체제로 제어권이 넘어가고 페이지 폴트 핸들러 Page-Fault Handler 가 실행된다 

+ 하드웨어 입장에서는 예상치 못한 어떤 일이 발생하면, ‘예외’를 발생시키고 운영체제를 호출하여 일이 해결되기를 기다린다, 이러한 처리 과정이 실제 오류가 났을 때와 동일하 기에 예외를 오류라고 볼 수도 있는 것이다

21.3 페이지 폴트 

하드웨어 기반의 TLB 와 소프트웨어 기반의 TLB 모두 페이지 폴트가 발생하면 운영체제가 처리를 담당한다 (페이지 폴트 핸들러가 규정) 

요청된 페이지가 메모리에 없고 디스크로 스왑되었다면 운영체제는 해당 페이지를 메모리로 스왑해온다 

운영체제는 PFN 과 같은 PTE 비트들을 페이지의 디스크 주소를 나타내는 데 사용할 수 있어서, 페이지 폴트 발생 시, 페이지 테이블 항목에서 해당 페이지의 디스크 상 위치를 파악하여, 메모리로 탑재한다 

디스크 I/O 가 완료되면 운영체제는 해당 페이지 테이블 항목 PTE 의 PFN 값을 탑재된 페이지의 메모리 위치로 갱신하고, 작업이 완료되면 페이지 폴트를 발생시킨 명령어가 재실행되면서 TLB 미스가 발생할 수 있고, 미스 처리 과정에서 TLB 값이 갱신된다 

최종적으로, 마지막 재실행 시에 TLB 에서 주소 변환 정보를 찾게 되고, 이를 이용하여 물리 주소에서 원하는 데이터나 명령어를 가져온다 

I/O 전송 중에는 해당 프로세스가 차단된 Blocked 상태가 된다는 것을 유의해야 한다, I/O 실행은 매우 시간이 많이 소요되기 때문에 다른 프로세스의 실행을 중첩 Overloap 시키는 것이 효율적이다 

🐣 왜 페이지 폴트 Page Fault 는 운영체제가 처리하는가?

첫째로, 디스크에서 데이터를 불러오는 작업은 매우 느리기에 소프트웨어에 부담이 적다

둘째로, 페이지 폴트를 하드웨어가 직접 처리하려면 알아야할 정보가 너무 많다, 이 모든 것을 알고 있는 운영체제에게 맡기는 것이 훨씬 간편하다

🐣 물리 메모리에 없는 페이지 (Valid Bit 가 0인 페이지) 는 페이지 테이블에 디스크 주소가 적혀져 있어서 따라갈 수 있다 

근데 이제 PFN 이 아닌 다른 공간에 저장된다고 함 (Valid Bit 가 1인 페이지는 PFN 에 메모리 주소가 있음)

그리고 디스크의 정확한 위치가 아니라 스왑 디스크 블록 번호디스크 오프셋 같은 정보가 포함되어 있을 수 있다고 한다 

🐣 I/O 인터럽트 시작은 소프트웨어가, 마지막은 하드웨어가 보낸다 🐣

21.4 메모리에 빈 공간이 없으면?

스왑 공간으로부터 페이지를 가져오기 위한 Page-In 여유 메모리가 충분하지 않은 경우에 

탑재하고자 하는 새로운 페이지(들)를 위한 공간을 확보하기 위해 페이지 아웃 Page Out 하려고 할 수도 있다

교체 Replace 페이지를 선택하는 것을 페이지 교체 정책 Page-Replacement Policy 라고 한다 

잘못된 선택은 프로그램의 성능에 큰 악영향을 미치기 때문에 (잘못하면 디스크 속도로 움직인다)

좋은 페이지 교체 정책을 만들기 위한 많은 노력이 있었다 

21.5 페이지 폴트의 처리 

TLB 미스 발생 시 하드웨어 처리 과정을 보면 아래 세 가지 경우가 있다 

1) 페이지가 존재하며 유효한 경우 (18-21)

2) 페이지가 유효하지만 존재하지 않는 경우 (22-23) - 페이지 폴트 핸들러가 반드시 실행되어야 한다 

3) 페이지가 유효하지 않는 경우 (13-14)

운영체제가 페이지 폴트를 처리하는 과정은 아래와 같다 

1) 탑재할 페이지를 위한 물리 프레임 (물리 공간) 을 확보하고

2) 여유 프레임이 없다면, 교체 알고리즘을 실행하여 메모리에서 페이지를 내보내고 여유 공간을 확보한다 

3) 물리 프레임을 확보하고 I/O 요청을 통해 스왑 영역에서 페이지를 읽어 온다

4) 운영체제는 페이지 테이블을 갱신하고 명령어를 재시도한다 

5) 재시도를 하게 되면 TLB 미스가 발생하며 🐣바보짓🐣 또 한번의 재시도를 하면 TLB 히트가 된다 

21.6 교체는 언제 일어나는가 

메모리에 항상 어느 정도의 여유 공간을 비워두기 위해서, 대부분의 운영체제들은 

여유 공간에 관련된 최대값 High Watermark, HW최소값 Low Watermark, LW 을 설정하여 교체 알고리즘 작동에 활용한다 

여유 공간의 크기가 최소값보다 작아지면 여유 공간 확보를 담당하는, 일반적으로 스왑 데몬 Swap Daemon or 페이지 데몬 Page Daemon 이라고 불리는 백그라운드 쓰레드가 실행되고, 이 쓰레드는 여유 공간의 크기가 최대값에 이를 때까지 페이지를 제거한다, 충분한 여유 메모리가 확보되면 이 백그라운드 쓰레드는 슬립 모드로 들어간다 

일시에 여러 개를 교체하면 성능 개선이 가능하기 때문에 다수의 페이지들을 클러스터 Cluster그룹 Group 으로 묶어서 한번에 스왑 파티션에 저장함으로써 디스크의 효율을 높일 수 있다 

🐣 Page Fault 는 운영체제가 처리하고, 그 과정에서 공간 확보는 BG Pagging Thread 를 시킨다 🐣

21.7 요약 

실제 존재하는 물리 메모리의 크기보다 더 많은 메모리를 사용하기 위해서, 메모리에 특정 페이지가 존재하는지를 알리기 위한 Present Bit 와 좀 더 복잡한 페이지 테이블 구조가 필요하다는 것을 배웠다 

운영체제는 페이지 폴트 Page Fault 를 처리하기 위해서 페이지 폴트 핸들러 Page-Fault Handler 를 실행시킨다 

그리고 이 모든 작업은 프로세스가 인지하지 못하는 상황에서 처리된다는 것을 기억해야 한다 

 

반응형