CS

운영체제 - 반효경 #8 Memory Management

unknownomad 2023. 5. 16. 00:43

# 8-1 Memory Management 1

Logical vs. Physical Address

메모리

  • 주소 통해 접근하는 매체
  • 주소가 매겨지는 것으로, 이 주소를 논리적 주소 / 물리적 주소 두 가지로 나눠볼 수 있음
논리적 주소
  • 가상 주소
  • 프로그램이 시작되면 0번째부터 주소 할당
물리적 주소
  • 메모리의 어디에 프로그램이 올라가느냐
  • 1개의 물리적 주소가 존재하고, 이 안에서 통으로 관리됨

주소 바인딩

  • 프로그램 실행 시 독자적 주소 공간이 생성됨
  • 프로그램마다 0번부터 시작되는 독자적 주소가 있는데,
  • 이게 실행되려면 물리적 메모리의 어딘가로 올라가야 하고,
  • 그러면 주소가 바뀌게 됨 = 주소 변환 = 주소 바인딩 = 주소 결정

Symbolic address

  • 메모리 주소를 가지고 프로그래밍하지는 않음
  • 메모리의 특정 위치에 변수값을 저장하지만, 메모리 몇 번째에 저장하는지와 같은 개념이 아닌, 그 이름의 '변수'에 얼마의 값을 저장하는 방식
  • 함수 호출 시에는 함수 자체가 아닌, 함수 이름을 다루는 방식
  • 즉, 숫자(값)를 직접 다루는 게 아니라 심볼을 다룸
  • ➡️ 심볼릭 주소가 컴파일되면 ➡️ 숫자로 된 독자적인 논리적 주소가 되고 ➡️ 실행되기 위해 물리적 메모리로 올라가면서 물리적 주소가 됨

Logical address

  • Symbolic address 가 컴파일된 것

Physical address

  • Logical address 가 실제 실행된 것

 

주소 바인딩

Compile time binding

  • 컴파일될 때

Load time binding

  • 실행이 시작될 때

Execution time binding

  • Run time binding
  • 프로그램 시작된 이후, 실행 도중에 바뀔 때

프로그램의 논리적 주소가 통째로 물리적 메모리에 올라갈 때를 가정한 그림

  • 물리적 메모리로 주소가 올라가야 프로그램이 실행됨

그림 실행 순서

  1. Symbolic address: A와 B를 더하고 C에서 점프
  2. Compile
  3. Logical address: 주소 20번지, 30번지의 내용을 더하고, 40번지에서 점프
  4. 실행 시작
  5. Physical address

 
물리적 주소가 결정되는 시점

  • Compile time binding
  • Load time binding
  • Run time binding

Compile time binding

  • 컴파일 타임에 주소가 미리 결정되기에 비효율적
  • 컴파일 시점에 이미 물리적 주소가 결정되기에, 미리 정해진 주소에만 올려야 함
  • 논리적 주소이지만 물리적 주소도 고정되며 바꿀 수 없기에, absolute code 라고도 부름
  • 논리적 주소 위치를 바꾸거나, 메모리에 올라갈 위치를 바꾸려면, 이미 정해진 물리적 주소는 변경 불가이기에 새로 컴파일해줘야 함
  • e.g. 현재 0번지부터 올라가는데, 100번지부터 올리고 싶으면 다시 컴파일하기

Load time binding

  • 프로그램이 시작돼서 메모리에 올라갈 때 물리적 메모리 주소가 결정됨
  • 컴파일 시점에선 논리적 주소까지만 결정됨
  • 컴파일해서 만들어지는 코드 = Relocatable code = 재배치 가능 코드
  • 항상 특정 위치에 올라가는 게 아니라, 비어있는 위치라면 실행 시 어느 곳이든 올라갈 수 있음
  • e.g. 500번지 전까지 비어있으니, 그 이후부터 채워넣자

Run time binding

  • 실행 시 주소가 결정되는 건 load time binding 과 똑같음
  • 근데 이 주소가 실행 도중 바뀔 수 있음
  • 얘만 주소가 바뀔 수 있기에, CPU 나 메모리를 사용할 때마다 binding 을 체크해봐야 함
  • e.g. 300번지부터의 주소가 700번지부터로 이동될 수 있음
  • 메모리로 쫓겨날 수도 있음
  • 지금 우리가 쓰는 시스템 방식
  • 주소변환을 그때그때 해줘야 하기에 하드웨어적 지원 필요
  • 주소 변환을 지원해주는 하드웨어 = MMU

 
CPU가 바라보는 주소는 뭘까?

  • CPU는 하드웨어라 physical address 바라볼 거 같지만, logical address 바라봄
  • 컴파일된 실행 파일들 = instruction
  • CPU가 각 번지 주소에 있는 인스트럭션을 실행하려면, 실행 파일 안에 있는 값을 CPU로 읽어들여 연산해야 함
  • 이 번지 주소 및 실행 파일 내의 값들은 전부 logical address 임
  • 그리고 physical address 로 올라간 instruction, 즉 소스 내의 값들 또한 logical address 임
  • 즉, 실행되어 physical address 로 올라간 실행 파일이라고는 하나, 실제 컴파일된 코드 자체에 들어간 주소값(인스트럭션 코드 안의 logical address)까지는 바꿀 수 없음(이게 바뀐다? 컴파일 다시 해야 함)
  • 메모리에 올라가는 시작 위치는 바뀌지만 그 코드 상의 주소들은 그대로 남아있음
  • e.g. 메모리의 20번지, 30번지 안의 내용을 CPU 안으로 읽어들일 때의 주소 = logical address
  • CPU가 매번 메모리 몇 번째에 있는 내용을 달라 요청하면 ➡️ 그때 주소 변환해서 물리적 주소 찾은 후 ➡️ 그 내용을 읽어 CPU에 전달
  • 그래서 CPU는 logical address 를 본다고 말함

 

Memory-Management Unit

Run time binding

  • 주소가 계속 바뀌기에 주소 변환용 하드웨어가 필요함 = MMU
  • (프로그램의 논리 주소가 통째로 물리 주소로 올라가는 것을 가정한 설명)

MMU

  • 2개의 레지스터를 통해 주소를 변환함

MMU scheme

  • 사용자 프로그램과 CPU는 logical address 만 다룸
  • 실제 physical address 는 볼 수도 없고, 알 필요도 없음

 

Dynamic Relocation

  • CPU 가 메모리 346 번째의 값을 달라고 하면
  • MMU 에서 가장 간단한 주소 변환은 2개의 레지스터로 이루어지는데,
  • Relocation register & limit register 통해 주소 변환이 이루어짐

현재 그림 상황

  • Virtual memory = logical memory
  • 0 번지부터 3000 번지의 주소 공간에서 0 번지부터 346 번지까지의 메모리를 요청한 상황(346이라는 논리적 주소 찾기)
  • 좌측 하단 점선 사각형 = CPU 에서 현재 실행 중인 프로그램
    • 그리고 이 프로그램이 physical memory 상에서는 14000번지부터 올라와 있는 상황

주소 변환 방법

  • 이 프로그램(프로세스)이 물리적 메모리에 올라간 시작 위치, 즉, 14000 번지 + 논리주소 346 번지 까지 읽은 후,
  • CPU에게 가져다주면 됨
  • 베이스 레지스터에 시작위치 14000번지 저장
  • 주소변환 시, 논리주소 + 시작위치

 
MMU 가 주소 변환 시 사용하는 레지스터 종류

  • Relocation register
  • Limit register

Relocation register

  • Base register
  • 프로그램의 시작 위치 저장
  • 주소 변환 시 논리주소 + 시작위치 = 346 + 14000 = 14346 이라는 물리적 주소를 얻게 됨

Limit register

  • 프로그램의 최대 크기가 있는데, p1 의 최대 크기는 3000 번지, 이 레지스터는 그 값을 담고 있음
  • 다른 프로그램의 메모리를 가져오는 걸 막기 위함
  • 3000 + 14000 이 최대 메모리인데, 이보다 더 큰 메모리를 요청해 다른 프로그램의 범위를 차지하려는 악의적인 시도가 발생하는 것을 방지함

 

Hardware Support for Address Translation

  • CPU가 메모리 몇 번째를 달라는 논리적 주소를 주게 되면
  • 이 논리적 주소가 프로그램 크기보다 더 큰 주소를 요청하는 게 아닌지 체크 = limit register
  • Limit register 의 값을 넘어가는 값을 요구하게 되면 trap 에 걸리게 됨
  • Trap 에 걸리면 이 프로그램이 CPU를 잡고 있다가도 하던 일을 멈추고, CPU는 운영체제에게 넘어가고, 운영체제는 trap 이 왜 걸렸는지 파악하게 됨

Trap

  • 논리주소가 프로그램 크기보다 더 큰 걸 요구하는 경우 = 악의적인 경우
  • Limit register 와 logical address 를 비교
  • Limit register 를 벗어나는 범위이면 trap 에 걸림

정상 작동 순서

  1. Logical address 가 프로그램 크기 이내에 있다면,
  2. base register 의 값을 더해 주소 변환 후
  3. 물리적 메모리 어딘가에 있는 내용을 읽어 CPU에게 전달해주게 됨

 

Some Terminologies

 

Dynamic Loading

  • 동적으로 올림 = 그때그때 필요할 때마다 메모리에 올림
  • 메모리가 균일하게 사용되는 게 아님
  • 프로그램 상당 부분은 거의 사용되지 않는 오류처리 등이 있고, 자주 사용되는 것도 굉장히 한정적인데,
  • 아주 이상한 프로세스에서도 처리될 수 있도록 방어적으로 만드는 게 일반적임
  • 이런 경우에는 사용되지 않는 것들도 메모리에 포함되는 문제가 발생함
  • 그러니 필요할 때만 메모리에 올려놓자 = dynamic loading
  • OS는 프로그래머가 쉽게 dynamic loading 할 수 있도록 라이브러리 제공해줌
    • OS는 페이징처리를 통해 직접 필요한 때만 메모리에 올려줌(나중에 추가 설명)
  • OS의 페이징 기법과 dynamic loading 은 원래 다르지만 섞어 쓰기도 함
  • 프로그래머가 명시적으로 dynamic loading 하는 게 오리지널
  • 프로그래머가 명시하지 않고 OS가 알아서 관리해주는 것도 dynamic loading 으로 쓰이긴 함

 

Overlays

Overlays

  • Dynamic loading 과 뭐가 다를까?
  • 초창기 컴퓨터 시스템 메모리는 워낙 작기에 큰 프로그램을 쪼개 일부를 먼저 실행하고 ➡️ 그 다음을 메모리에 올려 실행시키는 수작업 코딩을 함 = manual overlay
  • OS의 지원 없고 코딩 통해 전부 수작업으로 진행

Dynamic loading

  • 라이브러리 통해 진행되기에 훨씬 수월

 

Swapping

  • 메모리에서 통째로 쫓겨나는 것
  • Run time binding이 swapping 효율 면에서 좋음

 

Schematic View of Swapping

Swap out

  • 메모리에서 통째로 쫓겨나 하드디스크의 backing store 로 내려가는 것

Swap in

  • Backing store 로 쫓겨났던 게 다시 메모리로 올라오는 것

 

Dynamic Linking

Link

  • 여러 군데 존재하던 컴파일된 파일을 묶어 하나의 실행파일로 만드는 과정
  • 라이브러리도 링킹돼서 내 코드 안에 포함되는 개념 = static linking

Library

  • 내가 작성하지 않은 함수임에도 매우 유용하기에 필요할 때 가져다 쓰는 것

Dynamic linking

  • 내 코드 안에 라이브러리가 안 들어있기에 찾아야 함
  • 실행파일에 라이브러리가 별도의 파일로 존재해서 이걸 찾는 걸 stub 이라 함
  • 라이브러리 위치를 찾을 수 있는 포인터(stub)만 가지고 있고, 실제 코드는 포함하지 않는 것
  • 라이브러리가 이미 메모리에 올라와 있다면 그걸 공유할 수 있는
  • Dynamic library = shared library

 

Allocation of Physical Memory

물리적 메모리 관리 방법

  • 물리적 메모리의 낮은 주소 영역 : 항상 운영체제 커널이 상주함
  • 높은 주소 영역 : 사용자 프로세스

 
사용자 프로세스 영역의 할당 방법

  • Contiguous allocation
  • Noncontiguous allocation

Contiguous allocation

  • 연속 할당

Noncontiguous allocation

  • 불연속 할당
  • Paging 기법 = 프로그램을 구성하는 주소 공간을 같은 크기의 페이지로 잘라, 페이지 단위로 물리적 메모리에 올려두거나 backing store 에 내려두거나 함
  • Page frame = 페이지가 들어갈 수 있는 공간 = 물리적 공간
  • 불연속 할당 시 MMU 에 의한 주소 변환이 복잡해짐
    • 메모리 어디에 올라가 있는지 확인 필요
    • 주소 변환을 페이지 단위로 해야 하기에 binding 이 더 복잡해짐
  • Segmentation 기법 = 프로그램의 주소공간을 같은 크기로 자르는 게 아니라, 의미 있는 단위로 자르는 것

 

Contiguous Allocation

고정 분할 방식

  • 사용자 프로그램이 들어갈 영역을 미리 나눠두는 것

가변 분할 방식

  • 사용자 프로그램이 들어갈 영역을 미리 나눠두지 않는 것
  • 프로그램이 실행될 때마다 차곡차곡 순서대로 올려두는 것
  • 프로그램 D는 외부 조각들보다 크기가 커서, 외부 조각 위치에 들어갈 수 없음 = 사용 불가

낭비되는 메모리 조각

  • 외부 조각
  • 내부 조각

외부 조각

  • 내가 이 프로그램을 메모리에 올리고 싶은데,
  • 올리려는 프로그램보다 메모리 조각의 크기가 작아 사용이 안 됐을 때,
  • 프로그램이 들어갈 수 있는 공간이 있음에도 사용되지 않는 것

내부 조각

  • 프로그램의 크기가 분할한 크기보다 작아, 그 안에 남는 공간이 있을 때 사용되지 않는 것

  • Hole 이 n 보다 크기가 커야 함

Best fit

  • 전체 hole 다 살펴본 후 적합한 hole 에 집어넣기에 hole 을 탐색하는 시간이 다소 소요됨

  • Run time binding 이 지원되는, 메모리 위치가 실행 중에서 변경될 수 있는 기능이 지원돼야 compaction 가능
  • 최소한의 프로그램만을 이동시켜 큰 hole 을 만들 수 있으면 좋겠지

 

Dynamic Relocation

Segment

  • 프로그램의 주소 공간을 구성하는 의미 있는 단위이자 주소 공간
  • Code, data, stack 으로 구성
  • Code 중에서도 함수를 나눠 segment 로 구성할 수도 있음
  • 각각의 함수를 다른 segment 로 만들면 개수가 늘어남, 이 때의 함수 = 의미 단위
  • 각 함수를 segment 로 잘라 물리적 메모리의 다른 위치에 올려놓을 수 있음
  • 거기서 또 segment 단위로 주소 변환 해줘야
  • 의미 단위로 잘랐기에 크기가 균일하지는 않음
  • (dynamic storage-allocation problem 에서도 segment 크기가 균일하지 않아 문제 발생)

Dynamic relocation

  • Segment 는 크게 Code segment / Data segment / Stack segment 로 나뉘는데, 각각의 세그먼트를 필요 시 물리적 메모리의 다른 위치에 올려둘 수 있는 방법

 

Paging

Paging

  • 주소 변환이 페이지 단위로 이루어져야 함
  • 레지스터 2개만을 이용한 주소 변환은 불가능
  • 페이지 테이블 이용해 주소 변환

페이지 테이블

  • 프로그램 구성하는 주소 공간의 페이지가 여러 개 구성되는데,
  • 각 페이지마다 물리적 메모리의 어디에 올라가 있는지를 페이지 테이블에 표시해두는, 일종의 배열

Basic method

  • 같은 크기로 잘랐기에 external fragmentation 발생 안 함
  • Internal fragmentation 발생 가능
    • 프로그램의 크기가 반드시 페이지 크기의 배수가 되라는 보장은 없음
    • 근데 이걸 페이지 단위로 썰다 보니, 페이지 하나보다 남는 자투리가 더 작을 수 있음
    • 그럼 자투리 공간이 남는데, 페이지 하나에는 남는 자투리만 들어가고 아랫부분은 빈공간이 되기에, 외부 조각이 약간 생길 수 있음
  • 근데 페이지 크기를 잘게 썰면 외부 조각에 영향력이 그다지 있지는 않음

# 8-2 Memory Management 2

Allocation of Physical Memory

  • 컴퓨터 전원을 켜면 물리적 메모리에 운영체제 커널이 항상 상주
  • 나머지 영역에 사용자 프로세스가 올라갈 수 있음

Contiguous allocation

  • 사용자 프로세스를 연속으로 할당하는 방법
  • 프로그램을 통째로 메모리에 올려놓는 방법
  • 각각의 프로그램을 물리적 메모리에 올릴 때 주소 변환이 굉장히 간단함

 

Dynamic Relocation

  • 한 프로그램(process p1)이 물리적 메모리에 통째로 올라가면,
  • 프로그램의 주소 체계를 물리적 메모리의 주소 체계로 바꾸는 일
  • 프로그램의 0번지가 물리적 메모리의 몇 번지에 올라가는지 그 시작 주소만 알면, 주소 변환이 쉽게 이루어졌음

e.g. CPU가 논리적 주소 346 번지를 요청하면

  • 프로세스의 주소체계에서 346번지에 해당하는 게 물리적 메모리의 어디에 올라가 있는지를 주소 변환해야 아는 것
  • 이는 레지스터를 통해 아주 간단히 주소 변환할 수 있는데,
  • 베이스 레지스터에 프로세스의 물리적 메모리 상의 시작 위치를 담고 있고,
  • 그럼 논리 주소 346번지 요청 시, 프로세스의 해당 주소(346번지) + 베이스 레지스터가 담고 있는 시작 주소 = 물리적 메모리의 어디에 있는지 쉽게 얻을 수 있음
  • 근데 이는 프로그램이 통째로 메모리에 올라갈 때 그랬고, 실제로는 이렇게 진행되지 않음

 

Paging Example

페이징 기법

  • 프로그램을 구성하는 주소 공간이 동일한 크기의 페이지로 잘려져, 각각의 페이지가 필요에 따라 물리적 메모리의 어느 위치든 올라갈 수 있는 방법
  • 주소 변환이 단지 시작 위치만으로 이루어질 수 있는 게 아니기에, 각각 페이지들이 어느 위치에 올라가 있는지 알아내기 위해 페이지 별 주소 변환을 해주는 방법이 필요
  • 이전 슬라이드처럼 단순히 레지스터 2개를 이용해 주소 변환하는 방법은 사실상 불가하다는 의미
  • 프로그램을 구성하는 논리적 메모리를 동일한 크기의 페이지로 잘라, 페이지 별로 물리적 메모리의 적당한 어디든 비어있는 위치에 올라갈 수 있게 해주는 기법

페이지 테이블

  • 각각의 논리적 페이지들이 물리적 메모리의 어디에 올라가 있는지 알 수 있게
  • 각각의 논리적 페이지 별로 주소 변환하기 위한 페이지들
  • 페이징 기법에서 주소 변환 위해 사용됨

페이지 프레임

  • 논리적 페이지도 페이지 번호를 매기고,
  • 물리적 메모리에서 이 논리적 페이지가 들어갈 수 있는 공간을 페이지 프레임이라 부름
  • 페이지 프레임도 0번부터 동일한 크기의 페이지로 잘라 번호를 매김
  • 논리적 페이지 0번이 물리적 페이지의 어디에 올라가 있는가
  • 페이지 테이블은 논리적 메모리의 페이지 개수만큼 엔트리가 존재함
  • 엔트리
    • 테이블에서 흔히 쓰는 단어
    • 배열의 practical한 의미
  • 페이지 개수만큼 테이블의 엔트리가 존재하고,
  • 각각의 테이블의 엔트리에는 그 페이지가 몇 번 물리적 프레임에 올라가 있는지를 나타내줌
  • e.g. 0번 페이지는 1번 페이지 프레임에 올라가 있음
  • 주소 변환을 위한 페이지 테이블, 즉 페이지 배열은 순차적 검색 필요 없음
  • Why? 엔트리 크기가 미리 정해져 있기에
  • 테이블이나 배열은 어떤 인덱스를 통해 곧바로 접근할 수 있는 자료구조

 

Address Translation Architecture

  • Paging Example의 다른 버전
  • CPU가 논리적 주소를 주면 이를 물리적 주소로 바꿔야 하는데, 페이징 기법은 주소 변환 시 페이지 테이블 사용
  • P = 주소에서 앞부분이 페이지 번호
  • d = 뒷부분이 그 페이지 내에서 얼마나 떨어져 있는지를 나타내는 offset
  • 논리적 페이지 번호에 해당하는 엔트리를 ➡️ 페이지 테이블에서 p번째로 찾아가면 ➡️ f라는 페이지 프레임 번호가 나옴
  • ➡️ 그럼 논리적 주소를 물리적 주소로 바꾸는데, 이는 단지 논리적 페이지 번호를 물리적 프레임 번호로 바꿔주면 주소 변환이 끝남
  • 내부에서의 상대적 위치는 똑같음
  • 페이지 내의 offset 부분은 주소 변환에 영향 없음
  • P와 f만 바뀌지, d는 바뀌지 않음

 

Implementation of Page Table

  • 기본적인 MMU 기법에서는 2개의 레지스터(CPU안에 들어가는 아주 빠른 장치)로 주소 변환함
  • 프로그램을 구성하는 주소 공간을 페이지 단위로 자르는데, 보통 페이지 단위는 4KB
    • = 프로그램의 주소 공간이 굉장히 크다는 의미
  • 주소 공간을 자르면 페이지 테이블의 엔트리가 현재 4개로 보이는데, 실제 100만개 정도 필요
    • = 실제 100만개 정도의 페이지로 잘린다
    • = 페이지 테이블이 엄청난 용량을 차지
  • 프로그램마다 페이지 테이블을 별도로 둬야 하는 부담까지
  • 페이지 테이블은 용량이 너무 커 레지스터에 넣을 수도 없고,
  • 메모리 접근을 위한 주소 변환인데 이 페이지 테이블을 하드디스크에 저장할 수도 없고,
  • 캐시 메모리에 들어가기에도 용량이 너무 큼
  • Q) 그럼 페이지 테이블은 어디에 넣어야 할까? A) 물리적 메모리에
  • 실제로 메모리에 접근하려면 주소 변환 후 접근해야 하는데,
  • 주소 변환을 하려면 페이지 테이블에 접근해야 하고,
  • 또 페이지 테이블은 메모리에 존재하기에,
  • 결국 메모리에 한 번 접근하려면 두 번의 메모리 접근이 필요
  • 매번 두 번 접근해야 하는 부담이 커서 속도 향상이 중요함

첫 번째 memory access

  • 페이지 테이블 통한 주소 변환 위해 메모리 접근 필요

두 번째 memory access

  • 주소 변환 됐으면 메모리에서 실제 데이터에 접근하기 위해, 또다시 메모리 접근 필요

Base register

  • 메모리 상에서 테이블이 어디에 있는지에 대한 시작 위치를 base register가 가지고 있음

Limit register

  • 페이지 테이블의 길이는 PTLR이라는 레지스터가 가지고 있음

TLD

  • 일종의 캐시
  • 메인 메모리와 CPU 사이에 존재 및 주소 변환하는 계층

 

Paging Hardware with TLB

페이지 테이블

  • 원래 물리적 메모리 안에 있음

오리지널 페이징 기법에서는

  • CPU가 주는 논리적 주소에 대해, 물리적 메모리 상에 존재하는 페이지 테이블을 통해 주소 변환
  • ➡️ 이후 변환된 주소로 물리적 메모리에 접근
  • ➡️ 그러면 물리적 메모리에 두 번 접근해야 하기에 속도 향상 필요
  • ➡️ TLB라는 별도의 하드웨어를 둠

TLB

  • 메인 메모리 윗단에 캐시 메모리가 있는데, 이 캐시 메모리는 운영체제에게는 감추어진(transparent) 계층
  • 메인 메모리에서 빈번히 사용되는 데이터를 캐시 메모리에 저장해 CPU로부터 더 빨리 접근할 수 있게
  • 이런 것처럼 메모리 주소 변환 위한 별도 캐시를 두고 있는데, 그게 바로 TLB 계층
  • 데이터 보관용 캐시 메모리와 용도는 다름(TLB는 주소 변환이 목적)
  • 페이지 테이블에서 빈번히 참조되는 일부 엔트리를 캐싱하는 역할
    • 페이지 테이블의 전체가 아닌 일부만 담고 있음
    • 빈번히 참조되는 엔트리 몇 개만 가지고 있음
  • 페이지 테이블, 즉 메인 메모리보다 접근이 빠른 하드웨어로 구성됨
  • CPU가 논리적 주소를 주면 물리적 메모리 상의 페이지 테이블에 접근 전, TLB에서 먼저 검색
  • TLB에 저장된 정보를 이용해 주소 변환이 가능한지 확인
  • 만약 존재하면 TLB 통해 바로 주소 변환이 이루어진 후 물리적 메모리에 접근 = 물리적 메모리에 1번만 접근
  • 만약 TLB에 존재하지 않으면 물리적 메모리의 페이지 테이블에 접근해 주소 변환 후, 다시 물리적 메모리에 접근 = 물리적 메모리에 2번 접근
  • TLB는 페이지 테이블에 있는 모든 걸 가지고 있는게 아니니, 주소 변환된 프레임 번호 f만 보관한다고 주소 변환이 이루어지지 않음
    • 페이지 테이블에서 몇 번째 엔트리에 해당하는 걸 주소 변환한 게 f인지
    • 논리적 페이지 번호 p와 그 p에 대해 주소 변환된 프레임 번호 f, 이 둘을 쌍으로 가지고 있어야 함
  • 전체를 가지고 있는 게 아니니 논리적 페이지 + 논리적 페이지 번호의 쌍을 가지고 있어야
  • 주소 변환 위해 TLB의 특정 항목이 아닌 전체를 검색해야 함
  • p라는 페이지에 대한 주소 변환된 주소가 TLB에 있는지 확인하려면
    • 위부터 전체 항목에서 p가 있는지 확인 후,
    • 있으면 그에 대한 주소 변환된 정보인 f가 있다는 걸 알 수 있음
  • 근데 TLB에 없으면 페이지 테이블로 가서 주소 변환해야
  • 그러므로 TLB는 특정 항목이 아닌, 전체를 서칭함

 

Associative Register

  • TLB는 특정 항목이 아닌, 전체를 서칭함
  • 그래서 병렬적 서칭이 가능한 associative registers를 통해 구현하고 있음
  • TLB에서 페이지 번호 p를 기준으로 p에 해당하는 주소 변환 정보가 있는지를 parallel하게 서칭해서
    • 어느 한곳에 p가 있으면 주소 변환이 바로 이루어지고
    • 어디에도 없으면 TLB miss가 나면서 페이지 테이블에서 주소 변환이 이루어짐

페이지 테이블

  • 페이지 테이블에서는 엔트리 정보를 전부 서칭할 필요 없음
  • 페이지 번호 p가 주어지면 배열의 인덱스를 이용해 바로 찾을 수 있음
  • 직접 p번째 엔트리에 가기만 하면 주소 변환이 이루어짐
  • 각 프로세스마다 논리적 주소 체계가 다름(각 프로세스마다 존재)
  • 페이지 테이블의 일부를 담는 TLB도 프로세스마다 다른 정보를 담음
  • 그래서 프로세스마다 CPU 넘겨받을 때 flush 처리

 

Effective Access Time

  • TLB에 접근하는 시간 = associative register lookup time = 입실론
  • TLB에 접근하는 시간이 메인 메모리에 접근하는 시간(memory cycle time)인 1보다 훨씬 작음
  • TLB로부터 주소 변환되는 비율 = hit ratio = a = 알파

<hit>

  • 알파의 비율 만큼은, 즉, TLB에서 주소 변환 정보가 찾아지는 만큼은 = * a
  • TLB에 접근하는 입실론 시간 + 주소 변환이 끝났으니 실제 데이터에 접근하는 물리적 메모리 접근 시간 1 = (1 + 입실론)

<miss>

  • 주소 변환 정보가 TLB에 없는 경우, 1 – a 의 비율만큼은 TLB접근을 해봤는데 TLB에 없었지 = 입실론에 한시간 걸리고
  • 그럼 페이지 테이블에 접근하는 시간 필요, 물리적 메모리 접근 시간 1 들고
  • 주소 변환 후 실제 데이터 접근하려고 물리적 메모리 접근해야 하니 물리적 메모리 접근 시간 + 1 = 2
  • 알파는 거의 1에 가까운 큰 숫자, 입실론은 그에 반해 아주 작은 숫자
  • 결과값 = 페이지 테이블만 있을 때 접근하는 시간 2보단 훨씬 작은 시간이 됨

페이지 테이블을 이용한 주소 변환

  • 페이지 테이블이 물리적 메모리에 있고
  • 속도를 향상시키기 위해 TLB라는 주소 변환용 캐시를 이용해 메모리 접근을 빠르게 해줌

 

Two-Level Page Table

논리적 주소가 32 bits로 구성되면

  • 논리 주소는 프로그램마다 독자적으로 가지는 주소 공간, 즉, 프로그램의 크기(Virtual memory 크기)가 멕시멈 얼마까지 가능하겠느냐
  • 현대 컴퓨터 시스템은 각 프로그램의 Virtual memory 크기와 실제 물리적 메모리 크기는 독립적
  • 물론 물리적 메모리가 클수록 빠르긴 하나, 페이지 단위로 나뉘어 물리적 메모리로 올라오기에, 물리적 메모리보다 논리적 메모리 크기가 더 크더라도 실행 시 문제 없음
  • Q) 프로그램마다 가진 Virtual memory가 얼마까지 가능한가? A) 메모리를 표시하는 주소 체계를 몇 비트를 쓰느냐에 따라 달라짐

그럼 32 bits 주소 체계를 쓰면?

  • Q) Virtual memory에는 주소가 어떤 단위로 매겨지느냐? A) 바이트 단위로 매겨짐
    • 그럼 전체 공간은 4G
    • 페이지 사이즈는 4K
    • 4GB를 4K로 나누면 1M 개의 페이지 개수가 얻어짐
  • 결국 이 페이지 테이블도 물리적 메모리에 들어가야 함 = 공간 낭비가 심함
  • 엔트리 개수가 1M (백만 여) 개인데, 엔트리 크기가 4 bytes = 공간 낭비 심함

 

  • 1 bit면 표현 방법 1
  • 2 bits면 표현 방법 4
  • 3 bits면 표현 방법 8 = 2의 3승
  • 32 bits면 2의 32승

 

  • 2의 10승 = K 킬로
  • 2의 20승 = M 메가
  • 2의 30승 = G 기가

 

  • 전체 논리적 메모리 공간에서 실제로 사용되는 공간은 굉장히 적음 = 대개 중간중간 빈 공간이 있음
  • 근데 페이지 테이블은 위부터 아래로 인덱스 접근하기에, 빈 공간을 남겨두지 않음
  • 주소 체계 중 실제 일부분만 사용되지만, 페이지 테이블은 다 만들어줘야 한다는 의미

 

2단계 페이지 테이블

  • 페이지 테이블을 두 단계를 거쳐 주소 변환 진행
  • 바깥쪽 페이지 테이블 + 안쪽 페이지 테이블 ➡️ 이후 실제 메모리 접근

 
컴퓨터에서는 보통 목적이 2가지

  • 속도를 빠르게 하던지
  • 공간을 줄이던지

기억해야 할 점

  • 안쪽 페이지 테이블의 크기가 페이지 크기와 똑같음
  • 안쪽 페이지 테이블은 테이블 자체가 페이지화되어, 물리적 메모리의 페이지 어딘가에 들어가 있게 됨, 여기서 물리적 메모리의 페이지 하나의 크기가 4KB = 안쪽 페이지 테이블의 크기
  • 안쪽 페이지 테이블의 엔트리 하나의 크기 = 4 bytes
  • Q) 그럼 4KB의 안쪽 페이지 테이블에서 엔트리 하나가 4 bytes면, 4KB 안에 4 bytes를 몇 개를 넣을 수 있음?
    • A) 4K 개
    • 그럼 엔트리 개수는 1K 개

 
2단계 페이지 테이블 사용 이유

  • 속도는 더 느리지만, 페이지 테이블을 위한 공간을 줄일 수 있음
  • 근데 사실 바깥 테이블의 수가 줄어들 뿐, 안쪽 테이블은 백만 개 조회는 똑같음
  • 게다가 바깥 개수 + 안쪽 개수이기에 시간은 더 걸리고, 공간도 더 차지함
  • 주소 변환도 2번
  • 공간도 1단계 페이지 테이블에서 쓰던 엔트리 다 필요 + 바깥용 페이지 테이블 위한 엔트리도 또 필요
  • 그럼 시간도 손해, 공간도 손해라는 거임

그럼에도 쓰는 이유?

  • 프로그램을 구성하는 공간 중 상당 부분은 사용되지 않음
  • 실제 사용하는 페이지 수는 얼마 안 되는데, 페이지 테이블로 만들 땐 우리가 사용하지 않는 중간 공간들의 엔트리를 안 만들 수 없음(중간 엔트리를 없애면 배열의 인덱스 접근이 불가하기에)
  • ➡️ 맥시멈 로지컬 메모리의 크기만큼 페이지 테이블에 엔트리가 만들어져야 함
  • 근데 2단계 페이지 테이블을 쓰면 이를 해소할 수 있음
  • 바깥 테이블은 논리적 크기만큼 만들어지나,
  • 실제 사용 안 되는 주소에 대해 안쪽에서 안 만들어지고 포인터도 null로 되어 있고,
  • 실제 사용되는 메모리 영역에 대해서만 안쪽 테이블에 만들어져서 물리적 메모리의 주소를 가리키고 있고,
  • 중간에 사용 많이 안 하는 공간은 바깥 테이블에서도 null로 되어있고,
  • 그럼 안쪽은 안 만들어지기에,
  • 얼마나 사용 안 되는 공간이 많길래 2단계 페이지 테이블이 사용될지 짐작 가능
  • ➡️ 이런 논리로 공간 절약이 가능하다는 의미

 

Two-Level Paging Example

  • page number
  • p1, p2 = 서울 서대문구처럼 p1 ➡️ p2로 갈수록 구체화되는

예제 순서

  1. 논리적 주소에서 바깥쪽 페이지 테이블의 인덱스를 찾은 페이지 번호로 p1 번째 엔트리로 가서 주소 변환 정보를 얻는데,
  2. 여기서 얻어지는 건 안쪽 페이지 테이블 중 어떤 페이지 테이블인지를 지정해줌
  3. 안쪽 페이지 테이블은 여러 개가 있음
  4. 그 다음 p2 번째 엔트리에 가면 물리적 페이지 프레임 번호를 얻게 됨
  5. 이 페이지 프레임 번호를 d에 덮어씌우면 페이지 프레임이 나오고,
  6. 페이지 내에서 d 번째 떨어진 위치에서 원하는 정보를 찾을 수 있음

 
32 bits의 주소 체계에서

  • 페이지 안에서 떨어져 있는 offset이 몇 bits가 되어야 하고
  • 안쪽 페이지 테이블 번호가 몇 bits로 표현되어야 하고
  • 바깥쪽은 몇 bits로 표현되어야 하는지

 

  • 페이지 하나의 크기 = 4KB = 2의 12승
  • 그 안에서 byte 단위로 주소 구분을 하려면 몇 bits가 필요할까?

 

  • 하나의 페이지 안에서 몇 번째 떨어져 있는 byte 인지를 구분하기 위해,
  • 2의 12승 바이트를 구분하려면 12 비트가 필요함
  • 페이지 안에서 바이트 단위로 얼마나 떨어져 있는지를 구분하는 offset에 의해 12비트가 필요

 
Q) 20비트의 page number는 어떻게 나눌 것이냐

  • 안쪽 페이지 테이블에는 1K개의 엔트리가 있음
  • 1K개의 엔트리의 위치를 구분하기 위해 p2는 몇 비트가 되어야 하느냐
  • 1K = 2의 10승
  • 서로 다른 2의 10승 개의 엔트리 위치를 구분하기 위해 몇 비트가 필요하느냐 = 10비트
  • 그래서 page number인 p1, p2가 가리키는 숫자가 각각 10인 거임
  • 64비트인 주소 체계인 경우에는 어떨까?

 

Access-Translation Scheme

p1

  • p1 – p2 – d = p1의 비트

p2

  • 1K 군대 구별 ➡️ 10비트

d

  • 서로 다른 4K 군대 구별 ➡️ 12비트

# 8-3 Memory Management 3

Multi-level Paging and Performance

Multi-level Paging and Performance

  • 페이지 테이블을 위한 공간을 더 많이 줄일 수 있음
  • 그러나 한 번 주소 변환하려면 페이지 테이블을 여러 번 거쳐야 함
  • 또 페이지 테이블이 물리적 메모리에 있기에 주소 변환 위해 메모리에 4번 접근해야
  • 또 주소 변환 후 실제 원하는 데이터에 접근하기 위해 또 물리적 메모리에 접근해야
  • 그래서 총 5번의 접근이 필요해짐 = 오버헤드 엄청남

but TLB를 사용한다면 상황이 달라짐

  • 주소 변환을 전담해주는 일종의 캐시 메모리
  • 4단계 페이지 테이블 접근 시 시간이 오래 걸릴 수는 있으나,
  • 대부분의 주소 변환은 TLB를 통해 직접 이루어지기에,
  • 다단계 페이지를 사용하더라도 시간이 지나치게 오래 걸리지는 않음

 

Valid (v) / Invalid (i) Bit in a Page Table

왼쪽 그림

  • 논리적 메모리
  • 로지컬 메모리에 있는 페이지 개수 만큼 페이지 엔트리가 존재
  • 사용되지 않는 주소 영역이 많이 존재

가운데 그림

  • 페이지 테이블
  • 각 엔트리에는 논리적 메모리에 있는 페이지가 물리적 메모리의 어떤 페이지 프레임에 올라가 있는지에 대한 페이지 프레임 정보, 즉, 주소 변환 정보가 들어있음
  • + 주소 변환 정보 뿐만 아니라 추가적인 비트가 엔트리에 저장됨 = valid–invalid bit
  • 프로그램의 주소 공간이 가질 수 있는 최대 사이즈만큼 페이지 엔트리가 생겨야 함
  • 사용되지 않는 영역을 위해서도 엔트리가 만들어져야 함
  • Why? 테이블이라는 자료 구조 상 위에서부터 index로 접근해야 하기에, 빈 페이지가 있더라도 그대로 남겨둬야 함 = 이게 invalid bit

valid

  • 페이지 테이블 엔트리에 가면 0번 페이지가 2번 프레임에 실제 올라와 있다는 의미

invalid

  • 페이지가 프로그램에 의해 사용되지 않거나, 페이지가 항상 메모리에 올라가 있지 않은 경우
  • (사용할 때는 늘 물리적 메모리에 올라가 있으니)
  • 그러면 하드디스크의 backing 스토어에 내려가 있을 것임
  • 이때 그 페이지에 대한 주소 변환 시도 시, 물리적 메모리 프레임에는 안 올라와 있으니 invalid

오른쪽 그림

  • 물리적 메모리

 

Memory Protection

backing store

  • swap area

protection bit

  • valid-invalid bit 말고, 또 다른 bit
  • 자기 자신의 프로세스가 자기 자신에게만 접근하는 개념이기에, 이는 다른 프로세스의 접근과 무관함
  • 페이지 접근 권한을 제어 = 어떤 연산에 대한 접근 권한이 있느냐를 나타냄
  • 코드를 담는 페이지, 데이터나 스택 부분을 담는 페이지 등이 있는데,
  • 코드의 경우, 내용이 바뀌면 안 되고, 원래의 그 내용을 cpu에서 읽어 인스트럭션을 실행하는 용도 ➡️ 그래서 코드는 read-only로 세팅
  • 데이터나 스택은 read, write 권한 다 주고,
  • 이런 연산에 대한 권한을 표시하는 게 protection bit

 

Inverted Page Table

  • 페이지 테이블 자체가 차지하는 용량이 상당함
  • 주소 변환을 위한 공간인데, 페이지 테이블 자체가 데이터를 많이 차지하면 안 되겠지?
  • 주소 공간이 허용하는 한도만큼의 페이지 테이블 엔트리가 만들어져야 하고, 프로세스마다 각각 주소 변환을 해야하며, 각 프로세스마다 페이지 테이블이 있어야 하기에, 공간 오버헤드가 큼
  • 이를 막아보자 = Inverted Page Table

 

Inverted Page Table Architecture

  • 원래 페이지 테이블에 대한 주소 변환 개념을 역발상으로 전환한 것
  • 기존에는 페이지 테이블이 프로세스마다 존재했는데, 얘는 시스템 안에 페이지 테이블이 1개만 존재
  • 페이지 테이블의 엔트리가 프로세스의 페이지 개수만큼 존재하지 않고, 물리적 메모리의 페이지 프레임 개수만큼 존재한다는 의미
  • ➡️ 페이지 프레임 개수만큼 엔트리가 존재

 

  • 기존에는 페이지 번호를 보고 위에서부터 페이지 번호만큼 떨어지는 엔트리를 찾아 주소 변환을 진행했는데,
  • 얘는 그게 아예 불가함. Why? 들어가는 방향이 반대임
  • 첫 번째 엔트리에는 첫 번째 페이지 프레임에 들어가는 논리적 페이지 번호가 들어있음
  • 즉, 페이지 프레임에서 먼저 f번째 엔트리를 찾으면 ➡️ 논리적 페이지 번호가 나오는 정반대의 개념
  • 기존에는 논리적 주소를 보고 물리적 주소를 찾았는데,
  • 얘는 물리적 주소를 보고 논리적 주소를 찾아 바꿀 수 있는 테이블
  • 사실 우리 목적에 맞지는 않다고 봐야지

 

  • 논리적 주소를 보고
  • ➡️ 페이지 테이블에서 전체를 다 뒤져서
  • ➡️ 해당하는 p가 나오면, 이게 f번째라면
  • ➡️ 물리적 주소에서 f번째에 있는 정보를 찾을 수 있음
  • 배열처럼 인덱싱해서 찾는 게 기존 페이지 테이블의 장점인데,
  • 얘는 페이지 번호가 주어지면 엔트리를 전체 검색해야 주소 변환을 할 수 있음
  • 그래서 이 페이지 테이블을 associative register라는 별도의 하드웨어에 넣어 병렬적으로 동시 검색 가능하게 하면 순차적 탐색 오버헤드를 줄일 수 있음

 
장점

  • 시스템 안에서 하나만 존재하기에 공간을 많이 줄일 수 있음

단점

  • 시간이 오래 걸림
  • 엔트리를 전체 검색해야 물리적 주소의 정보를 알 수 있음
  • 페이지 번호 p가 어떤 프로세스의 p번째 페이지 번호인지 그 프로세스 아이디(pid)를 함께 저장해야 함
  • 왜냐하면 논리적 메모리는 프로그램마다 별도로 있는 개념이기에, 누구의 p번째 페이지인지에 대한 정보가 같이 필요

단점 보완

  • 그래서 어떤 프로세스의 페이지 번호라는 정보를 같이 주고,
  • 그 프로세스의 p번째 페이지가 어디인지 찾아서,
  • 찾아진 위치가 위에서부터 몇 번째 엔트리인지 확인 후,
  • 엔트리 위치에 해당하는 번호를 페이지 프레임 번호에 넣어주면 주소 변환 완료
  • 근데 공간을 줄이기 위해 이렇게 일일이 다 검색하면 오버헤드가 너무 큼

 

Shared Page

shared code

  • 프로그램을 구성하는 페이지 중, 다른 프로세스와 공유할 수 있는 페이지
  • re-entrant code
  • pure code
  • 여러 프로그램들이 같은 코드를 가지고 프로그램을 돌린다면, 그들은 같은 코드를 써도 됨
  • 이 경우, 중복 사용 가능한 코드를 메모리에 한 copy만 올려 씀
  • 여러 프로세스가 공유할 수 있는 코드를 같은 물리적 메모리에 매핑해주는 기법

shared code의 제약조건이자 필수조건

  • 이 코드들은 반드시 read-only
  • shared code는 동일한 논리적 주소(논리적 메모리에서 같은 페이지에 위치)를 가져야 함(동일한 물리적 주소를 가지는 건 당연)

private code and data

  • 프로세스마다 별도로 가져야 하는 코드 및 데이터

 

Shared Pages Example

p1, p2, p3 모두

  • 페이지 테이블에서 같은 페이지 프레임 번호로 매핑해 메모리에 한 카피만 올려 사용

논리적 주소

  • shared code를 가진 프로세스들은 동일한 논리적 메모리에서 페이지 번호를 가지고 있어야

shared memory vs shared page

shared memory shared page
read, write 가능 read-only 코드를 공유

 

Segmentation

페이징 기법

  • 프로그램을 구성하는 주소 공간을 페이지 단위로 쪼갠 것

segmentation 기법

  • 프로세스를 구성하는 주소 공간을 의미 단위로 쪼갠 것
  • 코드, 데이터, 스택 등으로 쪼갬
  • 더 잘게 쪼개고 싶다? 그럼 코드 기준, main() 함수 아래 … 등 별도의 세그먼트로 구성 가능

 

Segmentation Architecture

  • 페이징 기법과 비슷한 측면 있음

논리적 주소

  • segment-number, offset (세그먼트 안에서 얼마나 떨어져 있는지를 나타내는) 두 가지로 구성

 

  • 각 세그먼트 별로 서로 다른 물리적 메모리 위치에 올라갈 수 있기에 세그먼트 별로 주소 변환을 해야 함, 그래서 세그먼트 테이블을 두고 있음
  • 주소 변환 위한 두 가지 레지스터가 지원되는데,
  • 테이블의 시작 위치를 나타내는 = STBR
  • 테이블의 길이를 나타내는 = 그 프로그램이 사용하는 세그먼트 엔트리의 수 = STLR

 

Segmentation Hardware

  • CPU가 논리 주소를 주면 이를 두 부분으로 나눔
    • segment-number
    • offset
  • 세그먼트 테이블의 시작 위치
    • 레지스터가 가지고 있음
  • 세그먼트 테이블은 그 시작 위치부터, 세그먼트 번호의 위치만큼 떨어진 엔트리 위치에 가면, 이 세그먼트가 물리적 메모리에 어떤 번지에 올라가 있는지에 대한 정보를 가짐

세그멘테이션 기법의 엔트리

  • 세그멘테이션 기법은 페이지 기법과 다르게, 엔트리에 두 가지 정보를 가지고 있음
  • 물리적 메모리 상의 시작 위치 외에,
  • limit이라는, 세그먼트 길이를 가지고 있음
  • 페이지 기법에서는 페이지 크기가 모두 동일했으나, 세그멘테이션 기법에서는 의미 단위로 자르기에 세그먼트 길이가 균일하지 않을 수 있음

세그멘테이션 기법으로 주소 변환 시 고려해야 할 두 가지

  • CPU에 주어진 주소에서 논리 주소의 세그먼트 번호가 세그먼트 길이보다 작은 값인지 확인 필요
    • Why? 세그먼트 길이보다 큰 값을 요청하면 잘못된 시도이기에 trap에 걸림
  • 세그먼트를 통해 주소 변환 시, 세그먼트 길이보다 지금 세그먼트 안에서 떨어진 오프셋이 더 크지는 않는지 확인

 

  • 정상적인 요청 = 주소 변환 = 세그먼트 시작 위치 + 오프셋
  • 물리적 메모리에서 위에서부터 base 위치만큼 떨어진 곳에서부터 세그먼트가 시작
  • 거기서부터 d만큼 떨어진 위치에 가면 원하는 주소의 내용이 들어있음

 

Segmentation Architecture (Cont.)

페이징 기법

  • 페이지 크기가 모두 동일하기에, 오프셋이 미리 결정됨
  • 시작 주소가 프레임 번호로 주어지면 됨

세그먼트 길이

  • 오프셋으로 표현할 수 있는 비트수 이상은 불가함
  • 세그먼트 크기가 다 달라서 세그먼트가 어디에서 시작하는지를 정확한 바이트 단위로 매겨줘야 함
  • 연속할당기법에서 프로그램 크기가 균일하지 않아, 프로그램을 시작/종료할 때 여러가지 구멍이 생기는데, 세그먼트도 이와 마찬가지임
  • 중간중간 사용하지 않는 메모리 공간(external fragmentation, 외부 조각)이 생기는 단점이 있음
  • ➡️ 그래서 first fit / best fit을 가져다 써야 함

그럼에도 세그멘테이션 기법이 가지는 장점

  • 의미 단위 작업 시 매우 효과적

protection

  • 연산에 대한 권한 조건을 의미 단위로 나눠 부여
  • 페이징 기법에서는 프로그램을 구성하는 페이지를 동일하게 자르면,
    • 어떤 경우에는 코드와 데이터가 같이 들어가게 되는데,
    • 그럼 read-only를 줘야 할지, read & write를 줘야 할지, 의미 단위로 나누는 게 어려워짐

sharing

  • 의미 단위로 나눠야 효율적 작업 가능

allocation

  • 그러나 크기가 균일하지 않기에 외부 조각 발생

# 8-4 Memory Management 4

Segmentation Hardware

논리주소

  • 세그먼트 번호 + 세그먼트 안에서 얼마나 떨어져 있는지 그 위치를 나타내는 번호

세그먼트 번호

  • 세그먼트가 몇 개 있느냐에 따라 세그먼트 엔트리 개수가 정해짐

세그먼트 주소 변환

  • 세그먼트가 물리적 메모리 어디에 올라가 있느냐

 

  • 세그먼트 테이블의 해당 엔트리에 가면 이 세그먼트의 물리적 메모리 상의 시작 위치, 즉, base라는 주소값이 있음
  • base + 얼마나 떨어져 있느냐를 상징하는 offset 더해주면 주소 변환 가능

 

  • 세그먼트는 의미 단위로 자르기에 길이가 균일하지 않음
  • 그래서 세그먼트의 시작 위치 + 길이를 세그먼트 테이블에 각각 담고 있음
  • 세그먼트 길이보다 큰 값을 요구하면 적절하지 않은 메모리 참조인 것


주의사항

  • offset <= limit, 합당한 메모리 참조일 때만 주소 변환 해주기
  • offset = 세그먼트 내에서 얼마나 떨어져 있는지
  • limit = 세그먼트 길이
  • 이 조건 벗어나면 trap 걸어서 방지해줘야

 

Segmentation Architecture

 

Example of Segmentation

  • 페이징 기법에 비해, 메모리 공간 낭비 덜함

세그먼테이션

  • 의미 단위 처리 / 공유, 보안 등에 활용

 

  • 페이지는 개수가 되게 많은데, 세그먼트는 별로 없음
  • ➡️ 페이징 기법은 테이블을 위한 메모리 낭비가 심함

 

Segmentation Architecture (Cont.)

 

Sharing of Segments

  • 서로 다른 프로세스가 세그먼트 공유

segment 0

  • 코드를 담고 있고, 서로 다른 프로세스에서 같은 역할을 함

shared segment

  • 같은 물리적 메모리에 한 copy가 올라감(base : 43062)

 
segment1

  • data1, data2 : 서로 다른 주소 변환 정보가 들어있음

private segment

  • 별도의 주소 변환 처리

 

Segmentation with Paging

  • segmentation & paging 혼합 기법
  • 1개의 세그먼트가 여러 개의 페이지로 구성됨
  • 세그먼트에 대한 주소 변환이 먼저 이루어짐

logical address

  • s = 세그먼트 번호
  • d = 세그먼트 안에서 얼마나 떨어져 있는지를 나타내는 offset

 

  • 세그먼트 테이블이 메모리의 어디에 와 있는지를 찾아야 함
  • STBR 레지스터에 세그먼트의 시작 위치 정보가 들어있음
  • 거기서부터 s번째 엔트리에 가면 s 세그먼트에 대한 주소 있음

 
오리지널 세그멘테이션 기법

  • 세그먼트 테이블에 가면, 이 세그먼트가 물리적 메모리 어디에 올라가 있는지, 그 시작 위치가 담겨 있었음
  • 근데 오리지널에서는 세그먼트가 물리적 메모리에 통째로 올라가기에, 세그먼트의 시작 위치를 알려줘도 되지만,

혼합 기법은

  • 한 세그먼트가 여러 개의 페이지로 구성됨
  • 그래서 물리적 메모리에 올라갈 때 페이지 단위로 쪼개져서 올라감
  • 뭐가 장점일까? 중간중간 빈 곳 생겨 first나 best를 반영할 필요 없어짐 = allocation 문제가 발생하지 않음
  • Why? 물리적 메모리에는 페이지 단위로 올라가고, 세그먼트는 페이지 개수의 배수로 구성이 됨

 

  • 의미 단위로 해야 하는 공유 / 보안 등은 세그먼테이션 레벨에서 진행
  • 특정 세그먼트가 read-only인지, read & write 가능한지 등을 이 단계에서 표시
  • 실제 물리적 메모리로 올라갈 땐 페이지 단위로 올라감
  • 내부에서는 페이지 기법을 쓰는 게 수월함

 
두 단계의 주소 변환을 거치지만,

  • 세그먼트가 각 페이지 별로 주소 변환
  • 세그먼트 당 페이지 테이블이 존재하게 됨
  • 세그먼트 테이블의 해당 엔트리에 가면 이 세그먼트를 구성하는 페이지 테이블의 시작 위치가 나옴
  • 페이지 테이블의 엔트리 개수 = 세그먼트 길이

 

  • p = 페이지 번호
  • d = 페이지 내에서 얼마나 떨어져 있는지에 대한 offset
  • 페이지 테이블의 시작 위치로부터 페이지 번호 만큼 떨어진 곳에 가면 해당 페이지에 대한 주소 변환 결과가 나오고,
  • 물리적 메모리의 몇 번째 프레임에 있는지 그 번호가 나오게 됨

physical address

  • f = 물리적 메모리 내에서 몇 번째인지 프레임 번호
  • d = 페이지 안에서의 offset이 그대로 반영됨, 이게 물리적 메모리의 주소