✨ Logical address (논리적 주소 , =virtual address)
✨ Physical address (물리적 주소)
📌 Logical address에서 Physical address로 변환하는 것은 하드웨어가 하는 일이다
📌 주소 바인딩 : 주소를 결정하는 것
Symbolic Address → Logical Address → Physical address
↑
프로그래머가 바라보는 이 시점이
주소 언제인가?
✨ Compile time binding
물리적 메모리 주소(physical address)가 컴파일 시 알려짐
컴파일러는 절대 코드(absolute code), 즉 고정된 주소를 생성한다
시작 위치 변경시 재컴파일
Compile time binding은 프로그램 내부의 논리적 주소와 메모리상 물리적 주소가 동일하다
🏴 문제점 : 주소가 고정되어 있기 때문에 메모리 상에 빈 공간이 많이 발생할 수 있어 비효율적이고, 로드하려는 위치에 이미 다른 프로세스가 존재할 수 있다.
✨ Load time binding
Relocatable code는 메모리의 어느 위치에서나 수행될 수 있는 기계 언어 코드이다.
✨ Execution time binding (=Run time binding)
✨ MMU (Memory-Management Unit)란?
✨ MMU scheme
✨ user program
현대적 주소변환은 이렇게 간단하지 않다. 지금의 소개에는 메모리에 올라갈 프로세스의 주소들이 하나로 묶여서 올라가지만 현대의 운영체제 하에서는 쪼개져서 필요한 부분만 메모리로 올라가고 나머지는 디스크의 스왑영역에 저장된다.
basic register는 physical address의 프로세스 주소 최소값(14000)을 알고있고, 그 프로세서의 논리적 주소의 범위를 Limit register가 저장(3000).
346번만큼 올라가있는 주소를 더하면 바로 답이 나온다.
📌 Relocation register(= base register) 접근할 수 있는 물리적 메모리 주소의 최소값
📌 Limit register 논리적 주소의 범위 , 잘못된 메모리를 참조를 막아주는 기능을 한다
Dynamic Loading
'Loading: 메모리로 올리는 것'
Dynamic Linking
Linking : 내가 만든 코드와 library가 링크돼서 이루어 지는것
Overlays (대단히 메모리가 작전 시절의 이야기)
Swapping
여기서 말하는 Swapping은 통째로 쫒아내는 것을 의미. 현대적인 Swapping 방법은 통째로 쫒아내기도 하지만 부분부분 쫒아내는 것.
✨ 메모리는 일반적으로 두 영역으로 나뉘어 사용
✨ 사용자 프로세스 영역의 할당 방법
Contiguous allocation (연속 할당)
: 각각의 프로세스가 메모리의 연속적인 공간에 적재되도록 하는 것
✓ Fixed partition allocation (고정 분할 방식)
✓ Variable partition allocation (가변 분할 방식)
Noncontiguous allocation (불연속 할당)
: 하나의 프로세스가 메모리의 여러 영역에 분산되어 올라갈 수 있음
✓ Paging
✓ Segmentation
✓ Paged Segmentation
실제 현대의 운영체제에서는 사용하지 않는 방식
✨ 고정분할(Fixed partition) 방식
✨ 가변분할(Variable partition) 방식
📌 External fragmentation (외부 조각)
📌 Internal fragmentation (내부 조각)
✨ Hole
✨ Dynamic Storage-Allocation Problem
: 가변 분할 방식에서 size n인 요정을 만족하는 가장 적절한 hole을 찾는 문제
💡 First-fit best-fit worst-fit보다 속도와 공간 이용률 측면에서 효과적인 것으로 알려짐 (실험적인 결과)
✨ compaction
프로그램을 구성하는 주소공간이 짤려져서 서로 다른 주소환경에 올라 갈 수 있다.
✨ Paging
✨ Basic Method
Page table main memory에 상주
Page-table base register (PTBR)가 page table을 가리킴
Page-table length register (PTLR)가 테이블 크기를 보관
모든 메모리 접근 연산에는 2번의 memory access 필요
주소 접근을 위해 page table 접근 1번, 실제 data/instruction 접근 1번
속도 향상을 위해 associative register와 translation look-aside buffer(TLB)라 불리는 고속의 lookup hardware cache 사용
Page table은 인덱스를 통해 빠르게 서치 가능하지만 TLB는 인덱스가 없기때문에 논리적인 페이지 번호와 프레임 넘버를 쌍으로 가지고 있어야 한다.
TBL를 일일이 하나씩 서치하는 것은 오버헤드가 너무 크다. 그래서 TLB는 병렬적 서치를 가능하게 해주는 associative register를 사용해 병렬적 서치를 한다.
TLB 접근 시간 = ε
메모리 접근 시간 = 1
α는 대단히 1에 가까운 값을 가지고 있다.
(TLB를 통해 주소 변환이 이루어지는 확률) Hit ratio = α
(TLB를 통해 주소 변환이 이루어지지 않는 확률) TLB miss ration = 1-α
Effective Access Time(EAT)
EAT = (1+ε)ε + 2(+ε)(1-α) = 2+ε-α
✨ Structure of the Page Table
현대의 컴퓨터는 address space가 매우 큰 프로그램 지원
1. Two-level page talbe
→ page table과 메모리 사이에 page table을 하나 더 둠으로써 총 세번의 메모리 로드를 거치는 방법이다. 얼핏 듣기에는 2번을 로드하는 것 보다 안좋게 느껴질수 있다.
→ 하지만 100만개가 넘는 page table중 실제 사용되는 것은 정말 얼마 되지 않지만 기존은 전부 로드 했어야 됐다.
→ Two-level page table은 사용되지 않는 주소 공간에 대한 outer page table의 엔트리 값은 Null로 나타낸다(대응하는 inner page table이 없음)
→ 이를 통해 모든 page를 로드해야 하는 부담을 줄일 수 있다.
→ 기존에는 32 bit 논리적 주소 공간이라면, 20 bit는 page number, 12 bit는 page offset을 나타냈는데, Two-level인 경우, page table 자체가 page로 구성되기 때문에 page number는 10 bit의 page number와 10 bit의 page offset으로 또 나뉘게 된다.
→ 2단계 페이징에서의 Address-translation scheme
더 많은 메모리 접근이 필요하다면 이걸 사용할 필요가 있을까???
2. Inverted Page Table
물리적인 주소를 가지고 논리적인 주소를 얻어 내는 페이지 테이블(역방향으로 되어있다.)
page table은 각 page마다 하나의 항목을 가졌다. 반대로 Inverted page table은 메모리의 frame마다 한 항목씩 할당.
physical frame에 대응하는 항목만 저장하면 되므로 메모리를 훨씬 적게 사용한다. (장점)
각 page table entry는 각각의 메모리의 frame이 담고 있는 내용(PID, logical address)을 표시한다.
🏴 단점 : 테이블 전체를 탐색해야 하므로 시간이 오래 걸린다.(associative register 사용해서 문제해결 가능. 다만 비싸짐) 어떤 프로세스의 주소인지도 함께 가지고 있어야됨.
3. Shared Pages Example
똑같은 프로그램의 코드들이 중복해서 올라가는 것을 방지한다.
Shared code
✓ Re-entrant Code (=Pure code)
✓ read-only로 하여 프로세스 간에 하나의 code만 메모리에 올림
(eg, text editors, compilers, window systems).
✓ Shared code는 모든 프로세스가 logical address space(논리주소공간)을 가져야 된다.
Private code and data( Shared Code의 반대)
✓ 각 프로세스들은 독자적으로 메모리에 올림
✓ Private data는 logical address space의 아무 곳에 와도 무방
✨ Segmentation
프로그램은 의미 단위인 여러 개의 segment로 구성
✓ 작게는 프로그램을 구성하는 함수 하나하나를 세그먼트로 정의
✓ 크게는 프로그램 전체를 하나의 세그먼트로 정의 가능
일반적으로는 code, data, stack 부분이 하나씩의 세그먼트로 정의됨
Segment는 다음과 같은 logical unit 들임
main (),
function,
global variables,
stack,
symbol table, arrays
Logical address는 다음의 두 가지로 구성 : < segment-number, offset >
Segment table
✓ each table entry has :
base-starting physical address of the segment
limit-length of the segment
Segment-table base register (STBR)
✓ 물리적 메모리에서의 segment table의 위치(시작 위치)
Segment-table length register (STLR)
✓ 프로그램이 사용하는 segment의 개수 : segment number s is legal if s smaller then STLR
📌 Paging 기법과 시작위치만 담고 있는 것이 아니고 Segment의 길이(limit)를 가지고 있어야됨. paging에서는 크기가 다 똑같으니 가지고 있을 필요가 없었지만 Segmentation에서는 segment의 크기가 같지 않으므로 얼마만큼에 걸쳐 존재하는가를 담고 있어야됨.
프로세스가 5개의 세그먼트로 이루어진 예제
📌 Allocation 문제 : external fragmentation 발생
Segment의 길이가 동일하지 않으므로 가변분할 방식에서와 동일한 문제들이 발생.
ex) frist fit/ best fit 등의 방법 사용
📌 Protection : 각 세그먼트별로 protection bit가 있음.
Each entry :
Valid bit = 0 => illegal segment
Read/Write/Execution 권한 bit
📌 Sharing
💡 세그멘테이션은 코드와 데이터의 논리적 구성을 더 잘 지원하고 세그먼트 사이를 Protection하는 것과 같은 이점이 있지만 단순성, 조각화 방지 및 하드웨어 지원 측면에서 페이징의 이점으로 인해 페이징 기법이 지배적인 기술이 되었다.
현대 시스템에서는 세그먼테이션과 페이징의 조합을 사용하여 두 기술의 장점을 결합
공유나 보안 문제는 Segment로 해결. Allocation의 external fragmentation은 Paging단위로 올라가기에 발생하지 않음.