메인 메모리(Main Memory)

By 01/10/2018OS Concept

메인 메모리(Main Memory)

 

CPU는 PC(Program Counter)가 지시 하는대로 메인 메모리로부터 다음 수행할 명령어를 가져오는데 그 명령어는 필요한 경우 추가적인 자료를 더 가져올 수 있으며 반대로 자료를 메모리로 내보낼 수도 있다.

 

메인 메모리와 CPU에 내장되어 있는 레지스터들은 CPU가 직접 접근할 수 있는 유일한 저장 장치이다. 모든 실행되는 명령어와 자료들은 CPU가 직접 접근할 수 있는 메인 메모리와 레지스터에 있어야 한다. 만약 자료가 메모리에 없다면 CPU가 처리하기 전에 메모리로 이동(Load)해야 한다.

 

레지스터들은 일반적으로 CPU클록(clock)의 1사이트(cycle)내에 접근이 가능하지만 메인 메모리의 경우 많은 CPU 클록 및 사이클이 소요되어 CPU가 필요한 자료가 없어서 명령을 수행하지 못하는 지연(stall)되는 현상이 발생하기도 한다.  이러한 지연 현상을 해결하기 위해 캐시(cache)라 부르는 메모리 버퍼가 사용된다.

 

프로세스들은 독립된 메모리 공간을 갖는다. 각 프로세스는 합법적인(legal) 메모리 주소 영역을 설정하고 접근하는데 가장 작은 합리적인 물리 주소의 값을 가진 베이스 레지스터, 주어진 영역의 크기를 저장하는 상한 레지스터를 이용하여 메모리를 보호 한다.

 

메모리 공간 보호는 CPU 하드웨어가 사용자 모드에서 만들어진 모든 주소와 레지스터를 비교함으로써 이루어진다. 사용자 프로그램이 운영체제 메모리 공간이나 다른 응용 프로그램 공간의 접근이 일어나면 오류로 간주하여 트랩(trap)을 발생 시킨다.

 

베이스와 상한 레지스터는 여러 가지 특권 명령(privileged instruction)을 사용하는 운영체제에 의해서만 적재 된다. 특권 명령은 오직 커널 모드에서만 수행되고 운영체제만 커널 모드에서 수행되기 때문이다.

 

운영체제는 사용자 프로그램을 사용자 메모리 영역에 적재하고 에러가 발생한 경우에 그 프로그램을 덤프(dump out)하고 시스템 호출(system call)의 매개변수(parameter) 값을 변경하는 것과 같은 일들을 수행 할 수 있다.

 

 

[주소의 할당 (Address Binding)]

프로그램이 실행되기 위해서는 메모리에 적재되어야 한다고 했다. 프로세스가 종료되면 이전 프로세스가 사용했던 기억 공간이 가용(available) 공간이 되며 다른 프로세스를 위해 사용 된다. 대부분의 시스템은 사용자 프로세스가 메모리 내 어느 부분으로도 올라올 수 있도록 지원하고 있다.

 

메모리 주소 공간에서 명령어와 자료의 바인딩은 이루어지는 시점에서 다음과 같이 구분 된다.

  • 컴파일 시간(compile time) 바인딩 : 프로세스가 메모리 내에 들어갈 위치를 컴파일 시간에 미리 알 수 있으면 컴파일러는 절대 코드를 생성할 수 있다. 그러나 위치가 변경되어야 한다면 이 코드는 다시 컴파일 되어야 한다.
  • 적재 시간(Load time) 바인딩 : 메모리 내의 어느 위치로 올라오게 될지를 컴파일 시점에서 알지 못하면 컴파일러는 일단 이진 코드를 재배치 가능 코드로 만든다. 이 경우 심볼과 진짜 번지수와의 바인딩은 프로그램이 메인 메모리로 실제 적재되는 시간에 이루어지게 된다. 재배치 가능 코드는 주소가 바뀌어도 코드를 다시 적재만 하면 된다.
  • 실행 시간(Execution Time) 바인딩 : 프로세스가 실행 중간에 메모리 내의 다른 세그먼트로 옮겨질 수 있다면 이를 “바인딩이 실행 시간까지 허용되었다” 라고 한다.

 

 

[논리 대 물리 주소 공간(Logical Versus Physical Address Space)]

CPU가 생성하는 주소를 일반적으로 논리 주소(Logical Address)라 하며 반면에 메모리가 취급하게 되는 주소(MAR)는 물리 주소(Physical address)라 한다.

 

컴파일 시 바인딩과 적재 시 바인딩 기법 경우에는 논리, 물리 주소가 같다. 그러나 실행 바인딩 기법에서는 논리, 물리 주소가 다르다. 이 경우 논리 주소를 가상 주소(virtual address)라 한다.

 

프로그램에 의해 생성된 모든 논리 주소 집합을 논리 주소 공간(logical address space)이라 하며 이 논리 주소와 일치하는 물리 주소 집합을 물리 주소 공간(physical address space)이라 한다. 프로그램의 실행 중에는 이와 같은 가상 주소를 물리 주소로 바꾸어줘야 하는데 이 변환(mapping) 작업은 하드웨어 장치인 메모리 관리기 (MMU(Memory Management Unit))에 의해 실행 된다.

 

사용자 프로그램은 실제적인 물리 주소를 알 수 없기 때문에 베이스 레지스터에 대해 다시 바인딩 된다. 이때 베이스 레지스터를 재배치(relocation) 레지스터라 한다. 사용자 프로그램의 논리적 주소를 메모리의 물리적 주소로 바꾸는 것이다.

 

메모리 주소는 논리적 주소(0~max)와 물리적 주소(기준값 R에 대해 R+1 ~ R+max)가 있다는 것에 유의해야 한다. 이처럼 메모리의 주소 공간이 논리 주소 공간과 물리 주소 공간이 분리된다는 개념은 매우 중요하다.

 

[동적 적재(Dynamic Loading)]

프로세스가 실행되기 위해 프로그램 전부와 프로세스의 모든 자료가 메모리에 올라와 있어야 한다. 이 경우 프로그램은 메모리의 크기보다 클 수는 없다. 이런 단점을 보완하기 위해 동적 적재(Dynamic Loading)를 사용한다.

 

동적 적재(Dynamic Loading)는 각 루틴이 실제 호출되기 전까지는 메모리에 올라오지 않고 재배치 가능한 상태로 디스크에서 대기하고 있으며 먼저 주 프로그램이 메모리에 올라와 실행된다. 이 루틴이 다른 루틴을 호출하게 되면 호출 된 루틴이 이미 메모리에 적재 되어 있는지를 조사하여 적재되어 있지 않다면 재배치 가능 연결 적재기(relocatable linking loader)를 호출하여 요구된 루틴을 메모리로 가져오고 이러한 변화를 테이블에 기록한다. 그 후 CPU제어는 중단되었던 루틴으로 보내진다.

 

동적 적재의 장점은 사용되지 않는 루틴들의 경우 미리 적재 되지 않는다는 것이며 많은 양의 코드를 필요로 할 때 유용하다. 전체 프로그램이 클지라도 실제 사용되는 부분은 훨씬 작을 수 있다.

 

 

[동적 연결 및 공유 라이브러리 (Dynamic Linking & Shared library)]

동적 적재에서는 적재가 실행시 까지 미루어 졌다면 동적 연결에서는 연결(linking)이 실행 시 까지 미루어지는 것이다. 동적 연결은 주로 시스템 라이브러리에 사용 된다.

 

동적 연결에서는 라이브러리를 부르는 곳마다 스텁(stub)이 생긴다, 이 스텁은 그 라이브러리를 어떻게 찾을 것인가를 알려주는 작은 코드 조각이다. 스텁은 필요한 라이브러리 루틴이 이미 메모리에 존재하는가를 검사하여 없으면 디스크에서 가져온다.

 

동적 연결은 라이브러리 루틴을 바꿀 때 특히 유용하다. 라이브러리는 어느 때나 새로운 버전으로 교체될 수 있고 그렇게 되면 그 라이브러리를 사용하는 모든 프로그램은 자동적으로 이 새로운 라이브러리 버전을 사용하게 될 것이다.

 

여러 버전의 라이브러리들이 시스템에 존재할 수도 있기 때문에 각 프로그램은 라이브러리의 어느 저번을 사용해야 할지를 가려내기 위해 이러한 버전정보를 이용한다. 이러한 시스템을 공유라이브러리라 한다.

 

동적 적재와 달리 동적 연결은 일반적으로 운영체제의 도움이 필요하다. 메모리에 있는 프로세스들이 각자의 공간은 가지만 접근할 수 있도록 보호된다면 운영체제만이 기억공간에 루틴이 있는지 검사해 줄 수 있고 운영체제만이 여러 프로세스들로 하여금 같은 메모리 주소를 공용할 수 있도록 해줄 수 있다.

 

 

[참고자료]

Operating System Concepts / 홍릉과학출판사

 

operation system, 운영체제, 운영체제구조, 컴퓨터구조, OS Concept, 메인 메모리, 주메모리, 레지스터, 메모리 주소 할당, 동적로딩, sqlmvp, SQL Angeles

 

Leave a Reply