메모리를 보호하기 위해 CPU는 현재 진행 중인 작업의 메모리 시작 주소를 경계(bound) 레지스터에 저장
현재 진행 중인 작업이 차지하고 있는 메모리의 크기(마지막 주소까지의 차이)를 한계(limit) 레지스터에 저장
작업이 진행되는 동안 경계, 한계 레지스터의 주소 범위를 벗어나는지 하드웨어를 점검하여 메모리를 보호
만약 두 레지스터의 값을 벗어난다면 메모리 오류와 관련된 인터럽트가 발생하여 해당 작업을 종료
RAM(Random Access Memory)
용량이 충분히 크면 보조기억장치로부터 실행할 프로그램을 가지고 오는 일이 적어 실행시간이 줄어들지만 필요 이상으로 커지면 비례하는 것은 아님
임의 접근(Radom Access) : 저장된 요소에 순차적으로 접근할 필요 없이 임의의 위치에 바로 접근 가능한 방식
DRAM(Dynamic RAM)
시간이 지나면 저장된 데이터가 점차 사라지므로 데이터 소멸을 막기 위해 일정 주기로 데이터를 다시 저장해야 함
소비 전력이 낮고 저렴하며 집적도가 높아 대용량으로 설계하기 좋음
SRAM(Static RAM)
시간이 지나도 저장된 데이터가 사라지지 않음
빠르지만 소비전력이 크고 비싸고 집적도가 낮아 속도가 빨라야하는 저장장치(캐시 메모리)에 사용됨
SDRAM(Synchronous Dynamic RAM)
클럭 신호와 동기화되어 클럭 타이밍에 CPU와 정보를 주고 받을 수 있는 RAM
DDR SDRAM(Double Data Rate SDRAM)
대역폭(데이터를 주고 받을 길의 너비)을 넓혀 속도를 빠르게 만든 SDRAM
메모리에 바이트를 밀어 넣는 순서 - 빅 엔디안과 리틀 엔디안
메모리는 바이트 단위로 저장하지만 CPU는 워드 단위로 받기 때문에 여러 주소를 저장함
빅 엔디안
낮은 번지의 주소에 상위 바이트(큰 값, MSB(Most Significant Bit, 가장 왼쪽에 있는 비트))부터 저장하는 방식 숫자 체계를 읽고 쓰는 순서와 동일하기 때문에 메모리 값을 직접 읽거나 디버깅에 편리
리틀 엔디안
낮은 번지의 주소에 하위 바이트(작은 값, LSB(Least Significant Bit, 가장 오른쪽에 있는 비트))부터 저장하는 방식
메모리 값을 직접 읽고 쓰기는 불편하지만 수치 계산(작은 값부터 계산)이 편리
캐시 메모리
필요한 데이터를 모아 한꺼번에 전달하는 버퍼의 일종으로, CPU가 앞으로 사용할 데이터를 미리 저장
CPU 안에 있으며 CPU 내부 버스의 속도로 작동하고 메모리는 시스템 버스의 속도로 작동하기 때문에 빠른 CPU와 느린 메모리 사이의 속도 차이를 완화
CPU는 메모리에 접근해야 할때 먼저 캐시를 확인
캐시 히트 : 저장한 데이터가 CPU에 의해 사용되는 경우
캐시 미스 : 캐시 메모리에 없어 CPU가 메모리에 접근하는 경우
참조 지역성의 원리에 따라 메모리로부터 가져올 데이터를 결정
캐시 적중률을 높이기 위해 앞으로 많이 사용될 데이터를 결정
시간 지역성 : CPU는 최근에 접근했던 메모리 공간에 다시 접근하려는 경향, 변수
공간 지역성 : CPU는 접근한 메모리 공간의 근처에 접근하려는 경향, 배열
vector<vector<int>> v(20000, vector<int>(20000));
// 공간 지역성 good
for (int i = 0; i < 20000; ++i)
{
for (int j = 0; j < 20000; ++j)
v[i][j] = 0;
}
// 공간 지역성 bad
for (int i = 0; i < 20000; ++i)
{
for (int j = 0; j < 20000; ++j)
v[j][i] = 0;
}
캐시에 저장된 데이터가 변경되는 경우 메모리에 반영해야 하는 문제가 있음
즉시 쓰기
즉시 메모리에 반영
일관성 깨지는 상황을 방지하지만 메모리와의 빈번한 전송으로 성능이 느려짐
지연 쓰기
변경된 데이터를 주기적으로 메모리에 반영하는 방법
메모리와의 데이터 전송 횟수가 줄어 시스템의 성능을 향상시킬 수 있지만 메모리와 캐시 메모리 사이, 다른 코어 사이의 일관성이 깨질 수 있음