[OS] Virtual Memory : Issues in Demanding Paging

parkheeddong·2023년 5월 30일
0

Operating System

목록 보기
46/63
post-thumbnail

Issue 1. Page Sharing


🔔 Page Sharing Concept

하나의 컴퓨터 시스템을 여러 사용자가 사용하기 때문에, 각 프로세스들이 사용하는 라이브러리 함수들을 프로세스들이 공유하는 것이 더 합리적이다!

-> 페이지를 프로세스간에 공유할 수 있는 기법이 필요하다.


1) Procedure Pages

코드가 들어있는 페이지
-> Pure Code여야 한다. (= reentrant code: 재진입성 코드)

📌 Impure Code

한 프로세스가 특정 코드를 실행하면서 그 코드 자체를 변경시키는 경우가 있다. 이런 코드를 'Impure Code'라고 한다.

📌 Pure Code

프로세스가 특정 코드를 실행하면서 그 코드 자체를 변경시키지 않고, 있는 그대로 실행만 하는 경우의 코드.

2) Data Pages

데이터가 있는 코드

📌 Read Only Data

어떠한 제한 없이 프로세스 간 공유가 가능하다.

📌 Read Write Data

write가 가능한 데이터라면 변경이 가능한 데이터이기 때문에, concurrency control 메커니즘(synchronization, mutual exclusion)을 가진 상태에서 공유해야 한다.


🌱 데이터 페이지 공유

메모리의 페이지 프레임 p'에 데이터 페이지가 있다고 하자. 이 p'를 P1과 P2가 모두 공유하는 상황이라고 생각해보자.

p1은 n1개의 페이지를, p2는 n2개의 페이지를 갖고 각자의 PMT를 갖고 있는 상태이다.

두 프로세스 모두 가상주소 V = (k1, d), (k2, d)를 generation 하면 residence bit = 1임을 확인하고 (p', d)로 접근할 수 있다.

이 경우 data page는 두 프로세스에게 공유되고 있는 상황이다.


🌱 Procedure 페이지 공유

코드로 이뤄진 page frame p'을 p1과 p2가 공유하려고 한다고 생각해보자.

각자 (k1, d)와 (k2, d)의 virtual address 를 generation 하면 residence bit = 1이므로, page frame number로 (p', d)의 real address가 되어서 접근할 것이다.

이 경우 만약 p'에 브랜치 명령이 있다고 생각해보자. 그 p'에 있는 특정 영역으로 이동하려고 하는데, 그 때 virtual address(?, d)를 무엇이라 명명해야 할까? p1의 경우 k1이고, p2의 경우 k2이다.

그러나 이것은 공유 페이지이기 때문에 p1이던 p2이던 문제가 생기게 된다.


✨ Procedure 페이지 공유 문제 해결방법

따라서 같은 페이지 번호인 'k'에서 해당 페이지 프레임 p'을 공유해야 한다.
그렇게 된다면 Branch를 (k, d)로 할 수 있고 두 프로세스 모두 문제 없이 p'의 코드를 실행할 수 있다.





Issue 2. Page Fault Handling



❌ Page Fault 의 문제상황

기계어 명령 ADD A, B, C : A와 B를 더하여 C에 저장하라.

  1. 명령어를 Fetch한 후, 해독한다.
  2. 명령어 A를 fetch한다.
  3. 명령어 B를 fetch한다.
  4. A와 B를 더한다.
  5. C에 저장한다.

A번지와 B번지가 모두 Address Mapping을 했는데, 해당 페이지가 메모리 안에 있어서(residence bit = 1) fetch했다고 가정해보자.

C번지도 real address로 바꾸어서 address mapping을 하려고 하니, c번지는 페이지가 메모리에 없다고 가정해 보자. ➡ 이때 Page Fault 발생한다❗

이 경우 이 프로세스는 더 이상 실행할 수 없고 context switching해야한다.

그러나 기계어 명령은 atomic해야 하는데, 5번 단계를 마치지 못한 상태에서 context switching을 해야 하는 것이다.

중간에 이렇게 멈추게 되면, program counter는 이미 다음 명령어를 가리키기 때문에 현재 명령은 실행하지 못하고 건너 뛰는 결과가 되어버린다.

🔔 Solution

다시 프로세스가 실행되면 이 Instruction을 다시 실행하도록 'Exception Handling'을 해야 한다 !

1, 2, 3, 4번 사이에 레지스터값을 바꾸거나 하는 등의 변경사항은 원래대로 cancel 시키고, program counter의 값도 현재 명령어로 바꾸어놓는 일을 해야 한다.

➡ 따라서 Virtual Memory를 사용하는 컴퓨터 시스템은 모든 기계어 명령들을 Page Fault가 발생할 경우를 위해 Restartable Instruction으로 만들어야 한다!




Issue 3. Paging System의 성능 문제

평균 메모리 접근 시간(ma) : 100ns
평균 페이지 서비스 시간(pagingTime: page fault로 하드디스크에서 페이지 읽어서 메모리에 두는 시간) : 8ms
Page Fault Rate : p (0 <= p <= 1)
EAT(Effective Acces Time) :
(1-p) ma + p pagingTime = (1-p) 100 + p 8,000,000 = 100 + 7,999,900 * p
만약 p = 1/1000이라면 EAT = 8.1microseconds

8.1microseconds는 메모리 접근시간의 약 80배에 해당한다. ( = 80 * ma)

즉 프로세스의 실행 시간도 80배 느려지는 것이다.
virtual memory를 사용하지 않는 프로세스가 virtual memory를 사용하면 80배 느려지는 것이다.

만약 성능을 딱 10% 저하까지만 허용한다면,
EAT = 100 + 7,999,999 * p < 110
p < 1/800,000 이어야 한다.

즉 80만번에 한번만 page fault가 발생하도록 해야 virtual memory 시스템이 합리적으로 돌아갈 수 있다.






Issue 4. Copy-on-Write Scheme (CoW)



📌 Fork 시스템 콜

유닉스, 리눅스 운영체제에서 한 프로세스가 실행하다가 다른 프로세스를 실행시키는 시스템 콜이다. 즉, 부모 프로세스가 fork() 로 자식 프로세스를 생성한다.

자식 프로세스는 부모 프로세스의 모든 것을 물려받기 때문에 pid 빼고 모든 context가 동일하다. 즉, duplicate된 프로세스나 다름 없다.

만약 메모리에 parent가 page를 4가지 가지고 있었는데, fork 시스템 콜로 child process를 만들면, page 역시 4개 copy되어야 한다. 그런데.. 꼭 이렇게 copy해야 할까?!



🔔 Better Solution

어차피 똑같은 4개의 페이지를 쓰게 할거면 이미 있는 부모의 4개 페이지를 공유하도록 하자 !

위처럼 parent process의 PMT와 child process의 PMT가 PAGE를 공유한다. 이 때 child process와 parent process의 PMT에 해당 공유되는 페이지는 CoW로 마킹이 되어 있다.

그런데 만약 parent가 페이지를 변경하거나 update하게 되면, child process는 영향을 받으면 안 되므로 해당 페이지는 copy되어야 한다!

즉, 두 프로세스가 같은 페이지를 공유하다가 변경사항이 있으면 copy하고 그 다음 write한다! (copy-on-write = CoW break)

0개의 댓글