프로세스 - 논리적 주소, 메모리 - 물리적 주소주소 변환 또는 주소 바인딩이라고 한다.프로그래밍 - Symbolic address, 컴파일 - Logical address, 실행 - 주소 변환
- Compile time binding : 이제 이것이 실행이 되려면 메모리의 물리적인 주소로 올라가야 하고 이것을 주소 바인딩이라고 한다고 했다. 아까 전에 설명했던 Compile time binding은 앞서 논리적 주소라고 했던 숫자가 사실은 물리적 주소가 되는 것이다. 그렇기 때문에 컴파일러가 만들어 낸 코드는 절대 코드(absolute code)라고 불린다. 그래서 메모리에 올리고 싶은 위치를 바꾸고 싶으면 컴파일을 다시 해야 한다. 그러나 이 방법으로 주소 바인딩을 하는 것은, 뒤에 있는 주소들은 비었음에도 불구하고 0번지에 있는 주소부터 결정되기 때문에 비효율적인 방법이다. 옛날처럼 컴퓨터에서 하나의 프로그램만 실행할 수 있었던 경우에는 썼으나 최근 컴퓨터 시스템에서는 쓰지 않는다.
- Load time binding : 실행을 시작할 때 물리적 주소가 결정되는 방법이다. 메모리를 봤더니 500번지가 비어있으니 500번지에다가 논리적 주소 0번지부터 차례대로 올리라는 뜻이다. 컴파일러가 만들어낸 코드의 논리적 주소가 메모리 상황에 따라 바뀔 수 있기 때문에 컴파일러가 재배치 가능 코드(relocatable code)를 생성해야 한다.
- Run time binding : Load time binding과 비슷하게 실행 시 물리적 주소가 결정된다. 그러나 이 프로세스가 메모리에서 쫓겨났다가 다시 들어올 수도 있기 때문에 주소들이 실행 도중 바뀔 수 있게 된다.(Swapping) 이것이 Run time binding이다. 따라서 이 방법을 사용하면 CPU가 해당 프로세스의 주소를 참조할 때마다 binding을 Address mapping table을 이용하여 점검해야 하며 이를 위해 하드웨어적인 지원이 필요하다. 이때 사용되는 것이 MMU(Memory Management Unit) 혹은 base and limit register이다.

Run time binding을 이야기할 때 나왔던 장치. MMU는 Logical address를 Physical address로 매핑해주는 Hardware device.
MMU에서 주소 변환을 하는 방법은 기본적으로 레지스터 2개를 이용.



Linking을 실행 시간(Execution time)까지 미루는 기법. 프로그램을 작성하고 컴파일을 하면 목적 파일이 생성된다. 링킹이란 여러 군데 존재하는 목적 파일들을 묶어서 하나의 실행 파일을 만드는 과정을 뜻한다. 이때 필요한 라이브러리들이 실행 파일에 전부 포함되어 만들어지는데 이것을 Static Linking이라고 한다. 즉, 라이브러리가 프로그램 실행 파일 코드에 포함되고 이에 따라 실행 파일 크기가 커진다. 그러나 이 경우 동일한 라이브러리를 각각의 프로세스 메모리에 전부 올리기 때문에 메모리 낭비가 심하다. iostream이나 stdio.h와 같은 필수적인 라이브러리들은 중복으로 올라가게 될 것이기 때문이다.
반면 Dynamic Linking은 실행 파일에 라이브러리들을 포함시키는 것이 아니라 프로그램 실행 시에 라이브러리를 호출하는 곳에 도달했을 때 라이브러리를 연결하는 방법이다. 이때 라이브러리 호출 부분에 라이브러리 루틴의 위치를 찾기 위한 stub이라는 작은 코드를 둔다. 일종의 pointer 역할이다. 이때 라이브러리를 메모리에 올리게 되는데 만약 메모리에 해당 라이브러리가 이미 있다면 그 루틴의 주소로 가고, 메모리에 없다면 디스크에서 읽어오게 된다. 따라서 Dynamic Linking을 사용한다면 운영체제의 도움이 반드시 필요하다. 이 Dynamic Linking을 해주는 라이브러리를 Shared Library라고 부른다. 리눅스에서는 Shared Object, 윈도우에서는 dll이다.
메모리에서 낮은 물리 주소에는 운영체제 커널이 상주하고 높은 물리 주소 영역에는 사용자 프로세스 영역이 올라간다.
- External fragmentation (외부 조각) : 프로그램 크기보다 분할의 크기가 작아서 다른 분할로 들어가야 할 때 분할 한 개가 통째로 비어버리는 상황이 발생할 수 있다.
- Internal fragmentation (내부 조각) : 프로그램 크기보다 분할의 크기가 큰 경우 생기는 조각을 말한다.
- Variable partition allocation(가변 분할 방식) : 가변 분할 방식은 굳이 분할의 크기를 나누어 놓을 필요가 있겠는가 하는 의문에서 나왔다. 따라서 가변 분할 방식은 프로그램이 실행될 때마다 메모리에 차곡차곡 로드하는 방법이다. 그런데 만약 밑의 예시에서 프로그램 B가 끝나고 프로그램 D가 수행되는데 B가 들어갔던 공간이 작기 때문에 그 공간에 들어가지 못하고 아래쪽에 들어가게 된다. 따라서 가변 분할 방식에서는 내부 조각 문제는 발생하지 않지만 고정 분할 방식과 비슷하게 외부 조각 문제는 발생할 수 있다.

- First-fit : Size가 n이상인 hole 중에 처음으로 찾아지는 hole에 집어넣는다.
- Best-fit : Size가 n이상인 hole 중 가장 작은 hole에 할당을 하는 것이다. 그러나 hole들의 리스트가 크기 순으로 정렬되지 않았다면 모든 hole을 다 탐색해야 하며 많은 수의 아주 작은 hole들이 생성될 수 있다.
- Worst-fit : Size가 n이상인 hole 중 가장 큰 hole에 할당하며 이 역시 모든 hole을 다 탐색해야 하고, Best-fit과는 반대로 상대적으로 큰 hole이 생성된다.
기존에 연속 할당에서는 MMU의 register 두 개를 이용하여 주소 변환을 했다. 일반적으로 페이지 하나의 크기는 4KB이다보니 한 프로세스의 주소 공간을 페이지로 나누면 상당히 큰 숫자의 Page Table Entry가 필요하다. 그 큰 Entry들이 register안에 들어가지는 못할 것이다. 게다가 프로세스마다 Page Table이 별도로 존재해야 한다. 그렇다고 메모리 접근을 위한 주소 변환인데 어디 하드 디스크에 넣어둘 수도 없다. 또 캐시 메모리에 들어가기에도 Page Table들의 용량이 너무 크다. 따라서 Page Table을 메모리에다가 집어넣게 된다.
즉 Page Table은 main memory에 상주하게 되고, 앞서 MMU의 relocation register와 limit register는 Page Table을 가리키는 Page-table base register(PTBR)와 테이블의 크기를 보관하는 Page-table length register(PTLR)가 된다. 이러한 이유로 Paging 기법에서는 모든 메모리 접근 연산에는 2번의 memory access가 필요하다.
Associative register lookup time = ε ( < 1)
memory cycle time = 1
Hit ratio = α (Associative register에서 찾아지는 비율)
EAT = (Associative register lookup time + memory cicle time) * Hit ratio + // 적다가 만 부분. 강의 들으면서 채우면 된다.
EAT = (1 + ε)*α + ( 2 + ε)*(1 - α) = 2 + ε - α
따라서 Page Table만 있을 때 걸리는 시간 2보다는 2 + ε - α가 훨씬 짧다.
Page Table은 2단계로 존재할 수 있다. 여기서는 Outer-page table과 inner-page table이 있다. 페이지 테이블을 위한 공간이 줄어드는 것 때문에 2단계 페이지 테이블을 사용하는 것이다.
현대 컴퓨터는 Address space가 매우 큰 프로그램을 지원한다. 32 bit address를 사용한다면 2^32B (4GB)의 주소 공간을 표현할 수 있는데 Page size가 4KB이면 1M(1,048,576)개의 Page table entry가 필요하며, Page Entry 한 개의 크기가 4B 정도이기 때문에, 프로세스마다 4MB의 Page Table이 필요하게 된다. 그러나 대부분의 프로그램은 4GB의 주소 공간 중 일부분만 사용하기 때문에 Page Table 공간이 심하게 낭비된다. 이를 해결하고자 등장한 것이 2단계 페이지 테이블이다.
한 페이지에서 나타날 수 있는 변위는 최대 4KB이고 4K는 2^12이기 때문에 Offset을 나타내기 위해서는 12bit가 필요하다. 그리고 우리는 방금 Inner-Page Table에 Entry가 1K가 있다는 것을 알았다. 따라서 Inner-Page Table에서는 2^10의 서로 다른 Entry위치를 구분하기 위해 10bit가 필요하다. Outer-Page Table과 Inner-Page Table은 자연스럽게 10bit가 필요할 것이다.

===