9. 가상 기억장치(Virtual Memory)
▶ 목적: 프로세스가 기억장치 내에 전부 존재하지 않아도 수행이 가능하게 하기 위한 기법
→ 요구 페이징 형태의 가상 기억장치에 대해 논의
9.1 배경(Background)
▶ 일반적으로 수행을 위해 프로그램 전체를 요구하지 않고, 전체 프로그램을 요구하는 경우에도 동시에 모두 요구하지 않음
▶ 프로그램의 부분적인 적재 및 수행의 장점
- 실제 기억 공간의 양에 제한을 받지 않음
- 실제 기억 공간을 적게 차지하므로 보다 많은 사용자 프로그램이 수행될 수 있음
- 적재(load)나 교체(swap)를 위한 입출력이 적어지므로 수행이 신속해짐
▶ 가상 기억장치: 물리 기억장치로부터 사용자 논리 기억장치를 분리
→ 매우 큰 가상 기억장치를 제공
[그림 9.1] 물리 기억장치보다 큰 가상 기억장치를 나타내는 도표
▶ 가상 기억장치의 구현
- 요구 페이징(demand paging): 많이 사용
- 요구 세그먼테이션(demand segmentation): 가변 크기의 세그먼트로 인해 복잡
ex) Burroughs 컴퓨터 시스템, IBM OS/2
9.2 요구 페이징(Demand Paging)
▶ 개념: 스와핑(swapping) 기법을 쓰는 페이징 체제와 유사
[그림 9.2] 연속된 디스크 공간에 페이지화된 기억 장치의 이동
1) 전체 프로그램은 보조 기억장치에 저장하고
2) 게으른 스와퍼(lazy swapper)에 의해 요구된 페이지만 기억 장치에 교체로 저장
- 스와퍼(swapper): 프로세스 전체 교체기
↕
- 페이저(pager): 개개의 페이지 교체기 - 보다 적합한 용어
→ 해당 페이지의 위치를 구별하기 위해 페이지 테이블의 유효/무효 비트 기법 사용:
기억장치 ↔ 디스크
[그림 9.3] 일부 페이지가 주기억장치에 없을 때의 페이지 테이블
3) 무효 페이지 접근시, 페이지 부재 트랩 발생에 의한 교정: p.316-317의 과정 1-6
[그림 9.4] 페이지 부재를 처리하는 단계
▶ 순수 요구 페이징(pure demand paging): 요구될 때까지 결코 페이지를 기억 장치 속에 들여놓지 않는 방법
→ 기억 장치 속에 어떠한 페이지도 가지지 않고 시작
▶ 요구 페이징을 위한 H/W 및 S/W
- H/W: 페이징과 스와핑을 위한 하드웨어와 동일
1) 페이지 테이블: 유효/무효 비트
2) 보조기억장치: 고속의 디스크 장치 사용 - 스왑 장치
- S/W: 페이지 부재(page fault)를 해결 후 명령어를 다시 시작해야 함
ex) C ← A + B: p.318의 1-5
→ 단계 5에서 페이지 부재가 발생하면, 요구된 페이지를 가져온 후 단계 1부터 재 수행함
9.3 요구 페이징의 성능(Performance of Demand Paging)
▶ 요구 페이지화된 기억 장치에서의 유효 접근 시간
- 기억 장치 접근 시간(memory access time): ma
- 페이지 부재 확률: p
→ 유효 접근 시간 = (1-p) * ma + p * 페이지 부재 시간(page fault time)
(p.320의 1-12 참조)
▶ 페이지 부재 서비스 시간의 세 가지 주요 구성 요소
① 페이지 부재 인터럽트의 처리
② 페이지를 교체하여 읽어들임
③ 프로세스 재시작
ex) 평균 페이지 부재 서비스 시간: 25msec, 기억장치 접근 시간: 100nsec
→ 유효 접근 시간 = (1-p) * 100nsec + p * 25msec
= (1-p) * 100nsec + p * 25,000,000nsec
= (100 + 24,999,900*p)nsec
- if p = 0.001, 유효 접근 시간 = 25μsec - 250배 감속
- if 10% 미만으로 감속하려면, 110 > 100 + 25,000,000*p, p < 0.0000004
* 페이지 부재율이 매우 낮아야 프로그램 수행 시간을 적당한 수준에서 유지할 수 있음
9.4 페이지 교체(Page Replacement)
▶ 페이지 부재시 빈 프레임이 없는 경우: 과도 할당(over-allocation)
[그림 9.5] 페이지 교체의 필요성
① 사용자 프로그램을 중단하는 방법
② 프로세스 교체 방법: 다른 프로세스를 내보내 다중 프로그래밍 정도를 낮춰서 프레임을 확보
③ 페이지 교체 방법: 현재 사용되지 않고 있는 프레임을 스왑 공간에 저장하고 그 프레임을 확보
[그림 9.6] 페이지 교체 → p.324-325의 1-4
▶ 페이지 교체 시, 디스크로 나가는 페이지의 복사 시간 절약 방법
→ 수정 비트(modify/dirty bit) 사용: 즉, 페이지가 수정 상태가 아니면 예비기억장치에 복사할 필요 없음
▶ 요구 페이징 구현을 위한 두 알고리즘
- 페이지 교체 알고리즘: 희생될 페이지의 선택
- 프레임 할당 알고리즘: 프로세스마다 할당될 프레임 수 결정
9.5 페이지 교체 알고리즘(Page Replacement Algorithm)
▶ 알고리즘 선택 기준: 페이지 부재율(page fault rate)을 최소로 하는 알고리즘 선택
▶ 기억 장치 참조열(reference string): 난수 발생기에 의한 생성 또는 실제 시스템의 참조 기록
<자료의 양 축소>
- 주소(p+d) 대신 페이지 번호(p)만 고려
- 연속된 참조는 1회 참조로 간주: 연속된 참조시 페이지 부재가 발생하지 않기 때문
ex) 주소 참조열: 0100, 0432, 0101, 0612, 0102, 0103, 0104, 0101, 0611, 0102, 0103, 0104, 0101,
0610, 0102, 0103, 0104, 0101, 0609, 0102, 0105
→ 축소된 페이지 참조열(페이지당 100byte일 때): 1, 4, 1, 6, 1, 6, 1, 6, 1, 6, 1
▶ 프레임 수가 증가할수록 페이지 부재 수는 감소함
ex) 위의 페이지 참조열에 대해,
- 프레임 수 = 3: 3번의 부재 - 최초 참조시에만 발생
- 프레임 수 = 1: 11번의 부재 - 매 참조시 발생
[그림 9.7] 페이지 부재 대 프래임 수의 그래프
▶ (예)
- 프레임 수: 3
- 페이지 참조열: 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1
9.5.1 선입선출(FIFO; First-In-First-Out) 알고리즘
▶ 원칙: 가장 오래된 페이지를 대치 → 선입선출 큐 활용
[그림 9.8] 선입선출(FIFO) 페이지 대치 알고리즘 → 총 15번의 페이지 부재 발생
▶ 특성
- 알고리즘 간단
- Belady의 이상 현상 발생 가능
“할당되는 프레임 수가 증가해도 페이지 부재율이 증가하는 현상”
ex) 참조열: 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5
[그림 9.9] 어떤 참조열에 대하여 FIFO 대치 알고리즘을 적용했을 경우의 페이지 부재 그래프
9.5.2 최적(OPT, MIN; Optimal) 알고리즘
▶ 원칙: 앞으로 가장 오랜 기간 동안 사용되지 않을 페이지를 대치
[그림 9.10] 최적 페이지 대치 → 총 9번의 페이지 부재 발생
▶ 특징
- 최소의 페이지 부재율을 나타냄
- Belady의 변이가 나타나지 않음
- 참조열의 미래 정보를 요구하므로 비현실적인 알고리즘임
- 다른 알고리즘의 비교 평가를 위한 기준으로 사용
9.5.3 최근 최소 사용(LRU; Least Recently Used) 알고리즘
▶ 원칙: 가장 오랫동안 사용되지 않은 페이지를 대치
[그림 9.11] 최근 최소 사용 페이지 대치 → 총 12번의 페이지 부재 발생
▶ 특징
- 가장 최근의 과거를 가까운 미래의 근사치로 사용
→ 시간적으로 거꾸로 찾는 최적 페이지 알고리즘
- 구현 방법: 하드웨어 지원이 필히 요구됨
→ 매 기억장치 접근마다 소프트웨어로 정보 유지하는 것은 매우 느리기 때문
① 계수기(counter): 기억 장치 참조시마다 증가하는 계수기를 두고, 페이지를 참조할 때 그 페이지 테이블의 항목에 연관된 사용 시각 레지스터에 계수기의 값을 저장하는 방법
→ 최후 사용 시각이 가장 적은 페이지를 대치
② 스택(stack): 페이지 참조시마다 그 페이지 번호를 스택에서 제거하고 꼭대기(top)에 둠으로써 가장 최근에 사용된 순으로 정렬하는 방법
→ 바닥(bottom)에 있는 페이지를 대치
[그림 9.12] 가장 최근의 페이지 참조를 기록하기 위한 스택의 사용
- Belady의 변이가 발생하지 않음: n개의 프레임을 사용할 때 기억 장치에 있는 페이지 집합은 n+1개의 프레임을 사용할 때 기억 장치에 있는 페이지 집합의 부분 집합이기 때문
9.5.4 LRU 근접(Approximation) 알고리즘
▶ 원칙: LRU를 위한 고급 하드웨어 지원이 없는 시스템의 경우, 참조 비트(reference bit)를 이용하여 부분적인 순서 정보를 추출함으로써 근사 LRU를 구현할 수 있음
→ 페이지 참조시 참조 비트를 세트함으로써 페이지가 사용된 순서는 알 수 없으나 최근의 일정 기간 동안에 사용되었는지 여부를 구별해 낼 수 있음
(1) 참조 비트가 부가된 알고리즘(Additional-Rreference-Bits Algorithm)
- 각 페이지에 대해 참조 비트와 8비트 우측 이동 레지스터(right shift register)를 유지하고,
- 일정 간격으로 타이머 인터럽트가 발생될 때, 각 페이지의 참조 비트를 해당 이동 레지스터의 상위 비트로 전달하면서 우측으로 이동시키면,
- 레지스터의 무부호 정수 값이 작을수록 최근에 덜 사용된 것이므로, 그 값이 최소인 페이지를 대치함
ex) 00000000: 8번의 기간 동안 사용되지 않은 페이지
11111111: 각 기간마다 최소한 한번씩 사용된 페이지
11000100이 01110111보다 최근에 사용된 페이지의 레지스터 값
* 단지 참조 비트만 두고 이동 레지스터를 두지 않으면(0bit), 2차 기회 알고리즘에 해당됨
(2) 2차 기회 알고리즘(Second-Chance Algorithm)
- FIFO 대치 알고리즘을 기본으로 하여 희생자를 선택하는 것을 원칙으로 하되,
- 일정 간격으로 타이머 인터럽트가 발생될 때, 참조 비트가 1인 경우 0으로 변경하여 2차적 기회를 주고, 참조 비트가 0인 경우 대치한다.
- 물론, 페이지의 참조시 해당 참조 비트는 1로 세트된다.
→ 구현: 순환 큐(circular queue) 사용
[그림 9.13] 2차 기회 페이지 대치 알고리즘
(3) 2차 기회 개선 알고리즘(Enhanced Second-Chance Algorithm)
“(참조 비트, 수정 비트)”
- 1등급: (0, 0) - 최근 참조×, 변경×
- 2등급: (0, 1) - 최근 참조×, 변경○
- 3등급: (1, 0) - 최근 참조○, 변경×
- 4등급: (1, 1) - 최근 참조○, 변경○
→ 순환 큐에서 가장 낮은 등급 번호의 페이지를 대치
ex) 매킨토시 가상기억장치에서 사용
9.5.5 계수 알고리즘(Counting Algorithm)
▶ 계수기(counter): 각 페이지에 대해 참조한 숫자를 기록
(1) 최소 사용 빈도수(LFU; Least Frequently Used) 알고리즘
“각 페이지마다 참조 회수 계수기를 유지하고, 최소 값을 갖는(잘 사용되지 않는) 페이지를 대치”
(문제점) 초기 단계에만 빈번히 사용되는 페이지는 오랫동안 남게 됨
→ 지수적으로 감소하는 평균 사용 회수 사용: 일정 시간 간격마다 계수기를 우측 이동시킴
(2) 최대 사용 빈도수(MFU; Most Frequently used) 알고리즘
“각 페이지마다 참조 회수의 계수기를 유지하고, 최대 값을 갖는(이미 많이 사용된) 페이지를 대치”
(문제점) 지속적으로 사용되는 페이지가 있는 경우에는 역효과 발생
→ 페이지가 일정 기간 동안 사용되다가 필요 없어지는 경우에만 적합
▶ LFU와 MFU의 구현은 많은 비용이 소요되고, 최적 알고리즘에 접근하지도 않는 특별 알고리즘임
9.5.6 페이지 버퍼 알고리즘(Page Buffering Algorithm)
▶ 개념: “특정 페이지 대치 알고리즘 + 가용 프레임의 저장소”
→ 희생된 프로세스의 페이지가 보조 기억 장치로 가기 전에 임시로 저장하게 하여 해당 페이지가 곧 다시 필요해지면 신속하게 프로세스를 재개할 수 있게 하는 방법
▶ 추가적인 개선안
① 가용 프레임 저장소에 있는 페이지에 대한 수정 비트 리스트 관리
→ 페이지 기법의 장치가 쉬는 동안에, 가용 프레임 저장소에 있는 페이지의 수정 비트가 1이면 디스크에 기록하고 0으로 리셋함
② 가용 프레임의 저장소에 있는 페이지가 있었던 프레임 번호를 관리
→ 해당 페이지가 곧 다시 필요해지고, 있었던 프레임이 훼손되지 않았다면 프레임 보조기억장치로부터의 입력 없이 재사용 가능
9.6 프레임의 할당(Allocation of Frames)
▶ 개념: 다중 프로그래밍 기법을 사용할 때, 각 프로세스에 할당되는 프레임 수를 결정하는 문제
9.6.1 최소 프레임 수(Minimum Number of Frames)
▶ 명령어 집합 구조에 의해 정의됨
→ 즉, 하나의 명령어가 참조하는 모든 페이지를 수용할 수 있는 충분한 프레임 수
ex) PDP-11: 최소 6 프레임
IBM/370: 최소 8 프레임
Data General사의 Nova3: 최소 17 프레임 - 간접 참조의 영향
▶ 일반적으로 각 프로세스에 할당되는 프레임 수가 줄어들수록 페이지 부재율은 상승하고 수행 속도는 감소한다.
9.6.2 할당 알고리즘
▶ 다중 프로그래밍 정도에 따라 각 프로세스에 할당되는 프레임 수는 가변
▶ 균일 할당(equal allocation): 각 프로세스에 동등하게 할당
- 프레임 수: m
- 프로세스 수: n
→ m/n: 각 프로세스에 할당
m%n: 가용 프레임 버퍼 저장소(free frame buffer pool)
ex) 프레임 수 = 93, 프로세스 수 = 5
→ 18개씩 할당, 3개는 가용 프레임 버퍼 저장소로 사용
▶ 비례 할당(proportional allocation): 각 프로세스의 크기에 비례하여 할당
- 총 프레임 수:
- 프로세스 , 가상 기억 장소의 크기 , 할당 프레임 수
, (단, 최소 프레임 수 이상, 이하로 조정)
ex) m = 62, → ,
▶ 우선 순위 적용법: 우선 순위가 높은 프로세스에 많은 기억 장소를 할당하여 수행 속도를 높이는 방법
① 우선 순위와 프로세스 크기를 고려한 비례 할당법
② 우선 순위가 높은 프로세스가 낮은 프로세스에 할당된 프레임들 중에서 선택하는 방법
9.6.3 전역 대 국부 할당(Global Versus Local Allocation)
▶ 페이지 교체 알고리즘의 종류
① 전역 교체(global replacement): 전체 프레임 중에서 선택
- 각 프로세스에 할당되는 프레임 수 가변
- 각 프로세스의 페이지 부재율 및 수행 시간 가변
② 국부 교체(local replacement): 해당 프로세스에 할당된 프레임 중에서 선택
- 각 프로세스에 할당되는 프레임 수 불변
- 각 프로세스의 페이지 부재율 및 수행 시간 불변
* 전역 교체가 보다 좋은 성능을 보이는 일반적인 방법임
9.7 스레싱(Thrashing)
▶ 개념: 지나치게 자주 페이지 교환이 일어나는 현상 - “프로그램 수행시간 < 페이지 교환 시간”
→ 심각한 성능 저하 초래
9.7.1 스레싱의 원인(Cause of Thrashing)
▶ 중앙처리장치의 이용률 ↔ 다중 프로그래밍의 정도: [그림 9.14] 스레싱
▶ 발생 과정:
① 중앙처리장치의 이용률이 낮음
② 운영체제는 다중 프로그래밍의 정도를 높임
③ 페이지 부재율이 상승됨
④ 프로세스들이 페이징 처리 장치에서 대기함
⑤ 준비 큐가 비게 되어 중앙처리장치의 이용률이 낮아짐
⑥ 운영체제는 다중 프로그래밍의 정도를 더욱 높임: 악순환
⑦ 스레싱 발생
▶ 스레싱 방지 방법: 각 프로세스가 필요로 하는 프레임을 제공해야 함
- 프로세스 실행의 지역성 모델(locality model) 정의
- 지역(local): 실제로 함께 사용되는 페이지의 집합
[그림 9.15] 기억장치 참조 패턴의 국부성
ex) 서브루틴의 호출 시, 새로운 지역 정의:
→ 서브루틴의 명령어들, 지역 변수들, 전역 변수들의 집합
- 프로세스에게 현재의 지역을 만족시키는 충분한 프레임을 제공함으로써 스레싱을 방지할 수 있음
9.7.2 작업 집합 모델(Working-Set Model)
▶ 작업 집합(working set): 지역의 근사치
→ 작업 집합 창(working set window) (일정 시간, 일정 참조 횟수)에서 참조한 페이지 집합
[그림 9.16] 작업 설정 모델( = 10인 경우)
▶ 작업 집합의 정확도: 의 선택에 좌우됨
- 小: 전체 지역을 충족하지 못함
- 大: 여러 지역이 중복됨
▶ 시스템 내의 각 프로세스에 대한 작업 세트의 크기:
- 전체 요구 프레임:
- 총 유효 프레임 수: m
→ 만일 D > m이면, 스레싱 발생 가능
▶ 작업 집합 모델의 사용법
- 각 프로세스에 작업 집합의 크기에 맞는 충분한 프레임을 할당하되,
- 여분 발생 시에는 다른 프로세스를 작동시키고, 부족 시에는 한 프로세스를 중지시켜 확보함
→ 다중 프로그래밍의 정도를 가능한 높이면서도 스레싱을 방지할 수 있음
▶ 난점: 작업 집합의 추적
- 일정 간격 타이머 인터럽트(timer interrupt)와 참조 비트(reference bit)를 활용
→ 타이머 인터럽트마다 참조 비트를 복사하여 필요한 만큼 저장하여 작업 집합을 구함
9.7.3 페이지 부재 빈도(Page-Fault Frequency)
▶ 개념: 페이지 부재율을 직접 조절함으로써 스레싱을 방지하는 방법
[그림 9.17] 페이지 부재 빈도
→ 각 프로세스의 페이지 부재율에 대한 상한과 하한을 정하고,
- 상한 초과시: 프레임을 더 할당 → 여분 프레임이 없는 경우, 한 프로세스를 선택하여 중지시킴
- 하한 미만시: 프레임을 회수
9.8 기타 고려 사항(Other Considerations)
9.8.1 프리페이징(Prepaging)
▶ 개념: 프로세스의 시작 혹은 교체된 프로세스의 재시작의 경우, 필요한 것으로 간주되는 모든 페이지를 한꺼번에 기억장치에 가져옴으로써 페이지 부재를 감소시키는 방법
- 작업 집합 정보의 저장 필요
- 프리페이징에 드는 비용이 적어야 하고, 프리페이징에 의해 가져온 페이지가 사용되지 않는 비율이 적어야 함
9.8.2 페이지 크기(Page Size)
▶ 고려 사항
- 페이지 테이블 크기(↓) ↔ 페이지 크기(↑)
- 내부 단편화(↓) ↔ 페이지 크기(↓)
- 입출력 시간(↓) ↔ 페이지 크기(↑): 회전 지연의 횟수 감소(회전 지연 시간 > 전송 시간)
- 지역성(↑) ↔ 페이지 크기(↓)
- 페이지 부재율(↓) ↔ 페이지 크기(↑)
→ 페이지 크기를 결정하는 것은 어려움
9.8.3 역 페이지 테이블(Inverted Page Table)
▶ 역 페이지 테이블: 8.5.4절 참조
→ 메모리의 프레임마다 하나의 ‘항목’을 가짐: <process-id, page-number>
- 장점: 각 페이지 테이블을 별도로 저장하는데 필요한 메모리 총량 감소
- 단점: 페이지를 참조할 때 탐색 시간 증가
▶ 역 페이지 테이블은 요구 페이징이 필요로 하는 프로세스의 전체 논리적 기억 공간을 포함 못함
→ 프로세스마다 ‘확장된 페이지 테이블(extended page table)’을 두되, 페이지 부재가 발생할 경우에만 디스크에서 불러들여 사용함
9.8.4 프로그램 구조(Program Structure)
▶ 개념: 요구 페이징은 사용자 프로그램으로부터 감춰지지만, 그 특성을 알면 시스템 성능 개선에 도움이 됨
▶ (예) p.350-351의 두 프로그램
→ 페이지 부재 횟수(페이지 크기 = 128워드)
① 128 * 128 = 16,348회
② 128회
9.8.5 입출력 상호잠금(Input/Output Interlock)
▶ 개념: 요구 페이징을 사용할 때 일부 페이지를 기억장치에 고정시키는 것이 필요
▶ 어떤 프로세스가 입출력을 위해 장치 큐에 들어간 사이에 해당 페이지가 다른 프로세스의 수행을 위해 교체되어선 안됨
[그림 9.18] 입출력을 위하여 사용되는 프레임이 메모리내에 존재해야 하는 이유를 나타내는 도표
(해결책)
① 사용자 기억장치가 아닌 시스템 기억 장치에서만 입출력이 일어나게 하는 방법
“사용자 기억장치 ↔ 시스템 기억장치 ↔ 입출력 장치”
→ 오버헤드: ‘복사’
② 페이지들이 기억장치 속에서 잠금(lock)되게 하는 방법
→ 각 프레임마다 잠금 비트(lock-bit)를 두어, 입출력하는 동안 교체되지 않게 함
▶ 새로 읽은 페이지가 적어도 한번 사용되기 전에 우선 순위 교체에 의해 교체 당하는 것을 방지하기 위해 잠금 비트를 사용할 수 있음
→ 잠금 비트가 설정된 후 해제되지 않거나 과도한 잠금이 발생하지 않도록 해야 함
9.8.6 실시간 처리(Real-Time Processing)
▶ 실시간 시스템은 거의 가상 메모리를 사용하지 않음
→ 가상 메모리를 사용하는 경우, 해당 페이지를 잠금할 수 있게 함
9.9 요구 세그먼테이션(Demand Segmentation)
▶ 개념: 세그먼트 단위로 메모리를 할당
ex) OS/2
▶ 특징: 요구 페이징에 비해 효율은 떨어지지만 하드웨어가 부족한 경우에 적합
▶ 세그먼트 디스크립터(descriptor): 세그먼트 크기, 보호 정보, 위치 정보
- 유효 비트(valid bit): 해당 세그먼트가 메모리에 있는지를 나타내는 비트
- 접근 비트(accessed bit): 세그먼트 부재로 교체할 세그먼트의 선택을 위해 사용하는 비트
→ 요구 페이징에서의 참조 비트와 동일한 역할: 세그먼트 큐에 최근에 사용된 세그먼트가 헤드 부분에 위치하도록 하고 끝 부분의 세그먼트를 교체하면 됨