메모리의 범위와 종류 -----------------------------------------------------------------------------------------

1. 메인메모리

  메인메모리인 RAM을 의미하며 정확히는 D-RAM이다.

2. 레지스터

  CPU안에 내장되어 있는 레지스터를 의미한다.

3. 캐쉬

  D-RAM보다 빠른 S-RAM으로 구성되어있다. 캐쉬메모리는 원래 CPU의 일부로 존재하는 메모리 개념이 아니다. CPU에 근접해 있는 메모리 개념이다. CPU의 일부로 존재하는 메모리는 레지스터라는 것을 기억해야 한다.

  책의 설명 -> "CPU옆에 붙어있는 메모리"


메모리의 범위와 종류 -----------------------------------------------------------------------------------------

그림의 피라미드 구조가 메인메모리 구조이며 계층구조를 이루는 기준은 단 한가지로 명확하다.

"CPU로 부터 얼마나 떨어져 있는가?"


L1 L2캐쉬의 차이 -----------------------------------------------------------------------------------------

본래 CPU의 구조는 하나의 캐쉬만을 사용했다. 하지만 메인메모리는 캐쉬에 비해서 많이 느렸고 캐쉬의 요구를 메인메모리에서 수용하여 데이터를 입출력하는데 많은 시간이 들었다. 그리고 이러한 현상을 병목현상이라고 불렀다.

그러한 병목현상을 해결하기 위해서 캐쉬를 2개로 분할하여 메인메모리와 연결되는 L2캐쉬와 L1캐쉬로 나누어 놓았다. 그리고 중간과정을 하나 거침으로해서 병목현상을 개선하기 위한 용도로 사용한다.

그냥 하나의 큰 캐쉬를 쓰는것과 무슨 차이가 있는지에 대해서 까지는 책에서 설명이 되어있지 않지만 L2캐쉬에는 L1캐쉬에서 자주 참조하는 데이터를 비치해 놓는다는 차이를 두고 있다.


템퍼럴 로컬리티, 스페이셜 로컬리티 -----------------------------------------------------------------------------

우리가 사용하는 프로그래밍 코드에는 2가지 자주 발견되는 특징이 있다.

다음의 코드를 보자.

int* c[100] = new int;

n = 100;

c -> 초기화(100개의 랜덤한 정수를 부여한다.)

for(int i = 0 ; i < n ; i++)

{

for(int j = 1 ; j < n-1 ; j++)

{

int temp = c[j-1];

c[j-1] = c[j];

c[j] = teamp;

}

}

코드를 확인해보면 알겠지만 i, j, temp에 굉장히 자주 접근하고 있는 코드이다.

(Temporal Locality)템퍼럴 로컬리티란 프로그램 실행시 한번 접근이 이뤄진 주소의 메모리 영역은 지속적으로 자주 접근한다는 특징을 의미한다.

두번째 특징은 j-1과 같이 메모리 영역을 4바이트씩 지속적으로 줄여가며 접근을 하고 있다.

(Spatial Locality)스페이셜 로컬리티란 프로그램 실행시 접근하는 메모리 영역은 이미 접근이 이루어진 영역의 근처일 확률이 높다는 것을 의미한다.

당연히 이러한 2가지 특성은 캐쉬의 성능을 향상시키고 이러한 캐쉬메모리의 연산을 줄여주는 코드를 캐쉬 프랜들리 코드라고 한다.


캐쉬 힛, 캐쉬 미스 --------------------------------------------------------------------------------------

만약 L1캐쉬에서 자신의 메모리를 검색하여 필요한 데이터가 존재하면 이를 캐쉬 힛(Cache Hit)이라고 한다. 반대로 없을 경우에는 L2캐쉬에서 메모리를 가져와야 하는데 이를 캐쉬 미스(Cache Miss)라고 한다.

만약 이때 L2에서 데이터를 보낼때 블록단위의 전송을 한다. 즉 필요한 데이터를 4바이트 하나만 보내는 것이 아니라 그 주변 일정 블럭 이내의 데이터를 한번에 보내는 것이다. 이러한 점 때문에 스페이셜 로컬리티나 템퍼럴 로컬리티의 특성이 연산에 영향을 주게 되는 것이다.

또한 당연히 새로운 데이터를 출력하면 캐쉬교체가 일어나게 되는데 이때.

캐쉬 교체 정책(Cache's Replacement Policy)의 기준에 따라서 블럭단위 이동과 함께 블럭단위로 데이터를 밀어내게 된다. 그리고 가장 보편화된 기준은 LRU(Least_RecentlyUsed)알고리즘 이다.

단순히 이야기해서 가장 오래전에 참조한 메모리블록을 밀어내고 새 메모리 블록을 그곳에 새로 로딩하는 것을 의미한다.


가상메모리, 물리주소 -----------------------------------------------------------------------------------------

컴퓨터의 Ram은 512M바이트인데 어떻게 프로세스에는 4G가 할당될까?

C++에서 포인터의 주소는 4G가 한계이다. 물리주소는 512M바이트 안으로만 설정될 수 있다. 그렇다면 메모리 주소를 볼때 확인되는 물리적 주소를 넘어가는 주소는 어떻게 할당되는 것일까?

간단히 이야기 해본다면 모든 메모리가 꽉곽 채워져서 할당되지 않는 다는 점이 그 문제의 해결책이 된다.

MMU(Memory Management Unit)라는 녀석이 존재하여 메모리 할당을 중간에서 물리적 한계보다 더 크가 잡아서 할당하는 것이다.


MMU는 메모리의 일부분을 확인하고 그 일부분을 가상메모리 주소로 할당하여 메인메모리에 저장한다. 이로서 주소의 문제는 해결되었다. 하지만 물리메모리가 정말로 꽉 차버린다면 어떻게 해야할까?



바로 위와 같이 일부 데이터는 하드로 이동시키고 새로운 공간을 메인메모리에 할당하게 된다.

이를 통해서 어떻게 2개의 프로세서에서 각각의 프로세서에 4기가 이상의 바이트가 할당 가능한지 설명이 가능해진다. 물론 MMU가 이 모든걸 처리하는 것은 아니다. 가상메모리에서 메모리 할당과 주소 변환에 관련된 것들만을 MMU가 처리한다. 이러한 하드웨어적인 부분을 제외한 소프트웨어적인 부분은 운영체제와 관련이 있으며 이 부분은 윈도우 시스템에서 VMM(Virtual Memory Manager)과 관계가 깊다.

Posted by JJOREG