개발자 끄적끄적

비연속 메모리 할당 본문

운영체제

비연속 메모리 할당

햏치 2024. 5. 17. 17:31

<페이징(Paging)> 
- 한 프로세스의 논리 주소 공간을 동떨어진 공간들에 배정할 수 있도록 지원
  - 연속 할당에서처럼 연속적인 메모리 공간을 찾거나 만들 필요 없음
  - 외부 단편화 문제를 해결할 수 있는 메모리 관리 기술

- 동적 할당의 한 형태
  - 모든 논리 주소는 페이징 하드웨어에 의해 물리 주소로 매핑
 
- 대부분의 컴퓨터 시스템에서 채택





<Frame vs. Page>
- (Page) Frame
  - 물리 메모리를 고정된 크기의 블록으로 분할

- Page
  - 논리 주소 공간을 하나의 frame과 같은 크기의 블록으로 분할







<기본 방법>
- OS는 모든 free frame들을 관리
  - Frame table : 각 frame의 할당 정보 기록

- n page 크기의 프로그램 실행 위해서는 n개의 free frame을 차고, 그 곳에 적재

- 논리 주소를 물리 주소로 변환하기 위해 page table에 관련 정보 기록
  - Page table
    - 메모리에 각 page가 점유하는 주소를 가짐
    - 자연히 사용자 프로세스는 자신에게 할당되지 않는 메모리에 접근 불가






<페이징의 특징>
- 용이한 구현  
  - 고정 크기로 분할하기 때문

- 높은 이식성
  - 페이징을 위해 CPU에 의존하는 것 없음

- 높은 융통성
  - 시스템에 따라 page 크기를 다르게 설정 가능

- 메모리 활용과 시간 오버헤드면에서 우수
  - 외부 단편화는 발생하지 않음
  - 내부 단편화는 발생하지만 매우 작음
  - 홀 선택 알고리즘 실행 필요 없음
 
 
 
<페이징의 예>









<페이지 크기(Page Size)>
- 크기는 2의 제곱으로 증가
  - 보통 4Kbyte(OS에 따라 8KB, 16KB 등)

- 내부 단편화가 생길 수 있음
  - 메모리는 항상 frame의 정수배로 할당되기에
  - 평균적으로 프로세스 당 반(1/2) page 정도 발생

- 내부 단편화 감소 위해선 page size를 줄여야 한다
  - -> page table의 크기가 커져 공간 낭비

- 디스크 입장에선 page size가 클수록 효율적






<교재에서의 내부 단편화>
- 이 단원에서는 할당외었으나 이 단원에서는 필요 없고 
  다음 단원을 할당 할 수 없는 영역






<32비트 CPU를 가진 컴퓨터에서 페이징 사례>
- 조건
  - 4GB의 주소 공간을 갖는 프로세스
  - page의 크기 4KB

- 사용자 프로세스 현황
  - 총 6개 page 사용 중(프로세스 크기 = 6 x 4KB = 24KB)
    - 코드 : page 0 ~ page 2에 걸쳐 있음
    - 데이터 : page 2 ~ page 3에 걸쳐 있음
    - 힙 : page3 ~ page 4에 걸쳐 있음
    - 스택 : 사용자 공간의 맨 마지막 한 page에 할당
  - page table에서 6개 항목만 사용 중 
    - 기본적으로 주소 공간의 모든 page를 나타낼 수 있다








<프로세스가 동적 할당을 받는 예>
- char* p = (char*)malloc(200);
  - 200 바이트만 필요하더라도 1 page(4KB) 할당
  - 힙 영역의 page 5를 할당
    - page 5의 논리주소 : 5 x 4KB = 20KB = 20 x 1024 = 20480
    - malloc()은 page 5의 논리주소 20480을 반환

- *p = 'a';
  - 논리주소 20480번지에 'a'를 저장하라는 코드
  - page 5는 frame 2에 할당된다 가정
    - frame 2의 물리주소 : 2 x 4KB = 8KB = 8 x 1024 = 8192
    - MMU에 의해 논리주소 20480은 물리주소 8192로 매핑
    - 물리 메모리 8192번지에 'a' 저장







<프로세스가 시스템 호출을 하는 예>
- 커널 공간의 page k에 담긴 커널 코드를 실행한다 가정
  - 프로세스 내에서 커널 코드 역시 논리 주소로 식별
  - 시스템 호출을 통해 커널 코드가 실행될 때 현재 프로세스의 page table을 이용해 물리 주소로 변환됨
      - 현재 프로세스의 page table에서 page k의 frame번호 780090을 알아내고
      - frame 780090에 적재된 커널 코드를 실행

 



<페이지와 페이지 테이블에 대한 정리(1/3)>
- page의 크기가 4KB인 32비트 CPU 가정
  - 프로세스 주소 공간의 크기는?
    - 1바이트(=8bit)씩 할당된 2^32개의 주소들이므로 총 4GB

  - 물리 메모리의 최대 크기는?
    - 물리 주소의 범위는 : 0 ~ (2^32)-1 //4GB의 미만
    - 한 주소당 한 바이트 크기를 가지므로 최대 2^32바이트 = 4GB //실제 장착가능한 물리적인 메모리는 최대 4GBd이다

  - 설치된 물리 메모리 크키에 비례해 프로세스의 주소 공간의 크기가 변하는가? 프로세스 주소 공간은 논리 공간(가상 공간)으로 항상 4GB


<페이지와 페이지 테이블에 대한 정리(2/3)>
- 한 프로세스는 최대 몇 개의 page로 구성되나?
  - 4GB / 4KB = (2^32)/(2^12) = 2^20 = 1M개 = 약 100만개

- 각 프로세스의 page table 크기는?
  - page table의 각 항목의 크기 = 32비트 = 4바이트
    - 각 항목에서는 매핑되는 frame 번호를 저장해야 하므로
  - 4바이트 x 2^20 = 2^22 = 4MB

- 그림 9-2에서 프로세스가 사용자 공간에서 사용하고 있는 크기는? 
  - 6개


<페이지와 페이지 테이블에 대한 정리(3/3)>
- page table의 모양은? 
  - 대부분 비어 있는 희소 테이블(sparse table) <- page는 약 100만개 중 6개만 쓰이고 있기 때문
  - 낭비가 심하므로 줄이는 기법 필요

- page table은 어디에 존재하나?
  - PTBR(Page Table Based Register)이 가리키는 메인 메모리에 저장

- 커널 코드도 논리 주소로 되어 있는가?
  - 예 //모든 코드주소는 논리 주소로 되어있다
  - CPU가 커널 코드 실행 시 물리 주소로 변환 필요
    - 현재 프로세스의 page table 사용







<페이징 개념 확인(1/3)>
- 32비트 CPU, page 크기의 2KB, 물리 메모리 1GB, 프로세스 A는 사용자 공간에서 54321바이트를 차지한다 가정할 때
  - 물리 메모리의 frame 크기는?
    - frame의 크기는 page의 크기와 동일하므로 2KB

  - frame의 개수는?
    - frame은 전체 메모리를 일정한 크기로 나누어주는 것이므로 
      메모리 전체 크기 / 한 frame크기 = 1GB / 2KB = 2^30/2^11 = 2^19개


<페이징 개념 확인(1/3)>
- 프로세스 A가 사용중인 page의 개수는?
  - 54321 / 2KB = 약 26.5 = 27개 page
  - *page는 반드시 한 페이지 단위로 할당되어져야 하기 때문에 27개이다

- 프로세스 A를 적재하기 위한 물리 frame의 개수는?
  - 27개의 page를 사용 중이므로 27개의 frame 할당 필요

- page table 항목의 크기가 4바이트 일 때, 프로세스 A의 page table의 크기는?
  - 현재 프로세스에서 사용하고 있는 페이지 갯수와 상관없이 한 프로세스의 페이지 테이블은 현재 프로세스가 가지고 있는 모든 페이지에 대한 프레임들에 대해 매핑할 수 있어야 하므로
    2^32 / 2K = 2^32 / 2^11 = 2^21개
  - page table의 크기 = 2^21 x 4바이트 = 2^23바이트 = 8MB


<페이징 개념 확인(3/3)>
- 페이징에서 단편화 메모리의 평균 크기는?
  - 페이징에서 외부 단편화는 일어나지 않고 내부 단편화만 일어난다
  또한 페이징에서 마지막 부분만 내부 단편화가 이루어진다
  즉, 코드 영역과 데이터 영역은 연속되어 있고, 마지막 page에만 내부 단편화가 발생 -> 평균 크기는 한 page의 절반이므로 2K / 2 = 1KB

- page 크기와 단편화 관계는?
  - page의 크기가 크면 내부 단편화도 커질 수 잇다
    - 상대적으로 영향은 미미함

- page 크기와 page table의 크기의 관계는?
  - page 크기가 크면 page table 크기가 줄어든다

- page 크기의 추세는?
   - 디스크 I/O 속도를 높이기 위해 커지는 추세






<Address Translation Scheme(주소변환 기법)>
- CPU에 생성된 논리 주소는 다음과 같이 나뉘어 MMU(Page table)에 의해 해석된다
  - Page number : p
    - Page table 접근 시 인덱스(index, ex.쪽번호)로 사용
    - 각 page의 physical memory상의 base address(frame number)를 내용으로 가진다
    - Page offest : d 
      - 특정 page 내에서의 offset(그 페이지의 시작부터 어느부분까지 떨어져있는지, ex.줄번호)으로 사용
      -  base address와 연결되어 physical memory address를 나타낸다






<MMU의 논리 주소 해석>
- 논리 주소 공간의 크기 : 2^m
- 한 페이지의 크기 : 2^n

- 예
  - 32비트 논리 주소 체계 : 2^32
  - page 크기가 4KB일 때 : 12^12










<페이징의 구현>
- 하드웨어 지원
  - CPU는 PTBR(Page Table Base Register)제공
    - 이 레지스터는 OS에 의해 제어된다

-  MMU 장치
  - page table을 참조하여 논리 주소의 물리 주소 변환
  - page table을 저장/검색하는 캐시 포함
  - 메모리 보호
    - page 보호가 page table에 있는 지 확인
    - offset이 page 범위를 넘어갔는지 확인

- OS는 page table 관리 기능 제공
  - 물리 메모리에 할당된 page table과 빈 frame 리스트 생성 관리 유지
  - 프로세스 생성/소멸에 따라 동적으로 frame 할당 및 반환 처리
    - page table 갱신
  - 컨텍스트 스위칭 시 PTBR 로딩








<페이지 테이블 사용시 문제점>
- 한 번의 메모리 조작을 위해 두 번의 메모리 접근 발생
  - 각 page table은 수 MB 크기로 메모리 저장됨
  - CPU가 메모리 접근시마다 2번의 메모리 접근 필요
    - 실행 속도 저하
  - -> TLB 사용으로 해결
 
- page table의 낭비
  - 프로세스의 실제 크기는 매우 작아 대부분의 page table 항목이 비어있다
    - 프로세스의 최대 크기 기준으로 page table을 형성했기에
    - -> 2-레벨 page table 등의 방법 제안








<Page table 속도 저하 문제 해결 방법>
- Translation Look-aside Buffers : TLBs 
  - 특수한 고속의 하드웨어 캐쉬를 이용해 메모리 접근 문제를 해결
  
  - 주소 변환 개시로 불림
    - 최근에 접근한 page 번호와 frame 번호 쌍을 항목으로 저장
    - 현대 컴퓨터에서는 MMU 내에 존재

  - 연관메모리(Associative memory)
    - key + value
    - 병렬 검색으로 빠른 검색 가능하지만 비용이 많이 드는 하드웨어








<연관 메모리(Associativie Memory)>
- 동시에 여러 key(page number)와 비교
  - page 번호 발견 시(TLB hit) 
    - 그에 대응하는 frame 번호 알려줌
  - page 번호 미발견시(TLB miss)
    - 메모리에 있는 page table에서 찾아 TLB에 추가
    - 교체 작업 필요









<TLB와 참조의 지역성>
- TLB는 참조의 지역성으로 인해 효과적인 전략임
- TLB 사용 시 순차 접근 시 실행 속도 빠름
- TLB 사용 시 임의 접근이나 반복이 없는 경우엔 느림
  - TLB miss로 TLB 항목 잦은 교체 발생








<TLB 성능>
- TLB 히트율을 높이기 위해선 TLB 항목수 늘리기 
  - 비용과 상충

- page가 클수록
  - TLB 히트 증가 -> 실행 성능 향상
  - 내부 단편화 증가 -> 메모리 낭비

- TLB 도달 범위(TLB reach)
  - TLB의 모든 항목에 채워졌을 때 miss 없이 접근할 수 있는 메모리 접근 범위
  - TLB 항목수 x page 크기
 
 
 
 
<TLB가 있는 경우의 실행 과정>

 
 
 
<TLB를 가진 경우에 메모리 액세스 과정>









<TLB를 고려한 컨텍스트 전환 과정>
1. CPU의 모든 레지스터를 PCB에 저장

2. 새로 스케줄된 프로세스의 PCB에 저장된 page table의 주소를 CPU의 PTBR에 적재

3. TLB 캐시의 모든 항목을 지움 
  - 이전 프로세스 잔재이므로

4. 새 프로세스의 PCB에 저장된 레지스터 값들을 CPU에 적재 후 실행 재개
  - 이후 TLB miss가 발생하며 TLB 항목이 채워져 감

 
 
 
<2개의 페이지에 걸쳐있는 배열>







<페이지 테이블의 메모리 낭비>
- 32비트 CPU에서 프로세스당 page table 크기 
  - 프로세스의 주소 공간 : 4GB(프로세스의 논리주소공간)/4KB(각 페이지의 크기) = 2^32/3^12 = 2^20 = 1M개의 page로 구성
  - 프로세스당 page table의 크기
    - 한 항목이 4바이트이면 2^20개 x 4바이트 = 4MB
 
- 10MB 메모리를 사용하는 프로세스 가정 시
  - 실제 활용되는 page table 항목 수
    - 10MB / 4KB = 10 x 2^20 / 2^12 = 10 x 2^8 = 2560개
  
  - 실제 활용되는 page table 비율
    - 10 x 2^8 / 2^20 = 10/2^12 = 약 0.0024
      - 매우 낮음






<페이지 테이블 낭비 문제의 해결책>
- 역 페이지 테이블
- 멀티 레벨 페이지 테이블










<역 페이지 테이블(Inverted Page Table, IPT)>
- Page table을 물리 주소 공간에 대응시켜 구성
  - 일반적으로는 프로세스마다 논리 주소 공간에 대응

- 각 항목은 메모리의 frame에 대응
  - 시스템 전체에 단 하나의 page table만 존재
    - 역 페이지 테이블 항목의 수 = frame의 수 

- 구성 
  - 역 페이지 테이블의 인덱스 = frame 번호
  - 역 페이지 테이블 항목 = [pid, p]
  - 논리 주소 형식 = [pid, p, offset]
 
 
 
<역페이지 테이블의 예>

 
 
 
<역페이지 테이블을 이용한 매핑>









<역 페이지 테이블의 크기>
- 역 페이지 테이블의 항목 크기
  - 프로세스 번호(pid)와 page 번호(p)로 구성
    - pid와 p가 각각 4바이트라면 항목 크기는 8바이트
    - 역 페이지 테이블의 항목 수
      = 물리 메모리 크기 / 프레임 크기
        - 물리 메모리가 4GB, 프레임 크기 4KB이면
        - 역 페이지 테이블 항목 수 = 4GB/4KB = 2^20개 = 약 100만개
      - 역 페이지 테이블의 크기 = 2^20개 x 8바이트 = 8MB

- 10개의 프로세스가 실행 중일 때
  - 기존의 page table의 크기 = 10 x 4MB = 40MB
  - 역 페이지 테이블의 크기 = 8MB
    - 시스템에 1개만 존재








<역 페이지 테이블의 특징>
- Page table 크기를 획기적으로 줄일 수 있음

- 특정 page frame을 탐색하기 위해 더 많은 시간 소요
  - Page table 전체를 검색해야 하기에

- 탐색시간을 줄이기 위해 hash table 사용
  - -> 3번의 메모리 조작 발생
      - hash table -> inverted page table -> 주기억장치
    - 연관 메모리(Associate memory)사용
      - 고가의 비용








<멀티 레벨 페이지 테이블(multi-level page table)>
- 논리주소 공간을 여러 단계의 page table로 나눔
  - 대용량의 page table을 주기억장치처럼 취급하여 다시 페이징 함
    - Page table 자체를 위한 paging 기법
    - 사용중인 page들에 대해서만 page table 구성
      - 기존 page table의 낭비를 줄임

- 간단한 예 : 
  - 2-레벨 페이징 기법(Two-level paging scheme)
    - Page table을 다시 페이징 함
 
 
 




<2-레벨 페이지 테이블>
- page table을 다시 페이징
  - 논리 주소의 page 번호 부분을 2개의 레벨로 나눔
    page number(20비트) | offset(12비트)
    page directory index(10비트) | page table index(10비트) | offset(12비트)

  - 논리 주소 구성
    - [페이지 디렉터리 인덱스, 페이지 테이블 인덱스, 옵셋(offset)]
    - page 크기 4KB 일 때
      - 논리 주소의 하위 12비트 : page 내 옵셋 주소
      - 논리 주소의 상위 20비트 : page 디렉터리 인덱스와 page 테이블 인덱스

 
 
 
<2-레벨 페이지의 사례>








<세그멘테이션(Segmentation)>
- 가변길이의 연관된 정보들의 집합
  - 각 segment들은 '이름'과 '길이'를 가짐
  - 외부 단편화 발생
    - 내부 단편화는 없음

- 사용자 관점에서의 메모리 관리 기법
  - 논리 주소 공간을 segment들의 집합으로 정의
    - 코드, 데이터, 스택, 힙 세그먼트
    - 프로세스를 segment로 나누는 과정은 컴파일러, 링커, 로더, OS에 의해 이루어진다
 
 
 
<세그멘테이션 주소 매핑>









<세그멘테이션의 구현(1/2)>
- 논리 주소 구성
  segment number(s) | segment offset(d)

- 하드웨어 지원
  - CPU STBR(Segment Table Base Register)
    - segment table에 대한 메모리상의 시작 주소
  - MMU
    - 논리 주소를 물리 주소로 매핑
    - 논리 주소가 segment 범위를 넘어서는지 판별
  - segment table 
    - 각 segment 별로 시작 주소와 길이 정보 유지


<세그멘테이션의 구현(2/2)>
- 운영체제의 지원
  - segment의 동적 할당/반환 및 segment table 관리 기능 구현
    - 프로세스 생성/소멸에 따라 동적으로 할당/반환
    - 물리 메모리에 할당된 segment table과 자유 공간에 대한 자료 유지
    - 컨텍스트 스위칭 때 CPU 레지스터에 적절한 값 적재

- 컴파일러, 링커, 로더의 지원
  - 프로그램을 세그먼트 기반으로 컴파일 링킹, 로딩








<예 : The Intel Pentium>
- 2가지 구조를 동시에 지원
  - Pure segmentation
  - Segmentation with paging
    - Segment를 paging 함

- ex) 'CPU' -> logical address -> 'Segmentation Unit' -> linear address -> 'Paging Unit' -> physical address -> 'Physical Memory(물리적 메모리)'

 
 
 
 
<논리 세그먼트와 물리 세그먼트 매핑>

'운영체제' 카테고리의 다른 글

가상메모리(1)  (0) 2024.05.22
메모리 관리  (0) 2024.05.10
식사하는 철학자 문제  (1) 2024.05.01