RAM
에는 실행할 프로그램의 명령어와 데이터가 저장된다. 하지만 전원을 끄면 RAM에 저장된 명령어와 데이터가 모두 날아간다. 이렇게 전원을 끄면 저장된 내용이 사라지는 저장 장치를 휘발성 저장 장치
라고 한다.
반면 전원이 꺼져도 저장된 내용이 유지되는 저장 장치는 비휘발성 저장 장치
라고 한다. 보조기억장치는 전원을 꺼도 내용을 유지하지만, CPU는 보조기억장치에 직접 접근하지 못한다. 따라서 보조기억장치에는 보관할 대상
을 저장하고, 휘발성 저장장치인 RAM
에 실행할 대상
을 저장한다. 한마디로 CPU가 실행하고 싶은 프로그램이 보조기억장치에 있다면 이를 RAM으로 복사하여 저장한 뒤 실행한다.
RAM
의 용량이 크면 어떤 점이 좋을까?
CPU가 실행하고 싶은 프로그램이 보조기억장치에 있다면 이를 RAM으로 가져와야 할 텐데 RAM용량이 적다면 보조기억장치에서 실행할 프로그램을 가져오는 일이 잦아 실행 시간이 길어진다. RAM 용량이 충분히 크다면 보조기억장치에서 많은 데이터를 가져와 미리 RAM에 저장할 수 있다. 많은 프로그램을 동시에 실행하는데 유리하다.
하지만 그렇다고 RAM의 용량이 무지막지하게 크다고 속도가 비례해서 빨라지지는 않는다.
DRAM
DRAM
은 Dynamic RAM의 준말이다. 이는 저장된 데이터가 동적으로 변하는 RAM을 의미한다. 즉, DRAM은 시간이 지나면 저장된 데이터가 점차 사라지는 RAM이다. 그렇기에 DRAM은 데이터의 소멸을 막기 위해 일정 주기로 데이터를 재활성화해야 한다.
이런 단점에도 불구하고 저렴하고, 대용량으로 설계하기 용이하기 때문에 많이 쓰인다. 주로 주기억장치
로 쓰인다.
SRAM
SRAM
은 Static RAM의 준말이다. 이는 저장된 데이터가 변하지 않는 RAM을 의미한다. 주기적으로 데이터를 재활성화할 필요도 없기때문에 속도도 빠르다. 하지만 이런 장점에도 불구하고 가격도 비싸고 집적도가 낮다. 주로 캐시 메모리
로 쓰인다.
SDRAM
이름만 보면 DRAM과 SDRAM의 합성어라고 오해하기 쉽지만 전혀 관계가 없다. SDRAM
은 발전된 형태의 DRAM
이다. 클럭
과 동기화되었기 때문에 클럭에 맞춰 동작하며 클럭마다 CPU와 정보를 주고받을 수 있는 DRAM이다.
DDR SDRAM
DDR SDRAM
은 최근 가장 흔히 사용되는 RAM이다. DDR SDRAM
은 대역폭을 넓혀 속도를 빠르게 만든 SDRAM
이다.
CPU와 실행 중인 프로그램은 현재 메모리 몇 번지에 무엇이 저장되어 있는지 다 알고 있을까?
정답은 '그렇지 않다' 이다. 그 이유는 메모리에 저장된 정보는 시시각각 변하기 때문이다. 메모리에는 새롭게 실행되는 프로그램이 시시때로 적재되고, 실행이 끝난 프로그램은 삭제된다. 게다가 같은 프로그램을 실행하더라도 실행할 때마다 적재되는 주소가 달라질 수 있다.
그렇다면 CPU와 실행 중인 프로그램이 이해하는 주소는 무엇일까?
주소에는 메모리가 사용하는 물리 주소
가 있고, CPU와 실행 중인 프로그램이 사용하는 논리 주소
가 있다. 메모리가 사용하는 물리 주소
는 말 그대로 정보가 실제로 저장된 하드웨어상의 주소를 의미한다. 반면 CPU와 실행 중인 프로그램이 사용하는 논리 주소
는 실행 중인 프로그램 각각에게 부여된 0번지부터 시작되는 주소를 의미한다. 따라서 프로그램마다 같은 논리 주소가 얼마든지 있을 수 있다.
하지만 CPU가 이해하는 주소가 논리 주소라고는 해도 CPU가 메모리와 상호작용하려면 논리 주소와 물리 주소 간의 변환이 이루어져야 한다. 그렇다면 논리 주소는 어떻게 물리 주소로 변환될까?
이것은 MMU
라는 하드웨어에 의해 수행된다. MMU는 CPU가 발생시킨 논리 주소에 베이스 레지스터 값을 더하여 논리 주소를 물리 주소로 변환한다. 만약 베이스 레지스터에 45000이 저장되어 있고 CPU가 발생시킨 논리 주소가 100번지라면 이 논리 주소는 물리주소 45100번지러 변환된다. 물리 주소 45000번지로부터 적재된 프로그램의 논리 주소 100번지에는 이렇게 접근이 가능하다.
여기서 베이스 레지스터
는 프로그램의 가장 작은 물리 주소, 즉 프로그램의 첫 물리 주소를 저장하는 셈이고, 논리 주소는 프로그램의 시작점으로부터 떨어진 거리인 셈이다.
위와 같이 다른 프로그램의 영역을 침범할 수 있는 명령어는 위험하기 때문에 논리 주소 범위를 벗어나는 명령어 실행을 방지하고 실행 중인 프로그램이 다른 프로그램에 영향을 받지 않도록 보호할 방법이 필요하다. 이는 한계 레지스터
라는 레지스터가 담당한다.
베이스 레지스터가 실행 중인 프로그램의 가장 작은 물리 주소를 저장한다면, 한계 레지스터는 논리 주소의 최대 크기를 저장한다. 즉, 프로그램의 물리 주소 범위는 베이스 레지스터 값 이상, 베이스 레지스터 값 + 한계 레지스터 값 미만이 된다. 따라서 논리 주소는 한계 레지스터가 저장한 값보다 커서는 안된다. 한계 레지스터보다 높은 주소 값에 접근하는 것은 곧 프로그램의 범위에 벗어난 메모리 공간에 접근하는 것과 같기 때문이다.
CPU는 메모리에 접근하기 전에 접근하고자 하는 논리 주소가 한계 레지스터보다 작은지를 항상 검사한다. 만약 CPU가 한계 레지스터보다 높은 논리 주소에 접근하려고 하면 인터럽트를 발생시켜 실행을 중단한다.
모든 사용자들은 빠르고 동시에 용량이 큰 저장 장치를 원한다. 하지만 빠른 저장 장치와 용량이 큰 저장 장치는 양립하기 어렵다. 그래서 일반적으로 컴퓨터는 다양한 저장 장치를 모두 사용하게 된다.
컴퓨터가 사용하는 저장 장치들은 'CPU에 얼마나 가까운가'를 기준으로 계층적으로 나타낼 수 있다. 이를 저장 장치 계층 구조
라고 한다.
CPU가 메모리에 접근하는 속도는 레지스터에 접근하는 속도보다 느리다. 그럼에도 불구하고 CPU는 프로그램을 실행하는 과정에서 메모리에 빈번히 접근해야만 한다. CPU 연산 속도가 아무리 빨라도 메모리에 접근하는 속도가 그에 따라가지 못한다면 CPU의 발전은 아무 소용이 없다.
그래서 등장한 저장 장치가 캐시 메모리
이다. 캐시 메모리는 CPU와 메모리 사이에 위치하고, 레지스터보다 용량이 크고 메모리보다 빠른 SRAM 기반의 저장 장치이다.
우리가 사용하는 컴퓨터 내부에는 여러 개의 캐시 메모리가 있다. 그리고 이 캐시 메모리들은 CPU와 가까운 순서대로 계층을 구성한다. 코어와 가장 가까운 캐시 메모리를 L1 캐시
, 그 다음은 L2 캐시
라고 한다. 캐시 메모리 용량은 L1, L2 순서대로 커지고, 속도는 L3 L2 L1 순서대로 빨라진다. 가격은 일반적으로 L3, L2, L1 순으로 비싸다.
위 그림과 같이 멀티 코어 프로세서에서 L1-L2-L3 캐시는 일반적으로 L1 캐시와 L2 캐시는 코어마다 고유한 캐시 메모리로 할당되고, L3 캐시는 여러 코어가 공유하는 형태로 사용된다.
캐시 메모리는 메모리보다 용량이 작다. 당연하게도 캐시 메모리는 메모리에 있는 모든 내용을 가져다 저장할 수는 없다. 캐시 메모리는 CPU가 사용할 법한 대상을 예측하여 정장한다. 이때 자주 사용될 것으로 예측한 데이터가 실제로 들어맞아 캐시 메모리 내 데이터가 CPU에서 활용될 경우를 캐시 히트
라고 한다. 반대로 자주 사용될 것으로 예측하여 캐시 메모리에 저장했지만, 예측이 틀려 메모리에서 필요한 데이터를 직접 가져와야 하는 경우를 캐시 미스
라고 한다.
캐시 메모리는 한 가지 원칙에 따라 메모리로부터 가져올 데이터를 결정한다. 바로 참조 지역성
의 원리이다. 참조 지역성의 원리란 CPU가 메모리에 접근할 때의 주된 경향을 바탕으로 만들어진 원리이다.
CPU는 최근에 접근했던 메모리 공간에 다시 접근하려는 경향이 있다.
변수에 값을 저장하고 나면 언제든 변수에 다시 접근하여 변수에 저장된 값을 용할 수 있다. 이는 저장된 메모리 공간을 언제든 다시 참조할 수 있다는 것을 의미한다.
이를 시간 지역성
이라고도 한다.
CPU는 접근한 메모리 공간 근처를 접근하려는 경향이 있다.
CPU는 프로그램을 실행할 때에는 프로그램들이 모여 있는 공간 근처를 집중적으로 접근할 것이고, 사용자가 입력을 할 적에는 입력 기능이 모여 있는 공간 근처를 집중적으로 접근할 것이다.
이를 공간 지역성
이라고 한다.
캐시 메모리는 이렇듯 참조 지역성의 원리에 입각해 CPU가 사용할 법한 데이터를 예측한다.