본문 바로가기

컴퓨터공학

가상메모리.페이지2

페이지에 대해 살펴보았다.
이번에는 가상메모리 주소에 대해 알아본다.

sw를 빌드하면 sw의 코드,데이터들은 메모리주소를 부여받게 되고. 32bit 시스템의 경우 하나의 sw는 최대 4Gb의 어드레스 공간을 갖게된다.

그런데, 이 4Gb의 어드레스공간은
모든 sw가 다같이 공유하는 주소공간이 아니라
각각의 sw마다 제각각 갖고 있는 공간이다.

그러니까 예를 들어 abc.exe 라는 sw가 0x100번지에 fun1이라는 함수를 정의해놓고,

abcd.exe 파일은 0x100번지에 int a 라는 변수를 집어넣는것이 가능하다.

왜냐면 여기서 말하는 0x100번지는 실제 컴퓨터에 꽂혀있는 하드웨어 메모리의 물리적주소(Physical address) 를 의미하는게 아니라
sw마다 각자 4Gb씩 갖고있는 가상주소이기 때문이다.

참고로 Physical메모리는 오직 하나의 주소만 존재할 수 있다.
따라서 Physical address 0x100번지에 fun1 함수와 int a 변수를 동시에 할당하는것은 불가하다.

 

자 그렇다면. 멀티 프로세싱에서는 여러개의 프로세스를 동시에 ram에 올려두고 실행할 수 있다고 했는데 어떻게 그게 가능할까?
abc.exe 와 abcd.exe 가 모두 0x100 번지에 서로다른 정보를 담고있는데 어떻게 이게 가능할까?

그 비밀은 바로. 어드레스 맵핑이라는 작업을 통해서 해결된다.

 

앞에서 우리는 페이지기법에 대해배웠다. 그리고 로더에 대해서도 배웠다.
로더는 현재 메모리의 페이지프레임 중에서 비어있는공간에 sw의 페이지를 복사해서 옮긴다.

이때, 만약 abc.exe에 정의된 0x100번지의 fun함수가 실제로는 physical address 0x700번지에 할당됐다고 생각해보자.

그리고 abcd.exe에 정의된 0x100번지의 int a는
실제로 physical address 0x1500번지에 할당됐다고 생각해보자

그리고나서 cpu가 abc.exe 코드를 실행하는과정에서 0x100번지의 func1로 jump하는 명령을 수행하는 상황을 생각해보자.
abc.exe 파일에는 call 0x100 이라고 쓰여있을것이다. 그런데 로더가 sw를 메모리에 옮겨담을때. fun1은 0x100번지가 아니라 0x700번지에 담아놓은 상황이다. 그러므로 만약 cpu가 코드에 쓰여있는 그대로 0x100번지로 점프를 해버리면 이상한 동작을 하게 될 것이다.

여기서 바로 어드레스 맵핑. 작업이 이루어져야한다.
sw코드는 call 0x100 이지만
실제로 메모리에 접근할때는 0x700으로 점프하도록 치환해주는것! 이것이 바로 어드레스 맵핑이다.

이것을 어떻게 구현할 수 있을까?
간단한 예시를 생각해보자.
로더가 abc.exe를 메모리에 옮겨담을때, 0x100번지의 fun1을 0x700번지에 옮겼다는 사실을 로더는 알고있다.

그러므로, 테이블 형태의 자료구조를 만들어두고,
로더가 fun1을 쓸때
fun1(0x100)은 0x700에 옮겼어. 라고 테이블에 적어둔다.

그리고나서, 이제 코드가 실행될때 call 0x100을 만나면 그대로 실행하는게 아니라 아까 적어둔 테이블에서 0x100번지가 실제 메모리 어디에 옮겼는지를 찾아본다.
아까 적어둔 정보를 바탕으로 0x100이 0x700으로 치환되야한다는 사실을 알 수 있다.

그런데 이런 작업을 코드를 한번 실행할 때마다 매번해야한다. 생각해보면 오버헤드가 엄청나다.
코드를 한줄 실행할 때마다 해당 코드가 실제메모리 어디에 맵핑됐는지 서치하고 그걸로 치환까지 해서 접근해야되기 때문이다.

그래서, 이러한 가상주소 프로세스를 sw로 구현하려면 TLB(Memory Management Unit)라고 하는 Hw의 지원이 필수적이다.

TLB는 캐쉬의 일종인데,
메모리 맵핑정보를 갖고 있는 캐쉬이다.
그래서 아까의 예시로 돌아오면,
call 0x100을 호출했을때 처음에는 Tlb cache miss가 발생해서 테이블을 서치해서
0x100 -> 0x700으로 sw로 치환하고. 그러면 이 정보가 Tlb cache에 쓰이게된다.
그러면 그 뒤에 다시 call 0x100을 만나면 sw가 테이블을 뒤져볼 필요 없이 Tlb cache를 보고 자동으로 call 0x700으로 치환해준다.
따라서 오버헤드가 매우 줄어들게 된다.
이러한 TLb 가 없다면 명령 한줄한줄 실행할 때마다 오버헤드가 너무커서 사실상 가상메모리 시스템.멀티프로세스 시스템은 사용할 수 없다고 봐야한다.

'컴퓨터공학' 카테고리의 다른 글

로더.가상메모리.페이지.세그멘테이션  (0) 2020.08.31
dll 파일. 다이나믹 링킹  (0) 2020.08.30
로더  (0) 2020.08.30
컴파일.어셈블.링커(빌드)  (0) 2020.08.30