페이징
프로세스의 물리 주소 공간이 연속되지 않아도 되는 메모리 관리 기법!
페이징 기본 방법
- 물리 메모리 → 같은 크기 블록인 프레임(Fram)
- 논리 메모리 → 같은 크기 블록인 페이지(Page)
→ 논리 주소와 물리 주소가 완전히 분리되어, 물리 메모리 크기보다 더 큰 논리 주소 공간을 사용할 수 있다?!!
물리 주소
CPU로 부터 나오는 모든 페이지 주소는 페이지 번호, 페이지 오프셋이다.
- 페이지 번호(p)
- 물리 메모리 각 프레임의 시작 주소.
- 물리 메모리에서 “몇 번째 페이지에 해당하는가?”
- 예) 메모리의 2번째 페이지 → 페이지 번호 = 2
- 페이지 오프셋(d: offset)
- 참조되는 프레임 안에서의 위치.
- 해당 페이지 안에서의 정확한 데이터 위치.
- 예) 페이지 크기가 4KB(2^12 바이트) 라면, 오프셋 범위는 0부터 4095 까지..
- 프레임 시작 주소 + 페이지 오프셋 = 물리 메모리 주소
비유
도서관 책장에 비유해보자
- 책장(물리 메모리의 페이지)
- 책장 번호(페이지 번호) : 책장 내에서 몇 번째 책장에 있는가?
- 책(오프셋) : 해당 책장 번호의 책장 내에서 몇 번째 책인가?
CPU가 생성한 논리 주소를 물리 주소로 변환하기
MMU가 해당 단계를 실행한다.
- 페이지 번호p 를 추출해 페이지 테이블의 몇 번째 인덱스인지 확인한다.
- 책장에서 p 번째 서랍을 확인.
- 페이지 테이블에서 페이지 번호에 해당하는 물리 메모리의 프레임 번호를 가져온다.
- 페이지 번호 p 에 대응하는 프레임 번호가 f 를 찾아서 가져온다.
- 논리 주소의 페이지 번호 p를 프레임 번호f 로 바꾼다.
- p 와 f 를 찾았으니, 이제 오프셋을 사용하여 최종 물리 주소를 계산한다.
- 프레임 번호 + 오프셋 = 최종 물리 주소. ㅇㅋ?
→ 모든 논리 주소는 페이징 하드웨어에 의해 실제 주소로 바인딩 된다.
💡 페이징을 사용한다는 건, 각 메모리 프레임마다 하나씩 기준(또는 재배치)레지스터를 테이블로 유지하는 것과 유사하다.
→ 기준 레지스터는 논리 주소를 물리 주소로 변환해주는 레지스터
내부 단편화
페이징을 하면 모든 놀고 있는 프레임이 프로세스에 할당될 수 있기 때문에 외부 단편화가 발생하지 않는다. 하지만 **내부 단편화**가 발생한다..
- 프레임 할당은 항상 프레임의 정수배로 할당되기 때문이다.
- 만약 프로세스가 페이지보다 작은 메모리를 요구한다면, 마지막 페이지 프레임은 전부 할당되지 않는다.(꽉 채워지지 않음)
- 그럼 n + 1 번째 프레임은 거의 모두 내부 단편화가 됨 ㄷㄷ..
그럼 내부 단편화를 최대한 줄이기 위해서는 작은 페이지가 필요한 것 아닌가요?
- 하지만 페이지 크기가 작아지면 그에 반비례해서 페이지 테이블이 커지게 됨.
- 페이지 테이블이 차지하는 공간 낭비 ㅠㅠ
- 디스크 입장에서는 페이지 크기가 클수록 효율적이다.
- 디스크는 큰 메모리를 한 번에 읽는 게 효율적이라서! (디스크 탐색 시간 감소)
→ OS 마다 페이지 크기가 다르지만, 일반적으로는 페이지 크기가 프로세스, 메인 메모리에 따라 같이 커져왔다!
프로세스가 실행될 경우
- 프로세스의 크기가 페이지 몇 개 분에 해당하는가 조사.
- 프로세스가 n 개의 페이지를 요구하면 메모리에서 이용할 수 있는 프레임이 n 개 있어야 한다.
💡페이지 메모리 시스템에서 물리 메모리의 크기는 프로세스의 최대 논리적인 크기와 다르다.
→ 논리 메모리가 더 크다! 가상 메모리 사용하여 스왑 가능.
페이징의 가장 중요한 특징
메모리에 대한 프로그램의 인식과 실제 내용이 서로 다르다! 는 것.
- 프로그램 : 메모리는 하나의 연속적인 공간이며, 메모리에는 이 프로그램만 있다고 생각함.
- 실제 : 프로그램은 여러 곳에 프레임 단위로 분산되어 있고, 많은 다른 프로그램이 올라와 있음.
→ 주소 변환 하드웨어에 의해 이 차이가 해소된다. → 운영체제에 의해 조정 됨.
그래서
사용자 프로세스는 자기 것이 아닌 메모리는 접근조차 할 수 없다.
- 왜냐하면, 페이지 테이블을 통하지 않으면 다른 공간에 접근할 길이 없다.
- 페이지 테이블은 그 프로세스가 소유하고 있는 페이지들만 가리키고 있기 때문에, 접근할 수 없다.
- 예)
- 프로세스 A의 페이지 테이블에는 A의 물리 주소만 매핑 → B에는 접근 불가.
- MMU 가 논리 → 물리 주소로 변환하는데, 이 때 접근 가능한 메모리를 제한할 뿐만 아니라, 다른 페이지에 접근하면 페이지 폴트(Page Fault)가 일어난다.
- 운영체제만 테이블 접근 가능하니 보호 가능 ^^~!
프레임 테이블
운영체제가 물리 메모리를 관리하기 위해 사용하는 자료구조.
- 어느 프레임에 메모리가 할당되어 있고
- 어느 프레임이 사용 가능하며
- 총 프레임은 몇 개나 되는지 등을 저장한다.
운영체제는
프로그램 카운터와 레지스터의 사본을 유지하는 것처럼 각 프로세스의 페이지 테이블 사본을 유지한다.
- 이 사본을 논리 주소를 물리 주소로 변환하는 때에 사용한다.
- 프로세스가 할당될 때 CPU 디스패처(컨텍스트 스위칭 하는)가 테이블을 설정하는 데 사용한다.
- 그래서 페이징은 컨텍스트 스위칭 시간을 늘리긴 함.
하드웨어 지원
- 페이지 테이블의 포인터는 PCB에 저장된다.
- CPU 스케쥴러가 컨텍스트 스위칭을 하고 사용자 레지스터를 복구할 때, 새로 실행할 프로세스가 사용할 메모리 매핑 정보를 다시 적재한다.(복구한다.)
- 각 프로세스는 가상 메모리(논리 주소)를 사용하는데, 이 가상 메모리가 물리 메모리로 어떻게 매핑되는지는 “페이지 테이블”에 저장돼 있음.
- CPU는 저장된 사용자 페이지 테이블 정보를 참조해 새 프로세스의 레지스터와 메모리 매핑을 복구하는 거야.
- 페이지 테이블은 메인 메모리에 저장한다.
- 페이지 테이블 기준 레지스터 PTBR 가 페이지 테이블을 가리킨다.
- PTBR = (실행 중인 프로세스의 테이블 주소를 저장하는 레지스터.)
TLB
매번 페이지 테이블을 사용하기 위해 메인 메모리에 접근하면 너무 느리니까(페이지테이블 항목 찾고, 원하는 항목에 엑세스하는 두 번의 메모리 접근) 빠르게 접근하기 위한 특수한 소형 하드웨어 캐시.
- key : 가상 주소(페이지 번호) , value : 물리 주소(프레임)
TLB hit
- CPU 가 논리 주소를 생성하면
- MMU 가 해당 페이지 번호가 TLB 에 있는지 확인한다.
- key(가상주소, 페이지 번호)를 찾으면? → TLB hit
- 그에 맞는 프레임 번호를 알고(물리 주소로 변환) 메모리에 접근한다.
- key(가상 주소, 페이지번호)를 찾지 못하면? → TLB miss
- 페이지 테이블에 대한 메모리 참조를 해야 한다.
- 페이지 테이블 항목 찾고 → 원하는 항목(프레임)에 두 번 접근.
TLB 가 가득 차면?
기존 항목 중에서 교체될 항목을 선택한다.
- LRU(가장 오래된 페이지 교체), 라운드 로빈, 무작위 등 다양한 정책 사용.
- 그래도 주요 커널 코드는 TLB 에 고정 시킨다^^ 빠르게 접근해야되니깐.
ASIDs (address-spare identifiers)
TLB 항목이 어느 프로세스에 속한 것인지 알려주고 그 프로세스의 정보를 알려준다.
- ASID 를 이용하면 한 TLB 에 여러 프로세스의 정보를 한꺼번에 보관한다.
예시
- TLB에서 가상 주소를 변환할 때, 현재 수행중인 프로세스의 ASID 가 TLB 항목에 있는 ASID 와 같은지 검사.
- ASID 가 맞지 않으면 → TLB miss
만약 ASID 가 없다면?
- 컨텍스트 스위칭 시, 다음 프로세스가 가상 주소에 물리 주소를 잘못 변환하지 않도록 TLB 를 전부 flush 해야 함.
- 아주 비효율적이겠죠?
캐시 적중률, 미스율 Hit ratio, miss ratio
캐시 적중률 : 접근하려는 메모리의 페이지 번호가 TLB 에서 발견되는 비율.
캐시 미스율 : 접근하려는 메모리의 페이지 번호가 TLB 에서 발견되지 않아 메모리까지 들러야하는 비율
- 캐시 적중/미스율은 성능과 지대한 연관이 있다.
- 페이징 오버헤드를 계산하기 위한 완벽한 성능 분석을 위해서는 TLB 단계에서 **미스율 정보**가 필요하다.
- 하드웨어 구성요소(TLB 같은)가 메모리 성능에 지대한 영향을 줄 수 있다.
- (페이징과 같은) 운영체제의 발전이 (TLB 같은)새로운 하드웨어 구성 요소를 만들어내고, 그 구성 요소에 영향을 받는다.
보호
PTLR
페이지 테이블의 접근 가능한 페이지 수(범위)를 지정하는 레지스터
- 페이지 테이블이 몇 개의 엔트리를 포함하는가? (접근 가능 범위가 어디에서 어디까진가?)
- 예) PTLR이 10이면 → 프로세스는 0~9 까지만 접근 가능하고, 페이지 10 이상 접근 시 트랩 발생.
→ 프로세스가 존재하지 않는 페이지 번호를 요청하는 것을 막는 1차 방어선.
유효/무효(valid, invalid) 비트
해당 페이지가 프로세스가 접근 가능한 주소 공간 내에 있는가?
- 비트가 유효 : 관련 페이지가 실행되고 있는 프로세스가 접근 가능한 페이지이다.
- 비트가 무효 : 페이지가 프로세스의 논리 주소 공간에 없다. 즉, 접근 권한이 없다.
- 예1) 어떤 페이지는 아직 메모리에 로드되지 않았을 수도..(스왑 아웃 상태)
- 예2) 접근하면 안 되는 커널 영역의 코드일 수도..
→ 접근한 해당 페이지가 유효한 페이지인지 아닌지 검사. (2차 방어)
보호 비트
페이징 환경에서 메모리 보호는 각 페이지에 붙어있는 **보호 비트**를 통해 구현된다.
- 각 비트는 페이지가 읽기/쓰기/읽기 전용인지 각각 정의한다.
- 읽기 전용에 쓰기를 시도하면 trap
→ 접근한 페이지의 권한을 검사하여 불법 접근 방지.
💡 PTLR 로 1차 검사 → 프로세스가 유효한 범위의 페이지 번호를 요청했는가? 유효/무효 비트로 2차 검사 → 요청한 페이지가 접근 가능한 상태인가? 보호 비트로 3차 검사 → 읽기/쓰기/읽기 전용 권한을 확인하여 불법 접근 방지.
공유 페이지
페이징의 장점은 공통 코드를 공유할 수 있다는 것인데!~ 재진입 코드만 공유 가능하다.
재진입 코드
읽기 전용(read-only) 코드로 실행 중에 절대 변경되지 않으며 코드 영역만 공유하고 데이터 영역은 따로 관리된다.
- 두 개 이상의 프로세스가 동일한 코드를 동시에 실행할 수 있다.
- 예를 들어 커널 코드
- 그렇지만 사용자 프로그램 코드도 공유 가능하다(읽기 전용)
- 공유 페이지로 공유된다고 생각하면 된다.
- 공유 코드는 읽기 전용 코드로, 운영체제가 이 속성을 강제해야 한다.
- 예) C 표준 라이브러리는 물리 메모리에 하나의 사본만 저장하고 각 사용자 프로세스의 페이지 테이블은 동일한 물리적 사본으로 매핑시킨다.
페이지 테이블 구조
너무어려워용….ㅠ.ㅠ
-> 근데 실무에서 직접적으로 사용하는 건 아니어서 그냥 이런 게 있는지만 알아두기~
계층적 페이징
주소 변환을 효율적으로 관리하기 위해 여러 단계로 페이지 테이블을 나누는 구조. 큰 가상 주소 공간을 작은 페이지로 나눠 관리할 수 있도록 도와준다.
- 쉽게 얘기하면 너무 큰(길다고 해도 좋다.) 페이지 테이블 주소를 한 페이지에 담을 수 없어, 계층을 만들어 나눠서 저장한다.
- 마지막 오프셋에는 프레임 정보를 저장한다.
- 64비트의 주소 공간은 너무 크다. 기존 32비트처럼 단일 페이지로 만들면 비효율적
- 4단계의 계층적 페이징을 사용해 페이지 테이블을 여러 단계로 나누고 필요한 테이블만 메모리에 유지하는 방식.
4단계 페이징 방법
64비트 가상 주소를 4단계로 나눠 변환하는데..
- 가상 주소(64비트) = 4단계 테이블 + 오프셋(페이지 내의 위치)
- 각 테이블이 9비트씩 차지하면 9 * 4 = 36비트 로 주소 변환 수정.
- 오프셋(12비트)는 그대로 유지한다. 최종 물리 주소를 찾을 때 필요하니까.
동적으로 페이지 테이블 크기 조정
모든 페이지 테이블을 한 번에 생성하는 게 아니라, 필요할 때만 생성! 한꺼번에 생성하면 메모리 낭비가 심하자나.. → **메모리 절약**하자!
- 프로세스가 처음 시작할 때
- PML4(가장주소 맨 첫번째 테이블)만 생성하고 나머지는 생성하지 않음.
- 가상 주소를 처음 접근했을 때
- PML4 를 접근했는데 PDPT 가 없으면 새로 생성
- PDPT 에서 PD 없으면 새로 생성…뒤에도 등등.
- 마지막 단계에서 페이지 테이블을 찾으면
- 물리 메모리에 해당 페이지가 없으면 페이지 폴트
- 운영체제가 해당 페이지를 로드하고 페이지 테이블 업데이트
💡Linux나 ARM64 기반은 4~5단계 페이지 테이블을 사용할 수 있고,. 나머지는 전부 4단계 테이블을 사용한다!
해시 페이지 테이블
구조
- 가상 주소 공간으로부터 페이지 번호가 오면 그걸 해싱.
- 해시 페이지 테이블에서 연결 리스트를 따라가며 첫 번째 원소와 페이지 번호를 비교해봄.
- 일치되면 대응하는 프레임 번호를 가져와 물리 주소 얻음.
- 일치하지 않으면 그 다음 원소로 똑같은 행위 반복.
장점
- 가상 주소 공간이 매우 큰 환경에서 사용 가능
- 일반적인 계층적 페이징보다 가상 주소 매핑이 유연.
- 특정한 메모리 할당 패턴 OS 에는 유리할 수도.. (예: 대규모 서버 환경)
- 64비트에서 해시 페이지 테이블을 변형하여 클러스터 페이지 테이블을 만들었는데
- 메모리가 드문드문하게 비어있는 희소 주소 공간에 유용하게 사용한다.
단점
- 페이지 조회에 시간이 더 걸림
- 해시 테이블 충돌 방식이 발생하면 연결 리스트 방식으로 탐색해야 해서 성능 저하
- 이미 계층적 페이징이 충분히 크고 빠른데 굳이..?
- 하드웨어에서 직접 지원하는 구조가 아니어서 SW 적으로 구현해야하는데..흠..
역페이지 테이블
구조
- 메모리 프레임마다 한 항목씩 할당.
- 프레임에 올라와있는 페이지 주소
- 페이지를 소유한 프로세스 ID
- 이러면 페이지 테이블에는 단 하나의 페이지 테이블만 존재함.
장점
- 기존 페이지 테이블의 크기 문제를 해결하기 위해 등장.
- 테이블 항목 개수가 수백 수만 개가 될 수 있고, 그러면 물리 메모리 사용을 추적하기 위해 많은 물리 메모리를 소비해야 해서 생긴 구조.
- 물리 메모리를 중심으로 테이블을 구성해서 테이블 크기 줄일 수 있음.
단점
- 페이지 변환 속도가 느림.
- 해시 탐색하니까 계층적 페이징보다 느릴 수 밖에 ㅠㅠ
- TLB 와 맞지 않음. TLB 히트율 떨어뜨림.
→ 특수한 임베디드 시스템이나 메모리 제약이 없는 환경에서 일부 사용.
스와핑
- 프로세스 또는 프로세스의 일부분을 실행 중에 임시로 백업저장장치(디스크 스토리지)로 내보내졌다가 실행할 땐 다시 메모리로 되돌리는 것
- 프로세스의 물리 주소 공간이 시스템의 실제 물리 메모리 크기보다 큰 경우에도 프로세스를 동시에 실행하기 위해 사용.
기본 스와핑
메인 메모리 ↔ 백업 저장 장치(디스크 스토리지) 간에 전체 프로세스를 이동
- 다중 스레드 프로세스는 모든 스레드의 데이터 구조도 스왑되어야 함.
- OS 가 스왑 아웃된 프로세스에 대한 메타 데이터를 유지해야 다시 스왑인 될 때 복원 가능.
- 장점 : 실제 물리 메모리보다 더 많은 프로세스를 사용 가능하다!!!
페이징에서 스와핑
프로세스 전체가 아닌 프로세스 페이지를 스왑할 수 있는 변형 스와핑 사용
- 물리 메모리를 초과 할당할 수 있지만 프로세스 전체를 스왑하는 게 아니라, **페이징에서 스와핑**을 하는 것.
- 페이지 아웃: 페이지를 메모리 → 백업스토리지로 스왑 아웃
- 페이지 인: 페이지를 메모리 ← 스토리지로 스왑 인
모바일 시스템에서의 스와핑
모바일은 사실 어떤 형태의 스와핑도 지원하지 않음.
- 왜냐! 플래시 메모리를 사용하니까
- 저장 공간이 작음.
- 허용되는 쓰기 횟수가 정해져있음.
- 이런 장치는 메모리와 플래시 메모리의 처리량이 저조함..
- 대신 iOS 같은 경우, 앱에 할당된 메모리를 자발적으로 반환하도록 요청함.
- 필요하다면 프로세스를 종료 시킴
💡 스와핑이 필요하다는 것 → 사용 가능한 물리 메모리보다 활성 프로세스가 더 많다는 것. 스와핑을 하고 싶지 않으면(?) 일부 프로세스를 종료하거나 더 많은 물리 메모리를 장착하는 방법이 있다.
32 비트와 64비트 구조
IA-32 구조 (32bit)
메모리 관리
- 세그먼테이션
- CPU가 생성한 논리 주소를 전달받음.
- 그 후, 논리 주소에 상응하는 선형 주소(논리-물리에서 중간 단계 주소)를 생성함.
- 페이징
- 그 선형 주소를 메인 메모리의 물리 주소로 변환.
IA-32 세그먼테이션
세그먼트 라는 말 자체가 메모리의 논리적인 단위임. 그러니까 메모리를 여러 파티션으로 나눠서 사용하는 구조인 것.
- 각 세그먼트는 크기가 다를 수 있고, 코드, 데이터, 스택을 분리해서 사용.
- CPU가 생성한 논리 주소로 세그먼트의 시작 주소와 오프셋을 이용해 선형 주소를 계산한다.
구역
- 첫 번째 파티션 : 프로세스가 독점적으로 사용하는 8KB 세그먼트
- 지역 디스크립터 테이블(LDT) 에 저장.
- 두 번째 파티션 : 프로세스 사이에서 공유 가능한 8KB 세그먼트
- 전역 디스크립터 테이블(GDT) 에 저장.
→ 각 항목은 8byte 로, 세그먼트의 기준 위치와 길이를 포함하는 세그먼트의 자세한 정보를 유지함.
메모리 구조
한 프로세스는 6개의 세그먼트를 가리킬 수 있다.
- 코드 CS : 실행할 명령어
- 데이터 DS, ES, FS, GS : 전역 변수나 정적 데이터
- 스택 SS : 함수 호출 스택 및 지역 변수
셀렉터
- s : 세그먼트 번호 13비트
- g 세그먼트가 GDT? LDT? : 1비트
- p 사용자코드? 커널 코드? : 2비트
방법
- 셀렉터를 이용해 → 세그먼트 디스크립터 찾기
- 세그먼트 디스크립터로 → 세그먼트의 시작 주소 확인
- 시작 주소 + 오프셋 = 선형주소
💡 사실 이젠 64비트가 기본이라 잘 쓰이진 않지만,, 메모리 구조 (코드, 데이터, 스택) 정도는 남아있다고 한다…
IA-32 페이징
페이지 디렉터리 (최상위 페이지)
- 일반적으로 4KB 씩 나눔.
- 그런데 Page size 플래그가 true → 프레임이 일반적으로 사용하는 4KB 가 아니라 4MB
- 이러면 직접적으로 페이지 프레임을 가리키는 것임.
- invalid 비트 : 페이지가 디스크에 있냐? 없냐?
- invalid 외의 나머지 비트(31)를 스토리지 → 메모리로 가져오기.
페이지 주소 확장 PAE
32비트 처리기가 4GB 보다 큰 물리 주소 공간에 접근할 수 있게 함.
- 3단계로 나눔
- 페이지 디렉터리 포인터 테이블
- 페이지 디렉터리
- 페이지 테이블
- 페이지(오프셋)
- 페이지 테이블 항목의 길이를 32 → 64 비트로 증가.
- 주소 공간을 확장해 64GB 물리 메모리 접근 가능.
- 그치만 윈도우는 PAE 기능 활성화여도 4GB 물리 메모리만 접근 가능 ㅠㅠ
x86-64 (64bit)
IA-32 명령어 집합의 확장을 기반 → 훨씬 큰 논리 및 물리 주소 공간 지원, 구조적으로 많은 개선
- AMD 가 이 구조를 채택 ㄷㄷ 와우
- 2^64 바이트 메모리에 접근 가능
- 현실적으로 64비트보다 훨씬 적은 비트만 사용하긴 함~
- 4단계 페이지 테이블 사용
- PAE 를 사용하여 48-52비트 물리 주소 공간 사용
ARM
예전엔 Acorn 이 만들었는데 ARM Limited 회사에서 설계만 하고 칩을 만들 수 있는 라이센스를 발급해줘서 허가만 해줌 ㅋㅋ
- 4KB, 16KB, 64KB 변환 단위 크기가 있다. → 상자 크기라고 생각하자.
- 작을 수록 세밀한 관리가 가능하고
- 클 수록 대규모 연속 메모리 블록에 유리하다.
- region 이라는 더 큰 연속 메모리 영역도 있다. → 여러 크기의 페이지들을 섞어서 할당.
- 작은 데이터는 4KB
- 큰 데이터구역은 region 으로 묶어 최적화 !
- 두 가지의 TLB 도 지원함
💡 ARM 과 64비트의 차이
64비트 : 페이지 크기가 무조건 고정
2/4/16KB ARMv8 : 페이지 크기를 같은 메모리 블럭(region) 안에서도 자유롭게 선택 가능.
요약
- 메모리는 각각 고유한 주소를 가진 큰 바이트 배열.
- 주소 공간을 할당하는 방법
- 기준 레지스터 : 가장 작은 유효한 물리 메모리 주소
- 상한 레지스터 : 메모리 범위의 크기
- 예) 기준4 - 상한100 → 메모리 주소 4~104
- 심볼릭 주소 참조를 실제 주소에 바인딩 하는 건 컴파일, 적재, 실행 시간에 바인딩 가능하다.
- 심볼릭 주소 : int x 라는 것을 실제 물리 주소(메모리)에 언제 반영하는가?
- CPU 가 생성한 주소 : 논리 주소
- 메모리 관리 장치(MMU) : 논리 주소를 물리 주소로 변경
- 메모리를 할당하는 방법 : 다양한 크기의 연속 메모리 파티션
- 최초 적합
- 최적 적합
- 최악 적합
- 최초, 최적만 상황에 따라 씀
- 페이징의 논리 주소 : 페이지 번호, 페이지 오프셋
- 페이지 번호 : 페이지 테이블 인덱스 번호 (책장 번호)
- 오프셋 : 참조되는 프레임의 특정 위치 (책)
- TLB : 하드웨어 캐시
- 각 항목에 페이지 번호와 상응하는 프레임 저장
- 페이징에서 주소 변환에 TLB 를 사용하려면?
- 페이지 번호를 가져와서 해당 페이지의 프레임이 TLB 에 있는지 확인
- 있다면 : 프레임이 TLB 로부터 얻어짐
- 없다면 : 페이지 테이블(메모리)에서 찾아야 함.
- 페이지 번호를 가져와서 해당 페이지의 프레임이 TLB 에 있는지 확인
- 계층적 페이징은 논리 주소가 너무 길어서 계층으로 나누고 오프셋에는 실제 프레임을 넣는다.
- 스와핑을 통해 프로세스에 속하는 페이지를 디스크로 이동시켜 멀티 프로그래밍을 더 알차게 할 수 있음.
- 32비트는 4KB, 4MB 페이지 크기 → PAE 로 4GB 보다 큰 물리 주소 공간에도 엑세스 가능
- 64비트, ARM 은 계층적 페이징을 사용하는 64비트 아키텍처
- 64비트 : 2^64 로 48-52bit 사용
- ARM : 각각 다른 페이지 크기 사용 가능하고, region 안에서 묶기 가능.
'개발공부 개발새발 > OS' 카테고리의 다른 글
OS ) 파일 시스템 File System (0) | 2025.04.08 |
---|---|
OS ) 메인 메모리 - 1편 (0) | 2025.02.14 |
OS ) 교착 상태 DeadLocks (0) | 2025.01.23 |
OS ) 동기화 도구 -> 락 (Mutex, 세마포) (0) | 2025.01.21 |
OS ) 스레드 Thread (0) | 2025.01.15 |