: 프로세스들은 cpu와 메인 메모리를 다른 프로세스들과 공유한다.
-> 이 때 메인 메모리를 공유하다보면 프로세스들의 속도가 느려지거나, 실행하지 못 하게 될 수도 있고, 메모리는 손실에도 취약하다.
메모리를 보다 효율적으로 관리하기 위해 현대의 시스템에서는 가상메모리(VM, 메인 메모리의 추상화)를 제공한다.
가상 메모리는 각 프로세스에 하나의 크고, 통합된, 사적 주소공간을 제공한다.
[가상 메모리의 중요한 기능 3가지]
1. 메인 메모리를 디스크에 저장된 주소 공간에 대한 캐시로 취급
-> 메인 메모리 내 활성화 영역만 유지하고, 데이터를 디스크/메모리 간 필요에 따라 전송 = 메인 메모리 효율성 높임
2. 각 프로세스에 통일된 주소공간을 제공함으로써 메모리 관리의 단순화
3. 각 프로세스 주소공간을 다른 프로세스에 의한 손상으로부터 보호
=> 줄이면 보안 및 안정성 증가/개발의 용이성/메모리 관리의 단순화
cpu가 메모리에 접근하는 방식은 두 가지가 있다
1. 물리주소 방식
: 메인 메모리가 연속적인 바이트 크기 셀의 배열로 구성
각 바이트는 고유의 물리 주소(physical address)를 가진다
[물리 주소를 사용해 cpu가 메모리에 접근하는 방법]
1. cpu의 load 명령을 실행해 데이터를 읽어옴
2. cpu는 유효한 물리 주소를 생성
3. 유효한 물리 주소를 메모리 버스를 통해 메인 메모리에 전달
4. 메인 메모리는 읽은 데이터를 cpu에게 돌려줌
5. cpu는 그걸 레지스터에 저장
2. 가상주소 방식
[가상주소를 사용해 cpu가 메모리에 접근하는 방법]
1. cpu는 가상 주소(virtual address)를 생성해 메인 메모리에 접근
2. 주소 번역
- 메인 메모리에 보내기 전 가상 주소를 적절한 물리 주소로 바꾸는 과정
- 이 과정에서 cpu와 운영체제 간 긴밀한 협력이 필요함
- cpu 칩 내 메모리 관리 유닛(MMU)라고 부르는 전용 하드웨어는 메인 메모리에 저장된 참조 테이블을 사용해 실행 중 가상주소를 번역하며, 테이블의 내용은 운영체제가 관리
3. 이후는 물리 주소 방식대로 메인 메모리에 접근
: 비음수 정수 주소의 정렬된 집합 (ex. {0, 1, 2}
선형 주소공간
: 주소 공간의 정수가 연속적인 경우
가상 주소공간
: cpu는 가상 주소공간이라고 불리는 N=2^n 주소의 주소공간에서 가상의 주소를 생성함
ex) {0, 1, 2, …, N-1}
물리 주소공간
: M바이트의 물리 메모리에 대응되는 물리 주소 (M은 항상 2의 제곱일 필요X)
ex) {0, 1, 2, …, M-1}
[주소공간의 중요성]
- 데이터 객체(바이트)와 그들의 특성(주소)들 간 명확한 구별
- 각 데이터 객체가 다중 독립 주소를 가질 수 있도록 함
- 각각의 주소는 서로 다른 주소공간에서 선택됨
- 메인 메모리의 각 바이트는 가상 주소공간으로부터 선택된 가상주소를 가짐
결과적으로 가상 메모리는
[가상 페이지의 부분집합]
1. Unallocated: VM 시스템에 의해 아직 할당되지 않은 페이지들
-> 비할당된 블록들은 이들과 관련된 데이터를 가지고 있지 않으며, 어떤 공간도 차지하지 않음
2. Cached: 현재 물리 메모리에 캐시되어 할당된 페이지들
3. Uncached: 물리 메모리에 캐시되지 않은 할당된 페이지들
DRAM? SRAM?
DRAM 캐싱 시 발생할 수 있는 비용
1. 큰 규모의 미스 비용
2. 첫 번째 바이트를 접근하는데 드는 비용
아무튼 큼, 이런 비용을 줄이기 위한 DRAM 캐시 구성
[추가부분 필요…]
물리주소 방식은 cpu가 물리 주소를 메인 메모리에 바로 입력해 메모리 참조를 진행
-> 각각의 프로세스에 메모리 공간을 할당하기엔, 실제 메모리 크기의 한계가 있음
근데, 프로세스를 실행하기 위해 코드는 반드시 메모리에 있어야 하는데…
이 때 어떻게 하면 한정된 메모리에서 여러 프로세스를 실행시킬 수 있도록 메모리 구조를 할당할 수 있을까?
= 메모리가 실제 메모리보다 많아 보이게 추상화하여 제공하는게 가상 메모리
즉, 물리 메모리 크기의 한계를 극복하기 위해 가상 메모리가 등장함
기본 아이디어
: 프로세스는 가상 주소를 사용하고, 실제 해당 주소에서 데이터를 읽고 쓸 때만 물리 주소로 바꿔주면 된다
virtual address: 프로세스가 참조하는 가상 주소
physical address: 실제 메모리 주소
cpu가 특정 프로세스의 어떤 공간을 참조할 때 우선 가상 주소를 먼저 참조하고, 가상 주소에 해당하는 실제 물리 주소를 참조
이 때 가상 주소를 참조할 때마다 가상 주소를 물리 주소로 변환을 하게 되니까, 이 시간을 줄이려고 MMU라는 하드웨어 칩의 지원을 받음
MMU(Memory Management Unit): 가상 주소를 물리 주소로 빠르게 변환해주는 장치,
cpu는 가상 메모리 주소를 다루고, 실제 해당 주소에 접글할 때 MMU 하드웨어 장치를 통해 물리 메모리에 접근한다.
페이징 시스템
하나의 프로세스에서 특정 시간동안 쓰는 메모리 영역은 아주 일부분이기 때문에, 이 일부분만 실제 물리 메모리에 올려놓고 쓰자는 것이 가상 메모리인데, 이 때 어느 정도의 사이즈만큼 메모리에 올릴 지 결정해야 한다.
가상메모리를 일정 크기로 쪼개서 그 크기에 맞춰 프로세스를 잘라넣는 방식
이를 page라는 단위로 다루겠다는 것이 Paging System
모든 캐시에서처럼 VM 시스템은 가상페이지가 DRAM 어딘가에 캐시되어있는지 알 수 있는 방법이 필요하다.
그럼 어떤 물리 페이지를 캐싱했는지 알아야 한다.
만일 미스가 존재한다면, 디스크 어디에 가상 페이지가 저장되어 있는지 결정해야 하며, 물리 메모리 중에서 희생자 페이지를 선택해야 하고, 가상 페이지를 디스크에서 DRAM으로 복사해 희생자 페이지를 교체한다.
캐시 미스?
: 컴퓨터가 메인 메모리에 저장되지 않은 데이터를 읽거나 쓸 때 발생하는 문제
가상 메모리 시스템에서의 캐시 미스는 가상 메모리 시스템으로부터 발생한 데이터 요청을 캐시 안에서 찾을 수 없을 때.
페이징?
: 프로세스의 가상 주소를 크기가 동일한 페이지라는 일정 단위로 나눠서, 가상 주소 공간과 이에 매칭되는 물리 주소 공간을 관리하는 것 (불연속적)
- 하드웨어의 지원이 필요
- 페이지 번호를 기반으로 가상/물리 주소의 매핑 정보를 기록하고 사용한다
- 페이지 단위로 물리 메모리에 넣고, 해당 데이터를 찾을 때도 페이지 번호를 기반으로 주소를 찾음
이 때, 프로세스를 이루는 페이지가 어느 물리 주소 공간에 매칭되어 있는지 cpu가 일일이 알기 어렵다
프로세스가 메모리에 불연속적으로 배치되어 있다면? cpu가 이를 순차적으로 실행할 수가 없음
즉, 다음에 실행할 명령어 위치를 찾기가 어려워짐 -> 페이지 테이블 등장
페이지 테이블?
: 물리 메모리에 저장된 자료구조로, 가상 페이지를 물리 페이지로 매핑해준다.
실제 메모리 내 주소인 물리 주소에 불연속적으로 배치되더라도, cpu가 바라보는 주소인 가상 주소에는 연속적으로 배치되도록 하는 방법 (프로세스마다 페이지 테이블이 있음)
페이지 테이블을 사용하면 물리적으로는 분산되어 저장되어 있더라도 cpu가 보는 가상 주소는 연속적으로 보이기 때문에 cpu는 가상 주소를 순차적으로 실행하면 된다.
페이지 테이블은 페이지 테이블 엔트리(PTE)의 배열이다.
[페이지 테이블 엔트리 구성]
- 한개의 유효비트(valid): 가상 페이지가 현재 DRAM에 캐시되어 있는지 아닌지
- valid = 1: Cached
- 주소 필드 -> 가상 페이지가 캐시되어 대응되는 DRAM의 물리 페이지 시작을 나타냄
- valid = 0:
- 주소 필드 = NULL -> Unallocated, 가상 페이지가 아직 할당되지 않음
- 주소 필드 != NULL -> Allocated
- 주소 필드 -> 디스크 상의 가상 페이지 시작 부분을 다리킴
- n비트의 주소 필드: Null, 물리 페이지 번호, 가상 페이지 주소를 나타냄
: CPU가 DRAM에 캐시되어 있는 가상 메모리의 워드 읽기에 성공
[과정]
1. 주소 번역 하드웨어가 해당 워드의 PTE를 찾아내기 위해 가상 주소를 인덱스로 사용하고, 메모리로부터 읽어냄
2. 주소 번역 하드웨어는 유효비트를 확인 -> 찾고자 하는 워드가 캐시되어 있는지/아닌지 확인
3. PTE 내 물리 메모리 주소를 사용해 해당 워드의 물리 주소를 구성
DRAM 캐시 미스, cpu가 DRAM에 캐시되어 있지 않은 워드를 참조하는 것
[과정]
1. cpu가 DRAM에 캐시되어 있지 않은 워드를 참조
2. 주소 번역 하드웨어는 메모리에서 PTE를 읽으면서, 해당 데이터가 캐시되어 있지 않다는 것을 유효비트로 알아냄
3. 페이지 오류 예외를 발생시킴
4. 페이지 오류 예외 -> 커널 내 페이지 오류 예외 핸들러 호출
5. 희생자 페이지 선택
6. 커널은 희생자 페이지에 대한 PTE를 수정해 유효 비트/주소 필드 업데이트(더이상 캐시되지 않았음을 갱신)
7. 커널은 디스크로부터 메모리로 원래 접근하고자 했던 워드 내 데이터를 복사
8. PTE 갱신 후 리턴
9. 페이지 오류 핸들러가 오류 인스트럭션 재시작
10. 오류 가상 주소를 주소 번역 하드웨어로 재전송
11. 이번에는 제대로 캐시되었으니 page hit
: 새로운 페이지 할당
[과정]
1. 운영체제가 가상메모리의 새로운 페이지 할당
2. 가상 메모리에 페이지가 할당됨
3. PTE가 새롭게 만든 페이지를 카리키도록 할당
demand paging??이랑 다름
가상 메모리 기법 중 하나.
페이지가 실제로 사용되기 전까지 물리적 메모리에 할당하지 않는 방식
=> 프로세스에 의해 메모리가 요청될 때까지 해당 메모리 페이지를 0으로 초기화해 대기시키는 게 아니라,
실제로 해당 페이지가 접근되어 사용될 때 ‘0’으로 채워진 페이지를 할당하고 초기화 [메모리의 효율적인 사용]
필요할 때 할당하니까, 시스템은 더 많은 프로세스를 동시에 관리할 수 있고 실제 사용되지 않는 메모리 페이지에 대한 물리적 메모리의 낭비를 줄임
[동작]
1. Page Fault: 프로세스가 아직 메모리에 로드되지 않은 주소에 접근해, 페이지 폴트 발생
2. Demand-zero: 페이지 폴트 핸들러가 해당 페이지를 물리적 메모리에 매핑되고, ‘0’으로 초기화
- 요구에 의해 제로화
3. 사용: 초기화된 페이지는 이제 프로세스에 의해 사용될 수 있고, 프로세스는 ’0’으로 초기화된 메모리를 사용해 자신의 데이터를 저장함
[장단점]
- 장점
- 메모리 절약: 실제 사용되지 않는 페이지가 물리 메모리를 차지하지 않음
- 효율성: 프로세스 시작 시 필요한 메모리를 할당할 필요가 없어 빠른 시작 가능
- 유연성: 프로세스가 필요한 만큼의 메모리만 사용, 메모리를 더 유연하게 관리 가능
- 단점
- 오버헤드: 페이지가 사용될 때마다 페이지 폴트 처리가 필요
- 성능 지연: 페이지를 ‘0’으로 초기화하는 과정에서 미세한 지연 발생, 페이지 폴트가 빈번하게 발생하면 시스템의 전체적인 성능에 영향이 감
: 운영체제의 커널이 제공하는 서비스에 대해 응용 프로그램의 요청에 따라 커널에 접근하기 위한 인터페이스
운영체제는 커널모드와 사용자 모드로 나눠서 구동되는데 (=이중 동작 모드),
이는 커널에서 중요한 자원들을 관리하기 때문에, 사용자가 그 중요한 자원에 접근하지 못 하도록 함 = 시스템 보호 목적
커널 모드: 모든 자원에 접근/명령 가능
사용자 모드: 사용자가 접근할 수 있는 영역을 제한적으로 두고, 자원에 함부러 침범하지 못 하게 함
-> 시스템 콜은 커널 영역의 기능을 사용자 모드에서 사용 가능하게, 즉 프로세스가 하드웨어에 직접 접근해서 필요한 기능을 사용할 수 있게 함
[처리 과정]
1. 사용자 프로세스가 시스템 콜 호출 = 커널 모드 진입
2. 커널은 내부적으로 시스템 콜을 구분하기 위해 기능별 고유번호를 할당하고 그 번호에 해당하는 제어 루틴 정의
3. 커널은 요청받은 시스템 콜에 대응하는 고유번호 확인 후 번호에 맞는 서비스 루틴 호출
4. 서비스 루틴 처리 후, 사용자 모드 전환
[유형]
1. 프로세스 제어: 프로세스 실행/생성/대기 등fork(), exec(), wait(), exit()
- 파일 조작: 파일 열기/읽기/쓰기 등
open(), read(), write(), close()
- 장치 관리: 디바이스 부착/분리/읽기/쓰기 등
ioctl(), read(), write()
- 정보 유지: 시간, 날짜 설정 등
getpid(), alarm(), sleep()
- 통신: 통신 연결 생성/제거/상태 정보 전달 등
pipe(), shm_open(), mmap()
+) 페이지 교체
LRU, FIFO, random 등등 추가 공부하기