Developer.

1.2.2 Storage Structure

컴퓨터의 데이터 저장이 어떻게 되는지 전반적인 구조를 본다.

📂 목차


📚 본문

Overview

프로그램 실행의 전제 조건은 메모리(RAM)에서만 명령어를 불러올 수 있기 때문에, 모든 프로그램은 먼저 메모리에 적재되어야 실행할 수 있다. 대부분 DRAM(Dynamic Random Access Memory) 기반의 RAM에서 실행된다. RAM은 휘발성이므로 전원이 꺼지면 데이터가 사라진다.

예시: 문서를 메모장에서 작성 중일 때 저장하지 않고 컴퓨터를 꺼버리면 내용이 사라지는 것과 같다.

반면, 부팅 시 사용하는 EEPROM(Electrically Erasable Programmable Read Only Memory)Firmware(펌웨어)와 같은 비휘발성 저장소는 전원이 꺼져도 데이터가 유지되어, Bootstrap(부트스트랩) 프로그램 등을 저장한다. 이러한 저장소는 수정 속도가 느려 잦은 변경에는 적합하지 않으며, 정적인 프로그램이나 자주 변경되지 않는 데이터를 저장하는 데 사용된다.

모든 형태의 메모리에는 바이트 배열의 형태로 제공되며, 각각의 바이트는 고유한 주소를 가지고 있고, 이 주소를 통해 상호작용한다. CPU는 load, store 명령어 등을 사용하여 특정 메모리 주소와 데이터를 주고받는다.

  • load: RAM -> CPU 레지스터 로의 워드, 바이트 데이터를 옮김(이 의미보다는 그냥 메모리에 기록한다의 의미로 보는게 좋다)

Main Memory -> CPU
1. CPU가 Address Bus에 주소를 보냄
2. CPU가 Control Bus에 ‘읽기’ 신호 전송
3. 메모리가 해당 주소에서 데이터를 찾아 Data Bus를 통해 데이터 전송

  • store: CPU -> RAM 의 데이터 저장

CPU -> Main Memory
1. CPU가 Address Bus 에 주소를 보냄
2. CPU가 Data Bus에 데이터를 전송
3. CPU가 Control Bus에 ‘쓰기’ 신호 전송

CPU는 PC에 저장된 위치에서 메인 메모리로부터 명령어를 자동으로 로드하여 실행한다. 이 명령어 실행을 어떻게 수행하는지 더 자세히 보자.


⭐️저장 장치 구조 von Neumann Architecture

우선 전통적인 컴퓨터 시스템의 명령어 실행 사이클(Instruction Execution Cycle)을 살펴보자.

명령어를 메모리에서 가져와(Instruction Fetch)
-> 명령어 레지스터(Instruction Register)에 저장
-> 명령어를 디코딩(Decoding)
-> 필요한 피 연산자도 메모리에서 가져와 레지스터에 저장
-> 연산 수행 후 결과를 다시 메모리에 저장

위와 같이 메모리는 단순히 Address Stream(주소 스트림)만 인식하고 주소가 어떻게 생성되었는지, 명령어인지 데이터인지는 관심이 없다.

von Neumann Architecture 의 메인메모리 한계점

이렇게 된다면 프로그램과 데이터가 RAM에 항상 상주하는 것이 이상적이겠지만, Main Memory 만으로는 충분하지 않다:

  • 메인 메모리는 모든 프로그램과 데이터를 담기에 용량이 부족하다.
  • 램은 휘발성이기 때문에 전원이 꺼지면 내용이 사라진다. 전원이 꺼진 뒤 다시 켜면 모든 데이터를 다시 메모리에 로드해야 한다.

따라서 보조 저장장치가 필요하다.

보조 저장장치(Secondary Storage)

  • RAM 을 보완하여 대용량 데이터를 영구 저장한다
  • HDD, SSD, NVM 등이 있다
  • 프로그램과 데이터를 보관하고 실행 시 RAM으로 로드된다

운영체제 및 대부분의 프로그램은 보조 저장장치에 저장되며, 실행 시 RAM으로 로드된다.
하지만 보조 저장장치는 메인 메모리에 비해 느리기 때문에 데이터 저장과 접근 관리가 중요한 주제가 된다.

이 두 가지 메모리와는 달리 다른 Tertiary Storage(3차 저장소)도 있다.

⭐️계층적 저장장치 구조

저장 장치는 capacity(용량)과 access time(접근 속도)에 따라 계층적 구조를 가진다.

storage-device-hierarchy

전형적인 구조는 레지스터 < 캐시 < 메인 메모리 < 보조 저장장치 < 3차 저장장치이며, 작고 빠른 메모리는 CPU 가까이에, 크고 느린 저장장치는 멀리 배치된다. 작을수록 더 빠르고 반응성이 높다.

예시: 계산기에 바로 붙어 있는 메모장이 레지스터이고, 그보다 좀 떨어진 노트가 캐시, 책상 서랍이 메인 메모리, 서재가 하드디스크라고 비유할 수 있다.

저장 시스템 설계 시 고려사항

  • 고속이지만 비싼 메모리는 최소한만 사용하고
  • 느리지만 저렴하고 영구적인 저장소는 최대한 활용한다

예시: 자주 쓰는 물건은 책상 위에 두고, 가끔 쓰는 물건은 창고에 보관하는 것과 같다. 창고는 크지만 접근 시간이 오래 걸린다.

두 저장 장치 간 속도 차이가 클 경우에는 Cache(캐시)를 사용하여 속도 차이를 줄여 전반적인 성능을 향상시킨다.


✒️ 용어

DRAM

우리가 쓰는 DDR5 RAM이 DRAM 의 일종이다.

DRAM 모듈은 우리가 데이터를 접근할 때 비트 단위가 아닌 Byte 또는 Word 단위로 접근하므로 이에 따른 병렬성을 활용하기 위해 여러 개의 bank로 구성되어 있으며,
각 bank는 데이터를 읽을 row를 지정하는 row decoder,
메모리 값을 증폭해 0 또는 1로 만드는 sense amp,
데이터가 저장되어 있는 array를 포함한다.

SRAM에 비해 속도가 느리지만 트랜지스터 하나와 캐패시터 하나로 만들어져 있기에 고집적화가 가능하여 고용량을 만들 수 있다.

EEPROM

비휘발성 메모리의 한 유형으로, 전원을 꺼도 데이터가 유지된다. 전기적으로 데이터를 지우고 다시 쓸 수 있으며, 부트로더나 BIOS 저장에 주로 사용된다.

Firmware

하드웨어를 제어하기 위해 장치에 탑재된 영구 소프트웨어. 주로 비휘발성 메모리 ROM에 저장되며, BIOS(Basic Input Output System)나 임베디드 시스템에 널리 쓰인다.

⭐️Bootstrap

컴퓨터가 전원을 켰을 때 운영체제를 실행하기 위해 수행하는 일련의 초기화 과정이다. 이 과정을 Bootstrap(부트스트랩) 또는 줄여서 Booting(부팅)이라 부른다.

일반적인 부트스트랩 과정은 다음과 같은 단계로 이루어진다:

  1. 전원 공급 및 하드웨어 초기화: 전원이 들어오면 CPU는 하드웨어 리셋 상태로 진입하며, 지정된 위치에서 BIOS 또는 UEFI 펌웨어 실행을 시작한다.
  2. BIOS/UEFI 실행: 하드웨어 구성 요소(RAM, 키보드, 디스크 등)를 검사하고 초기화한다. 이를 POST(Power-On Self Test)라고 한다.
  3. 부트 디바이스 탐색: 설정된 순서에 따라 부팅 가능한 저장 장치(HDD, SSD, USB 등)를 찾는다.
  4. ⭐️ 부트로더 실행: 부팅 가능한 장치의 MBR(또는 UEFI 환경의 ESP - 여기서 ESP는 레지스터가 아닌 파티션을 말함)에서 부트로더(예: GRUB, Windows Boot Manager 등)를 메모리로 로드하고 실행한다.
  5. 운영체제 로딩: 부트로더는 커널 이미지를 메모리에 적재하고, 운영체제 실행을 시작한다.

이 과정을 통해 저장 장치에 있는 운영체제를 CPU가 실행 가능한 상태로 만들 수 있다.

BIOS

메인보드에 내장된 펌웨어로, 컴퓨터가 켜졌을 때 가장 먼저 실행되는 프로그램이며,

  • 하드웨어 초기화(RAM, CPU, 키보드 등)
  • 부트 장치 탐색 및 부트스트랩 로더 실행
  • 간단한 I/O 인터페이스 제공 의 역할을 수행한다.
GRUB

GNU GRUB(Grand Unified Bootloader)은 리눅스 및 기타 운영체제를 부팅할 수 있게 해주는 대표적인 부트로더이다. BIOS 또는 UEFI가 부트로더를 메모리에 로드하면, GRUB은 사용자에게 운영체제 선택 메뉴를 제공하거나 자동으로 설정된 운영체제를 로드한다. GRUB은 멀티 부트 환경, 커널 파라미터 설정, 복구 모드 진입 등의 기능도 제공하며, 리눅스 배포판에서 널리 사용된다.

Fetch

CPU가 메모리에 저장된 명령어를 가져오는 과정을 말하며, 코드 조각이다.

  1. 프로그램 카운터(PC, Program Counter) 가 다음에 실행할 명령어의 메모리 주소를 가리킨다.
  2. CPU 는 해당 주소 기반으로 메모리에서 명령어를 가져와 Instruction Register(IR) 에 저장한다.
Program Counter

CPU 내부에 있는 특수한 레지스터로, 다음에 실행할 명령어의 메모리 주소를 저장한다. Fetch 단계에서 이 값을 참조하여 메모리에서 명령어를 가져오고, 명령어가 실행된 후에는 자동으로 다음 명령어 주소로 증가하거나, 분기(branch) 명령에 따라 새로운 주소로 갱신된다. 명령어 실행 흐름을 제어하는 핵심 요소이다.

Instruction Register

CPU 내부에 있는 레지스터로, 현재 실행 중인 명령어를 저장한다. Fetch 단계에서 메모리로부터 가져온 명령어는 이 레지스터에 임시로 저장되며, 이후 DecodeExecute 단계에서 참조된다. 프로그램 카운터(PC)가 다음 명령어를 가리키는 반면, Instruction Register는 현재 실행될 명령어의 내용을 담고 있다는 차이가 있다.

Address Stream

CPU가 메모리에 접근할 때 발생하는 연속적인 주소의 흐름이다. 즉, 메모리 주소를 순서대로 참조, 점프하여 다음 메모리 주소를 참조의 여러과정을 통해 주소들이 시간의 흐름에 따라 나열된 형태를 주소 스트림이라고 한다.

Tertiary Storage

3차 저장장치는 주로 백업 및 아카이빙 목적으로 사용되는 저장 장치이다. 접근 속도는 매우 느리지만, 저장 용량이 크고 비용이 저렴하다. 예로는 자기 테이프(magnetic tape), 광디스크(optical disc) 등이 있으며, 데이터를 장기간 보관하거나 자주 접근하지 않는 정보의 저장에 적합하다. 필요할 때만 로드되기 때문에 자동화된 장치(예: 테이프 라이브러리)를 사용하는 경우도 많다.

Cache

자주 접근되는 데이터를 빠른 메모리에 미리 저장하여, 느린 메모리 접근을 줄이고 전체 시스템 응답 속도를 개선한다.


🔗 출처