컴퓨터(Computer Science)/컴퓨터구조(Computer Arichitecture)

컴퓨터 구조에서 본 가상메모리, Virtual memory - 기본 개념 [컴퓨터구조]

게임이 더 좋아 2020. 6. 1. 21:50
반응형
728x170

 

가상 메모리는

참 많이 들었을 것이다.

 

왜 RAM이 가상메모리지?? 왜 사람들이 그렇게 말하는 거지?? 운영체제에서 배운 가상메모리랑 같은 개념인가?

뭐지??

 

이제부터알아보자

 


 

 

 

우리가 알고 있는 Main memory, 즉, DRAM을 캐시로써 사용한다는 개념이다.

즉, 다시 말해서 메인 메모리가 Secondary 메모리의 캐시 역할을 한다는 뜻이다.

 

특징을 보면

프로그램들은 메인 메모리를 공유한다.

 

메인 메모리를 사용할 때, (MMU, memory management unit 이 이용)

 

각각의 프로그램들은 자신만의 virtual address space 를 갖게 된다.

해당 space에 프로그램에 대한 code, data가 담겨있는 것이다.

또한 다른 프로그램의 접근을 제한한다. 

 

이러한 가상 메모리는 실제 메모리 주소와 다르므로

가상 메모리를 사용할 때 실제 메모리로 바꿔주는 작업이 필요하다.

CPU, OS에선 가상메모리를 사용하지만 실제로 사용 시에는 실제 메모리로 계산되어 사용된다.

 

가상 메모리 또한 블럭 단위로 사용되는데 우리는 이것을 page라 부른다.

또한 가상 메모리의 misspage fault라고 부른다.

 


 

아니 뭐 캐시로 사용하는 것은 알겠는데

왜 그렇게 해야하는데?

 

 

가상 메모리의 이점과 목적을 알아야 잘 이해가 될 것이다.

 

메인 메모리가 커진다는 생각(프로그래머 입장에서)

Memory protection

Data sharing

 

 

우선

가상메모리는 실제로 더 많은 메인 메모리가 있다고 생각하게 만든다.

다수의 프로그램을 동시에 수행할 때 메모리를 효과적으로 공유할 수 있기 때문이다.

다수의 프로그램을 한꺼번에 올려놓고 사용할 수 있다.

 

예를 들어 다수의 가상 머신이 같은 메모리를 사용하는 경우를 보자

가상 머신이 각자 보호될 수 있도록 보장하고

각 프로그램은 자신에게 할당된 메인 메모리의 부분에만 읽고 쓸 수 있도록 보장해야 제대로 돌아갈 것이다.

** 가상 메모리가 그것을 가능케 해준다.

 

프로그램을 컴파일할 때는 가상 머신이 다른 어떤 가상 머신과 메모리를 공유할 지는 알 수 없다. 

실제로 메모리를 공유하는 가상 머신은 가상 머신들이 수행되는 동안 동적으로 변한다.

 

이러한 동적 상호작용 때문에 각 프로그램들이 자신만의 주소 공간(address space)

즉, 이 프로그램에 의해서만 접근 가능한 분리된 메모리 영역에서 컴파일 되어야 한다.

++그렇지 않으면 데이터 무결성에 문제가 될 수 있겠지??

 

**가상 메모리는 프로그램의 주소 공간을 실제 주소(physical address) 로 변환시켜준다.

Data Protection을 가능케하고 이것은 프로세서를 공유하는 여러 프로그램들이

프로세서, 메모리, 입출력장치는 공유하지만 서로 간섭하지 않게 하는 것이다.

(OS가 처리한다)

 

 

 

다음으로는 사용자 프로그램이 메인 메모리보다 더 커질 수 있게 해주는 데 있다.

 

프로그램이 메인 메모리 할당 공간보다 클 경우 프로그램을 줄이던가 조각(fragment)으로 나눠야 했다.

**여기서 말하는 것은 연속적으로 메모리를 할당했을 때 크다는 것(실제로 메인 메모리보다 큰 것이 아니다)

 

그렇지만 가상메모리는 다르게 해결한다.

 

가상 메모리 블록은 페이지(page)라고 한다.

가상 메모리 실패는 페이지 부재(page fault)라고 한다.

-> 접근하는 페이지가 메인 메모리 안에 존재하지 않는 것

 

가상 메모리를 갖는 프로세서는 가상 주소(virtual address)를 만들어내고

가상 주소는 하드웨어와 소프트웨어의 조합에 의해 메인 메모리 접근에 사용되는

실제 주소(physical address)로 변환된다.

 

가상 메모리는 재배치(relocation)기능을 제공하여 수행될 프로그램의 적재를 단순화한다.

재배치는 프로그램에 의해 사용되는 가상 주소를 메모리에 접근하는 데 사용 되기 이전에

다른 실제 주소로 사상시켜준다.

 

** 재배치는 메인 메모리 내의 어떤 위치에도 프로그램을 적재할 수 있게 해준다.

따라서 프로그램을 할당하기 위해 메모리에서 연속적인 블록을 찾아낼 필요가 없게 되었다. 

그냥 메인 메모리 내에 충분한 페이지가 있는지 확인만 하면 된다.

 

가상 메모리 시스템의 주소는 "가상 페이지 번호" 와 "페이지 변위" 가 있다.

당연히 실제로 쓰일 때는 가상 페이지 번호에서 실제 페이지 번호로 바뀐다.

 

 

 


 

 

아까 말했듯이 CPU,OS가 쓰는 가상메모리 주소는 물리적 주소와 다르다

때문에 가상메모리에서는 물리적 주소로 바꾸는 작업이 필요하다.

이것을 Address Translation이라고 부른다.

 

 

 

저기 보면 가상 메모리 주소의 비트와

물리적 주소의 비트가 차이가 나는데

가상 메모리는 4GB를 사용하지만 실제로 DRAM은 1GB라는 것을 의미한다.

 

page offset은 그대로지만 page number의 bit가 다르다.

20비트를 18비트로 바꿔주는 것이 바로 translation이다.

 

Virtual Address, VA를 물리적 주소를 바꿀 때 이런 식으로 사용한다.

 

 

CPU에서는 VA를 쓰지만 캐시 메모리, 메인 메모리에선 PA, Physical Address를 쓴다.

때문에 Translation은 CPU와 캐시 사이에서 발생한다.

 

 

하지만 뭔가 이상하다.

물리적 주소를 알려면 Main Memory에 대해서 검색을 한다는 뜻인데..

그렇다. Translation 작업에는 Main memory 접근을 필요로 한다.

즉, 캐시에서 Miss가 난다면 접근을 2번이나 해야하는 비용이 높은 작업을 해야한다는 것이다.

 

 

**아니 그럴거면 처음부터 VA 사용안하고 PA사용하면 되잖아??

-> 가상메모리의 이점을 보고오자, 다른 것으로 보완가능하고 이점이 단점보다 커서 사용한다.

 

 

이를 극복하기 위해 TLB라는 장치를 만들었다.

 

Translation Lookaside Buffer로 

최근에 Translation 했던 정보를 담는 버퍼다.

만약 해당 정보에 Translation 정보가 있다면 Main Memory를 access하지 않아도 되어 비용을 줄일 수 있다.

즉, 메인메모리 Pagetable lookup 하는 과정을 줄이는 것이다.

 

구조적으로 보면 이런 식으로 작동한다.

 

 

Page Table Register로 페이지의 시작 주소 값을 알 수 있다.

Virtual page number가 해당 page table의 index가 되고 그 안에 들어있는 것이

Physical page number가 된다.

 

여전히 Valid bit 역할은 같다.  1이면 Main memory에 있고 0이면 없는 것이다.

** 0이면 Disk에서 찾아와야 한다는 뜻이다.

 

 

CPU의 VA를 해석해서

나온 PA를 가지고 캐시나 메인메모리에 Access를 하는 것이다.

 

Valid bit에 따라 접근하는 곳이 다르다.

 

 

즉, Page table은 Physical page 또는 Disk address를 가리키게 되는 것이다.

 

 


 

다음은 Page Table에 대해서 더 알아보자.

같은 말의 반복이다.

 

 

Page Table은 가상 주소를 물리적 주소로 바꾸기 위한 정보를 가지고 있는 Table을 말한다.

 

Page Tables은 Entries의 배열이며 해당 Entries들은 virtual page number로 index되어 있다.

 

즉, page가 메인 메모리에 있다면

PTE, Page Table Entry에는 physical page number가 있어야 하며

해당 페이지에 대한 부가정보를 위한  bit를 가지고 있기도 하다.

 

page가 메인 메모리에 없다면

PTE는 disk나 swap space에 있는 위치를 가리키게 된다.

 

 


 

가상메모리에서 Miss 가 나면 즉, page fault가 나면 어떻게 될까???

 

 

page fault는 Disk에서 page를 불러오는 작업을 해야만한다.

 

Disk에서 가져오는 일은 무척 비용이 큰 일이다. 

** 캐시의 miss는 CPU가 관리하지만 Page의 miss는 OS가 관리한다.

 

그래서 우리는 최대한 page fault가 안나게끔 해야만 한다.

그래서 캐시와 비슷하게

 

Fully Associative 로 모든 물리적 주소로 매핑되는 정보를 가지고 있게 하거나

어떤 page를 가지고 있어야 fault가 안날지 충분히 고려해서 교체작업을 진행한다.(LRU)

 

 

 

 

 

Page fault 는 Handler가 아래와 같이 작동한다.

 

 

page fault를 일으킨 virtual address를 PTE에서 찾는다.

해당 page를 disk에서 찾고

replace할 page를 선정한다.

내가 Access한 page를 읽어서 메인메모리에 올리고 Page table을 갱신한다.

그 후 page fault를 발생시킨 명령어를 다시 시작하면 된다.

 

 

 


 

Page fault 이후에는

 

replace가 일어난다.

page fault로 일어난 작업

즉,  Disk 에서 읽어오는 작업은 비용이 정말 큰 작업이다.

 

 

교체가 일어날 땐

보통 최근에 쓰지 않은 순서대로 페이지를 교체해 나간다. (LRU)

 

모두가 1이면 구분할 수 없기에 OS가 주기적으로 0으로 만들어서

최근 것과 최근 것이 아닌 것을 구분할 수 있도록 해준다.

 

그리고 Disk write는 큰 작업이기 때문에

블럭 단위로 읽기, 쓰기를 진행하며 (보통 블럭당 512 Bytes)

Write-through는 별로다. Write-back을 쓴다.

 

 

 


 

위에서 메인 메모리 접근을 줄이기 위해 TLB라는 버퍼를 쓴다고 했다.

 

페이지 테이블이 메모리에 저장되기 때문에 프로그램에 의한 모든 메모리 접근 시간은 최소한 2배 이상이다. 

실제 주소를 얻기 위한 메모리 접근 한 번과 데이터를 얻기 위한 또 한 번의 접근이 필요하다. 

접근 성능을 높이기 위한 핵심은 페이지 테이블에 대한 참조의 지역성에 달려있다.

 

 

PTE, Page Table Entry를 말한다.

TLB는 보통 16-512 PTE를 가지고

hit이 발생했을 때 훨씬 적은 비용을 가지고 있다.

TLB의 miss rate도 아주 낮다.

 

 

 

TLB에서 hit가 발생하면 바로 그대로 캐시에 이용할 수 있어서 유용하다.

miss가 발생하면 그저 Translation을 해서 다시 사용하면 된다.

 

이러한 원리를 이용한 것이 많은데 장치를 조금이라도 늘려서 시간이 줄어든다면 좋은 성능을 보이기에

거의 모든 장치들에 이러한 원리를 이용하는 것이다.

 

**하지만 TLB에서 miss가 났을 때는 2가지 경우를 생각해볼 수 있다.

 

 

1. 단순 TLB miss

메인메모리에 있지만 TLB에 아직 안올린 것

그런 경우에는 바로 Miss 처리 후 TLB로 갱신이 가능함

 

 

2. page fault ( true page fault)

메인메모리에 없어서 Disk에서 가져와야하는 것

이것은 진짜 없어서 바로 TLB로 갱신하는 것은 불가능하고

Disk에서 메인 메모리로 가져와서 그 다음 올려야 하는 큰 비용이 든다.

 

하지만 단순 TLB miss가 훨씬 더 많이 발생한다. 

 

또한 TLB miss가 일어났을 때 Handler가 작동한다.

 

 

 

실제 구조는 이렇게 보면 된다.

 

 

처음엔 TLB를 가서 해당 Physical Address가 있는지 조사한다.

없다면

실제로 Page Table로 와서 메인 메모리에 있는 지 없는 지 조사한 후 TLB에 갱신하기 위해

메모리에 접근하거나 Disk에 접근하면 된다.

 

**TLB는 VA로 접근, 캐시는 PA로 접근 

 

 

반응형
그리드형