메모리, RAM(Random Access Memory)
RAM은 Random Access Memory로 어떤 위치건(Random) 접근(Access)할 수 있는 기억장치(Memory)입니다.
메모리라고 하면 컴퓨터에서는 대부분 RAM을 말합니다. 램이라고 부르는 이 저장장치는 휘발성(Volatile) 저장장치로, 전원이 꺼지면 안에 있던 명령어나 데이터가 없어집니다. 반면에 하드디스크 드라이브, 솔리드 스테이트 드라이브(SSD)는 전원이 꺼져도 내부 데이터가 남아있어 비휘발성 저장장치로 분류됩니다.
메모리의 필요성과 휘발/비휘발
램은 왜 있을까요? 초기에 공부했던 것처럼, 램이 필요한 이유는 프로그램의 명령어와 데이터는 CPU 내부의 레지스터에 모두 저장할 수 없는 크기이기 때문에 필요한 데이터나 명령어를 저장해두는 공간이 필요해서 입니다. 비휘발성 메모리를 램으로 쓰지 않는 이유는 느려서입니다. (물론 램의 크기가 충분치 않을 때는 가상 메모리라고 해서 비휘발성 저장장치의 공간도 램처럼 씁니다. 램 크기가 부족하면 시스템이 더 이상 프로그램의 명령어들을 수행할 수 없기 때문에 없는 것보다 낫기 때문입니다.)
램의 종류
램은 DRAM, SRAM, SDRAM, DDR SDRAM 의 종류가 있습니다.
DRAM은 Dynamic RAM으로 저장된 데이터가 동적으로 계속 없어지기 때문에 일정 주기로 다시 저장을 해줘야 하는 램입니다.
SRAM은 Static RAM으로 저장된 데이터가 없어지지 않습니다. 그리고 일반적으로 DRAM보다 더 빠릅니다. 다만 비쌉니다. 그래서 램으로 쓰진 않고 캐시 메모리로 씁니다. 이에 대해서는 아래에서 추가로 다루겠습니다.
SDRAM은 Synchronous Dynamic RAM 입니다. DRAM인데 싱크를 맞출 수 있는 램입니다. 싱크는 클럭에 따라 CPU와 정보를 주고받음으로써 맞춥니다.
DDR SDRAM은 Double Data Rate SDRAM입니다. SDRAM의 대역폭을 늘린 램입니다. 대역폭은 DDR > DDR2 > DDR3 > DDR4 > DDR5 까지 한 단계당 두 배로 늘어났습니다. 요새 나오는 PC들은 DDR5 SDRAM을 이용하고 있는거지요. (DDR5는 핀당 6400Mbps)
메모리의 주소 공간
물리 주소와 논리 주소
메모리의 주소는 두 가지로 나뉩니다.
물리주소 : 하드웨어가 사용하는 주소
논리 주소 : CPU와 실행중인 프로그램들이 사용하는 주소
*논리 주소는 어떤 하나의 하드웨어 주소를 새로운 기준으로 잡고 그 뒤의 공간들에 부여한 주소들입니다.
물리 주소가 필요하다는 것은 자명한 일인데 왜 논리 주소라는 개념이 등장했을까요?
메모리에 저장된 정보가 변할 수 있기 때문에 개별 물리주소를 관리하는 것이 비효율적이기 때문입니다.
논리 주소는 관리가 물리 주소보다 쉽지만, 결국 그 안에 저장된 데이터와 명령어를 불러오려면 물리 주소로 변환해야 합니다. 이걸 해 주기 위한 하드웨어가 따로 있습니다. 그것이 바로 MMU입니다. (Memory Management Unit)
MMU에는 베이스 레지스터가 있는데, 논리 주소 값에 베이스 레지스터에 저장된 값을 더하면 물리 주소가 됩니다. 이 물리 주소 값을 이용해서 램에 접근하는 것입니다. 베이스 레지스터의 값은 프로그램의 첫번째 물리 주소 값이 되겠지요. 논리 주소는 첫번째 물리 주소에서 떨어진 거리가 될 것입니다.
때때로 잘못된 물리 주소에 대한 명령어가 존재할 수 있습니다. 이 경우 해당 명령어는 수행되면 안 되겠지요. 다른 프로그램의 데이터와 명령어에 영향을 주는 일이니 오류를 만들게 될 것입니다. 이러한 잘못된 메모리 주소에 의한 실패를 막기 위한 것이 메모리 보호 기법입니다. 메모리 보호 기법은 어떻게 만들 수 있을까요? 논리 주소의 최대 크기를 알 수 있다면, 실제 프로그램의 램 할당 범위를 벗어나는 잘못된 접근을 막을 수 있겠지요. 그래서 레지스터를 하나 추가합니다. 이는 한계 레지스터로 논리 주소의 최대 크기(프로그램의 크기)의 값을 저장합니다. 메모리에 접근하기 전에, 접근하고자 하는 논리 주소가 한계 레지스터의 값보다 작은지를 검사하는 것입니다.
(접근하고자 하는 논리 주소 = 베이스 레지스터 + 논리 주소 입니다.)
만약 접근하고자 하는 논리 주소가 한계 레지스터의 값보다 큰 경우는, 메모리에 잘못된 주소로 접근하는 것입니다. 이 경우 CPU는 인터럽트(트랩)을 발생시켜서 잘못된 메모리 접근에 의한 실패를 방지하게 됩니다.
캐시 메모리
캐시 메모리는 무엇이고 왜 필요한가?
캐시 메모리는 뭘까요? 그 전에 캐시는 뭘까요? 캐시는 cash가 아니라 cache입니다. 은닉처라는 의미인데, 가까이 숨겨두는 곳을 생각하시면 됩니다. 캐시 메모리는 데이터와 명령어를 잠시 보관해두는 곳인 거지요.
캐시의 어원을 알았으니 그 필요성에 대해서 알아보겠습니다. 저장장치에도 등가교환의 법칙이 있습니다. 속도와 용량, 가격은 세마리 토끼를 동시에 잡기 힘듭니다. 속도가 빠르면 용량이 작고, 용량이 크면 가격이 비싸지고, 가격이 싸지면 속도와 용량에서 손해를 보는 그런 등가교환의 법칙입니다. 그래서 저장장치 계층구조(memory hierachy)가 생깁니다. 빠르고 비싼 건 용량이 작은 만큼 최대한 활용하고, 느리고 용량이 크고 저렴한 건 덜 써도 용량이 중요한 부분에 쓰고, 그런 계층 구조가 생긴 것입니다.
이런 계층 구조는 빠르고 비싼 순으로 적은 용량을 쓰게 됩니다.
레지스터 - 캐시 메모리 - 램(메모리) - 보조기억장치
캐시 메모리는 레지스터 다음의 계층을 이루고 있는 메모리입니다. SRAM 기반이며, CPU에 대해 관심이 많으신 분들은 들어보셨을 L1, L2, L3 캐시가 그것입니다. (여기서 L 은 Level 입니다.)
*일반적인 참고사항
L1, L2는 코어 내부에, L3은 코어 외부에 위치합니다. L1, L2는 각 코어마다 단독으로 사용하며 L3은 여러 코어가 공유합니다.)
참조 지역성 원리
참조 지역성 원리는 Locality of reference 혹은 Principle of locality를 말합니다. CPU가 메모리에 접근할 때 경향성이 있다는 원리입니다. 이 경향성이 어떤 것인지 풀어서 말하면 아래의 내용입니다.
1. CPU는 최근에 접근했던 메모리 공간에 다시 접근하는 가능성이 높다. = 시간지역성(Temporal locality)
2. CPU는 접근한 메모리 공간 근처를 접근하는 가능성이 높다. = 공간지역성(Spatial locality)
변수에 저장된 값이나 유사한 명령어가 반복해서 사용되는 경우가 많고, 프로그램을 실행할 때 메모리에 올라간 해당 프로그램의 공간 내에서 반복해서 접근할 가능성이 높으니 이러한 경향성이 나타나는 것입니다. 이런 경향성에서 성능을 향상시키기 위해 캐시가 활용됩니다. 캐시 메모리에는 CPU가 사용할만한 데이터나 명령어를 저장해두고 램에서보다 더 빨리 코어로 그 데이터를 줍니다.
*캐시에 필요한 데이터가 있으면 캐시 히트라고 하고, 캐시에 필요한 데이터가 없으면 캐시 미스라고 합니다. 전체 캐시 확인 수에서 캐시 히트의 비율은 캐시 적중률(cache hit ratio)가 됩니다.