티스토리 뷰

Logical vs. Physical Address

Logical address

  • 프로세스마다 독립적으로 가지는 주소공간.
  • 각 프로세스마다 0번지부터 시작한다.
  • CPU가 보는 주소는 logical address이다.

Physical address

  • 메모리에 실제로(물리적 공간) 올라가는 위치

Q. 주소 바인딩이란?

A. 주소를 결정하는 것

  • Symbolic Address -> Logical Address - ... (이때가 언제일까?) ... -> Physical Address

symbolic Address란?

  • 함수나 변수값으로 메모리를 사용하는 것을 symbolic address라 한다. 컴파일이 되면 해당 메모리가 프로세스의 논리적 메모리 주소로 변환이 되고, 이를 실제 물리적 메모리 주소로 변환해서 처리하게 된다

주소 바인딩 (Address Binding)

1) Compile time binding

  • 물리적 메모리 주소가 컴파일 시 정해지는 경우.
  • 시작 위치 변경이 필요하면 재컴파일해야 한다.
  • 컴파일러는 절대 코드(absolute code)를 생성한다.

Q. 절대코드 (absolute code)란?

A. 컴파일시 정해진 논리적 주소가 실제 물리적 주소로 고정되므로, 원하는 메모리 주소에 올리고 싶으면 컴파일 자체를 새로해야한다.
한번 컴파일 된 메모리 주소는 절대적이라 바꿀수 없다는 개념이다.

2) Load time binding

  • 실행이 시작될 때 변환되는 경우.
  • Loader의 책임하에 물리적 메모리 주소 부여한다. (실행시 빈 곳을 찾아서 정해줌)
  • 컴파일러가 재배치 가능한 코드(relocatable code)를 생성한 경우에 가능하다.

3) Execution time Binding (Run time binding)

  • 실행이 시작 된 이후에도 프로세스의 메모리 위치가 변경되는 경우
  • CPU가 주소를 참조할 때마다 binding을 점검해줘야 한다. (물리적 메모리가 바뀌어있을수 있으므로)
  • address mapping table 확인이 매번 필요하다.
  • 하드웨어적인 지원이 필요하다 (하드웨어 MMU를 이용하기 위해서)

형태

  1. 소스코드의 symbolic address가 컴파일이 되어서 실행파일에서 logical address로 변환된다.
  2. Binding을 통해 Logical Address를 Phisical Address로 매핑한다.

Compile time binding

  • 이미 컴파일 때 물리적 메모리 주소로 변환되므로, 컴파일에 존재하는 주소를 그대로 사용한다.
  • 컴파일 때 정해진 주소가 실제 물리적 주소로 사용되야하므로 여러 프로그램을 돌리는 경우 매우 비효율적이므로 사용하지 않는다.
    옛날에 프로그램을 하나씩만 올릴 때에 사용하던 방식이다.

Load time binding

  • 프로그램을 실행할 때, 물리적 주소가 정해지는 방식이다. 실행할 때 물리적 주소를 확인해보고 비어있는 곳을 찾아서 해당 주소로 변환하게 된다.

Run time binding

  • Load time binding과 동일하게 프로그램이 시작될 때, 물리적 주소를 갖게된다.
    하지만 실행되는 도중에 물리적 메모리 주소가 변경될 수 있다. 그림에서는 300번지에서 실행되다가 쫒겨나서 700번지에서 실행되는 모습이다.
  • 메모리가 부족해서 Swap-area로 쫓겨나거나 다시 들어올 때 제자리로 돌아올 필요가 없으니 관리하기가 좋다. 대신 항상 주소가 달라지므로 연산 때마다 논리적메모리를 계산해서 실 주소를 찾아줘야 한다.

Q. CPU가 프로그램을 Instruction을 수행할 때 보는 주소는 Logical? Physical?

A. 소스코드를 컴파일해서 생성된 실행파일에서 symbolic 주소는 logical 주소로 변환되어 있다. 이런 변수 및 함수의 호출 주소는 physical 주소로 instruction을 변환해서 보더라도 logical 주소가 유지되어있다.

따라서 최종적으로 physical address로 바뀐 후라도 cpu는 Logical address를 보면서 물리적 주소로 변환해서 instruction을 수행하게 된다.

Run time binding을 위한 하드웨어적 지원 MMU (Memory Management Unit)

MMU (Memory Management Unit)

  • Logical address를 Physical address로 매핑해주는 하드웨어 Device
  • 레지스터 두개를 이용해서 주소변환을 하게 된다 (Relocation(Base) register, Limit register)

MMU scheme

  • 사용자 프로세스가 CPU에서 수행되며 생성해내는 모든 주소값에 대해 base register(relocation register)의 값을 더한다.

User program

  • logical address만을 다루며, 실제 physical 주소는 볼 수도 없고 알 필요도 없다. 물리적 주소에 대한 접근은 MMU가 알아서 처리한다.

Dynamic Relocation

로직

  • relocation register, limit register 2개를 사용해서 MMU가 논리적 주소를 물리적 주소로 바꿔준다.

Relocation Register(base register) 역활

  • MMU는 프로그램이 요청하는 logical address에 자신이 갖고있는 (물리적 메모리의 시작 주소)를 더한 물리적 주소를 반환한다. physical Address의 시작 주소의 값은 relocation Register가 갖고있다.
  • 위에서 프로그램의 instruction이 논리적 주소상 346번지를 요청했으므로, MMU가 relocation 레지스터의 값 14000을 더해서 실제 물리적 주소상 14346번지를 가리키게 되는 경우이다.

Limit Register 역활

  • Limit register가 갖는 값은 해당 프로세스가 갖는 최대 메모리 크기이고 그 이상의 접근을 제한한다.
  • 만약 해당 프로그램이 악의적인 의도가 있는 프로그램의 경우 자신의 최대 메모리 위치를 벗어나는 위치를 요청할 수 있다. 따라서  요청 주소가 MAX 메모리 주소보다 작은지 확인하고 넘을 경우 Trap을 발생시켜서 해당 프로그램을 종료시켜버린다.

프로세스의 논리적 주소 instruction 처리 절차

  • 요청 메모리가 최대 범위를 넘는지 확인한다. 넘을 경우 trap()을 일으키고 프로그램을 종료시킨다.
  • 제대로된 주소를 요청하고 있다면 실제로 relocation register의 값을 더해서 해당 물리적 메모리 주소에 접근한다.

용어 설명

Dynamic Loading

  • 프로세스 전체를 메모리에 미리 다 올리는 것이 아니라 해당 루틴이 불려질 때 메모리에 load하는 것이다.
  • Memory utilzation의 향상이 있을 수 있다.
  • 가끔씩 사용되지만 코드의 양이 많은 경우에 유용하다.
  • 운영체제의 특별한 지원없이 프로그램 자체에서 구현하는 방법이다. (라이브러리를 사용해서 구현)

예시

  • 오류 처리를 위한 루틴이 있을 수 있다. 모든 코드에 대해 다양한 테스트코드가 돌아가므로 많은 코드량이 있으므로 항상 메모리에 올려놓으면 메모리에 부담을 줄 수 있다. 따라서 테스트가 실행 될 때만 메모리에 적재하고 그외에는 Swap Area 또는 저장공간에 놔두는 방식을 취한다.

참고로 앞에서 배웠던 운영체제가 실행하는 프로세스의 일정 부분을 메모리에 올리고 swap area에 내려놓고 하는 Swapping은 OS가 직접 paging기법을 이용해서 구현하는 것으로 dynamic loading과는 구별되어야 한다. 의도는 같지만 주체자에서 차이가 있다.

Overlays

  • 메모리에 프로세스의 부분 중 지금 필요한 정보만을 올린다.
  • 프로세스의 크기가 메모리보다 클 때 유용한 방법.
  • 운영체제의 지원없이 사용자에 의해 구현된다.
  • 작은 공간의 메모리를 사용하던 초창기 시스템에서 수작업으로 프로그래머가 구현한 방법이다.

Q. Dynamic Loading과 Overlays의 차이점은?

Overlays는 총 메모리가 워낙 작아서 프로그램 하나 조차도 전부 올릴 수 없던 시기에 프로세스를 쪼개서 프로그래머가 직접 구현한 대로 특정 부분만을 메모리에 올리고 내리는 것을 구현한 방법이다.

Dynamic Loading은 메모리를 효율적으로 사용하기 위해 메모리 공간을 너무 많이 차지하는 코드 부분을 미리 전부 올리지 않고 필요할 때 해당 부분을 메모리에 올리는 방법이다.

Swapping

프로세스를 일시적으로 메모리에서 backing store(Swap Area)로 쫒아내는 것.

 

Swap in / Swap out

  • 일반적으로 중기 스케줄러(Swapper)에 의해서 swap out 시킬 프로세스를 선정한다.
  • priority based CPU sheduling algorithm 적용
  • priority가 낮은 프로세스를 swapped out 하고, priority가 높은 프로세스를 swapped in한다.

물리 메모리 바인딩 기법에 따른 차이

  • Compile Time binding, Load Time binding 방식에서는 원래 메모리 위치로 swap in 해야한다.
    (메모리 주소가 바뀌면 이를 알지 못하므로, 기존 메모리 위치를 지켜야한다.)
  • Execution(Run) Time binding 방식에서는 아무 빈 메모리 주소에 swap in 해도된다.
    (어짜피 MMU가 실행할 때마다 물리적 메모리 주소를 계산해서 알려준다.)
  • swap time은 대부분 transfer time으로, 실제 swap 되는 양에 비례하는 시간이다.
    (하드디스크 기준 대부분의 시간은 헤더가 움직이는 시간이 대부분이지만 이동할 데이터 양이 방대한 경우 의미있는 영향을 준다.)

Dynamic Linking

Linking이란?

  • 프로그램을 작성하고 compile하고 link에서 실행파일을 만들게 된다. 이때 linking은 컴파일된 파일들을 묶어서 하나의 실행파일을 만드는 것.

Static Linking

  • 라이브러리 코드가 프로그램의 실행 파일코드에 포함된 경우이다.
  • 실행파일의 크기가 커진다 .
  • 동일한 라이브러리를 각각의 프로세스가 메모리에 올리게 되므로 메모리가 낭비된다. 예를들어서 여러 파일들에 존재하는 "printf함수의 라이브러리코드" 를 호출하기 위해 동일 라이브러리 임에도 각각의 프로세스가 메모리에 올리게 된다.

Dynamic Linking

  • 라이브러리가 실행시 연결(link)된다.
  • 실행파일에 라이브러리 코드를 넣지 않는다.
  • 별도의 라이브러리 파일이 존재하고, 실행파일에는 해당 파일의 위치를 나타내는 코드만 넣게 된다.
    (라이브러리 호출 부분에 STUB 이라는 작은 코드를 넣음)
  • 라이브러리가 이미 메모리에 있으면 그 루틴의 주소로 가고, 없으면 그때 디스크에서 읽어와서 메모리에 올려논다. 따라서 중복적으로 라이브러리 코드가 올라가지 않는다. -> 메모리를 아낄 수 있다.
  • 운영체제의 도움이 필요하다
반응형
Comments
반응형
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday