Shared Pages
Shared Code
- 여러 프로세스에서 공유되는 읽기 전용 코드의 한 복사본
- 여러 스레드가 동일한 프로세스 공간을 공유하는 것과 유사하다.
- 읽기-쓰기 페이지의 공유가 허용된다면 프로세스간 통신에도 유용하게 사용 가능 (OS에 따라, Shared Page를 사용해서 Shared Memory를 구현하는 경우도 있다)
Private Code and data
- 각 프로세스는 코드와 데이터의 별도 복사본을 유지한다.
- 개인 코드와 데이터를 위한 페이지들은 논리적 주소 공간 어디에든 나타날 수 있다.
two-level paging
32비트 아키텍처에서 앞서 다룬대로 페이지 테이블을 만들면, 페이지의 크기가 4KB일 때 페이지 테이블은 각각 4MB가 된다. two-level paging은 이렇게 사용되는 메모리를 줄이기 위해 사용한다.
32비트에서, 10비트의 외부 페이지 테이블의 인덱스 p1과 10비트의 내부 페이지 테이블의 인덱스 p2, 그리고 오프셋 d가 주어진다.
p1은 참조하고자 하는 내부 페이지 테이블을 가리킨다.
p2는 참조한 내부 페이지 테이블에서 실제 데이터가 있는 페이지를 가리킨다.
d는 참조하고자 하는 실제 데이터가 해당 페이지의 어디에 위치하는지를 가리킨다.
이를 전방 매핑된 페이지 테이블(forward-mapped page table)이라고 한다.
만약 64비트라면 p1이 42비트가 되어 충분하지 않다.
이 경우, 2번째 외부 페이지 테이블을 추가할 수 있는데(3계층), 그럼에도 불구하고 2번째 외부 페이지 테이블은 여전히 2^32byte를 사용한다.
intel x86-64의 경우 64비트 중 48비트만 논리주소로 사용하고 4계층 테이블을 사용한다.
Hashed Page Tables
해시 페이지 테이블은 32비트 이상의 주소 공간에서 흔히 사용된다.
가상 페이지 번호(p)는 페이지 테이블에 해싱된다. 이 페이지 테이블에는 동일한 위치로 해싱되는 요소의 연결리스트가 포함된다.
각 요소에는 가상 페이지 번호, 매핑된 페이지 프레임의 값, 다음 요소를 가리키는 포인터가 포함된다.
가상 페이지 번호는 이 연결 리스트에서 일치 여부를 검색하기 위해 비교된다.
***
1) p가 해시함수를 통해 해시값으로 변환됨.
2) 해시테이블에서 해시값으로 연결리스트를 찾음. (연결리스트에는 동일한 해시를 갖는 페이지들이 모여있음)
3) 연결리스트에서 p와 같은 요소를 찾고, 프레임 번호를 얻는다!
***
Inverted Page Table
프로세스마다 페이지 테이블을 갖지 않고 물리적 페이지를 직접 관리하는 방법
실제 메모리 페이지마다 하나의 엔트리가 존재한다.
각 엔트리에는 실제 메모리 위치에 저장된 페이지의 가상 주소(p)와, 해당 페이지를 소유한 프로세스에 대한 정보(pid)가 포함된다.
테이블에서 p가 몇번째에 있는지 확인하고, i번째에 있을 때, 물리적 주소를 i라고 한다. 즉, 탐색하는데 시간이 오래걸린다.
따라서 해시테이블을 사용하여 탐색 시간을 줄일 수 있고, 별도의 하드웨어 캐시인 TLB를 사용하여 시간을 줄일 수 있다.
공유 메모리를 구현하는 것은 하나의 물리적 주소에 하나의 가상다른 방법보다 더 까다롭다.
Swapping
standard swapping = swapping : 프로세스 전체를 스와핑
paging : 페이지 단위로 스와핑
Swap out : 메모리 -> 백업 저장소
Swap in : 저장소 -> 메모리
프로세스의 총 물리적 메모리 공간이 실제 물리적 메모리를 초과할 수 있다.
백업 저장소는 모든 사용자의 메모리 이미지 복사본을 수용할 수 있을 만큼 크고 빠른 디스크이다.
이 저장소는 이러한 메모리 이미지에 대한 직접 접근을 제공해야 한다.
롤 아웃과 롤 인은 우선 순위 기반 스케줄링 알고리즘에서 사용되는 스와핑 방법이다.
우선순위가 더 낮은 프로세스가 swap out되어 우선 순위가 더 높은 프로세스가 로드되고 실행될 수 있다.
swapping 시간의 주요 부분은 전송 시간이다. 총 전송 시간은 메모리의 양에 직접 비례한다.
시스템은 디스크에 메모리 이미지를 가진 실행 준비가 된 프로세스의 ready queue를 유지한다.
이는 즉시 실행될 수 있는 상태의 프로세스들이 메모리에 로드될 수 있도록 대기하고 있다는 것을 의미한다.
일반적으로는 swap out된 프로세스가 동일한 물리적 주소로 swap in될 필요는 없으나, I/O 버퍼와 같은 주소 바인딩에 따라 같아야 할 수도 있다.
주소가 실행 시간에 바인딩 된 경우 (가상메모리) : 메모리의 다른 위치로 swap in 가능
주소가 컴파일 시간 또는 로드 시간에 바인딩 된 경우 : 동일한 물리적 주소로 다시 swap in 해야함
일반적으로 스와핑을 하지 않다가, 메모리가 임계값 이상 할당되면 스와핑이 시작된다.
Context Switch Time and Swapping
CPU에 올릴 다음 프로세스가 메모리에 없다면, 프로세스를 swap out하고 목표 프로세스를 swap in한다. 이렇게 되면 context switch의 시간이 길어진다. (swap out 시간 + swap in 시간)
실제로 사용되는 메모리 양을 알면 swapping될 메모리의 크기를 줄여 시간을 줄일 수 있다.
시스템콜을 사용해 OS에게 메모리 사용을 알리는 request_memory()와 release_memory() 함수가 이에 사용될 수 있다.
보류중인 I/O가 있을 경우, I/O가 잘못된 프로세스로 이뤄질 수도 있어서 swap out을 할 수 없다.
또는 더블 버퍼링이라는 항상 I/O를 커널 공간으로 전송한 후 I/O장치로 전송하는 방법도 있는데 이는 오버헤드를 추가한다.
standard swapping은 현대의 운영 체제에서는 사용하지 않고 수정된 버전이 일반적으로 사용된다. 예를 들어 사용 가능한 메모리가 극도로 낮을 때만 스왑하는 경우가 있고, 이는 메모리 관리를 효율적으로 하고 시스템의 성능을 최적화한다.
Swapping on Mobile Systems
모바일 시스템에서는 일반적으로 지원되지 않는다.
모바일은 플래시 메모리를 기반으로 하는데, 이는 제한된 공간과 쓰기 주기 수를 가지고 CPU와 플래시 메모리 간 처리량이 낮기 때문이다.
대신 메모리 압축을 사용하고, 페이징을 사용하며, 메모리가 적을 때 다른 방법으로 메모리를 해제한다.
페이징이란 프로세스 단위가 아닌 페이지 단위로 swapping을 하는 것을 뜻한다.
iOS는 앱에게 할당된 메모리를 자발적으로 해제하도록 요청한다. 필요한 경우 읽기 전용 데이터는 폐기되고 플래시에서 다시 로드된다. 해제하지 않으면 종료될 수도 있다.
안드로이드는 메모리가 적을 때 앱을 종료하지만 빠른 재시작을 위해 애플리케이션 상태를 플래시에 기록한다.
Example: The Intel IA-32 Architecture
세그멘테이션과 페이징을 모두 지원한다.
각 세그먼트는 최대 4GB까지 가능하고, 프로세스 당 최대 16KB의 세그먼트를 가질 수 있다.
세그먼트는 두 파티션으로 나뉜다.
첫 번째 파티션에는 최대 8KB의 세그먼트가 프로세스에게 개인적으로 제공된다. (로컬 디스크립터 테이블 = LDT에 저장됨)
두 번째 파티션에는 최대 8K의 세그먼트가 모든 프로세스 간에 공유된다. (글로벌 디스크립터 테이블 = GDT에 저장됨)
CPU는 (선택자, 오프셋) 형태의 논리적 주소를 생성하고 이 선택자를 세그멘테이션 유닛으로 전달한다.
이로써 선형 주소를 생성하고 이 주소는 페이징 유닛으로 전달한다.
페이징 유닛은 주 메모리의 물리적 주소를 생성하고, 페이징 유닛들은 메모리 관리 유닛(MMU)의 기능을 수행한다.
페이지의 크기는 4KB 또는 4MB가 될 수 있다.
logical address : 논리 주소, 세그먼트 번호와 세그먼트 내의 오프셋으로 구성된다.
segmentation unit : 세그멘테이션이란 메모리를 고정 크기가 아닌 가변 크기의 세그먼트로 분할하는 것을 뜻한다. 세그멘테이션 유닛은 논리 주소를 세그먼트 번호와 오프셋으로 분리하고 이를 사용해 선형 주소를 생성한다.
16비트의 셀렉터에 세그먼트 번호와 세그먼트의 종류, 프로텍션에 대한 정보가 들어가고, 32비트에 세그먼트 오프셋이 들어간다.
세그먼트 디스크립터로 32비트의 세그먼트 기본 주소를 구하고 오프셋을 더하여 선형 주소를 구한다.
여기서 선형 주소는 two-level paging의 구조를 가지고 있다.
외부 페이지 테이블, 즉 page directory는 page_size라는 flag를 가지고 있는데 0이면 4KB의 페이지, 1이면 4MB의 페이지 프레임을 뜻한다.
찾고자 하는 내부 페이지 테이블(또는 페이지 프레임)이 존재한다면, 그 엔트리의 invalid bit는 1로 나타나고 나머지 31bit로 디스크 내의 찾고자 하는 내부 페이지 테이블(또는 페이지 프레임)의 위치를 나타낸다.
만약 4KB 페이지라면 내부 페이지 테이블에서 해당 페이지를 찾고 오프셋을 더해 찾고자 하는 메모리 주소를 구한다.
4MB 페이지라면 page directory의 offset에 선형 주소의 offset(여기서의 offset은 12비트가 아닌 22비트가 된다)을 더해 찾고자 하는 메모리 주소를 구한다.
Intel IA-32 Page Address Extensions
32비트 아키텍처는 기본적으로 4GB까지의 메모리 공간에 접근할 수 있다.
인텔은 페이지 주소 확장(Page Address Extensions, PAE)을 만들어서 4GB 이상의 메모리 공간에 접근할 수 있게 했다.
이를 위해 페이징은 3단계 체계로 변경되었다.
가장 상위의 두 비트는 페이지 디렉토리 포인터 테이블(PDPT)을 참조한다. 이는 4개의 엔트리로 구성되며, 각 엔트리는 page directory를 가리킨다.
그리고 page directory와 page table의 각 엔트리가 64bit로 확장하고, base address를 20에서 24비트로 확장한다.
이때 논리적인 메모리는 여전히 2^32지만, 물리적인 메모리는 2^36까지 가능해서 64GB의 메모리를 사용할 수 있게 된다.
PAE는 macOS, Linux는 지원하지만 window-32는 지원하지 않는다.
Intex X86-64
64비트를 사용하여 매우 큰 메모리 공간(16 엑사바이트 이상)을 지원한다.
그러나 실제로는 48비트 주소 지정만 구현된다.
페이지 크기는 4KB, 2MB, 1GB가 있고 페이징 계층은 총 4단계이다.
또 PAE를 사용해 가상 주소를 48비트(256TB)로 하고, 물리 주소를 52비트(4PB)로 설정할 수 있다.
ARM Architecture
ARM은 모바일 플랫폼 칩으로 주로 사용되며, 에너지 효율적인 32비트 CPU이다.
페이지 크기는 4KB와 16KB를 지원하며, 동시에 섹션이라 불리는 1MB와 16MB 페이지를 지원한다.
섹션에 대해 one-level 페이징을 사용하고, 작은 페이지에 대해 two-level 페이징을 사용한다.
arm 아키텍처에는 두 단계의 TLB가 있다.
바깥쪽에는 두 개의 micro TLB (데이터용, 명령어용)이 있고, 안쪽에는 하나의 주 TLB가 있다.
먼저 안쪽 TLB를 확인하고 만약 미스가 발생하면 바깥쪽 TLB를 확인하며, 이 또한 미스가 발생하면 CPU에 의해 페이지 테이블 워크를 수행한다.
'학교강의필기장 > 운영체제론' 카테고리의 다른 글
운영체제론[17]: 가상메모리 - 2 (0) | 2023.06.22 |
---|---|
운영체제론[16]: 가상메모리 - 1 (0) | 2023.06.22 |
운영체제론[14]: 메모리 - 1 (0) | 2023.06.22 |
운영체제론[13]: 데드락 (0) | 2023.06.22 |
운영체제론[12]: 동기화 방법 (0) | 2023.06.22 |