컴퓨터 구조 원리
서문
트랜지스터에서 CPU까지 배운 후, 컴퓨터는 어떻게 완전한 시스템을 구성할까? 이전 장에서 우리는 트랜지스터 출발하여 가산기, 레지스터, 연산 장치를 구성하고 최종적으로 CPU 코어를 만들어냈습니다. 하지만 CPU만으로는 부족합니다 — 메모리, I/O 장치와의 협력이 필요하고, 버스로 각 부품을 연결해야 하며, 명령어 체계로 구동해야 합니다. 이 장에서는 CPU의 내부 시각에서 전체 컴퓨터 시스템의 시각으로 전환하여, 폰노이만 구조, 명령어 체계, 저장 계층, 버스와 I/O의 전문 원리를 깊이 이해해 봅시다.
이 글에서 무엇을 배우게 될까요?
이 장을 마치면 다음을 얻게 됩니다:
- 시스템 관점: CPU, 메모리, I/O가 어떻게 협력하는지 이해 — 더 이상 고립된 하드웨어 애호가가 아닙니다
- 하드웨어 전문 용어: 명령어 사이클, 파이프라인, CPI, 캐시 적중률 등 핵심 개념 습득
- 성능 사고: 컴퓨터 구조의 병목과 최적화 수단 이해
- 후속 학습 기초: 운영체제, 컴퓨터 아키텍처, 임베디드 개발을 위한 전문 기초 확보
| 장 | 내용 | 핵심 개념 |
|---|---|---|
| 제 1장 | 폰노이만 구조 | 프로그램 내장 방식, 5대 구성 요소, 데이터 패스 |
| 제 2장 | 명령어 체계 | 명령어 형식, 어드레싱 모드, CISC vs RISC |
| 제 3장 | CPU 제어 장치 | 제어 유닛, 마이크로 오퍼레이션, 명령어 사이클 |
| 제 4장 | 저장 체계 | 캐시, 주기억장치, 가상 메모리, 페이징 기법 |
| 제 5장 | 버스와 I/O | 버스 중재, DMA, 인터럽트 기법 |
0. 전경도: 컴퓨터 하드웨어 시스템
이전 장 "트랜지스터에서 CPU까지"에서 CPU 내부가 어떻게 작동하는지 — 인출, 해독, 실행, 쓰기까지의 과정을 이해했습니다. 하지만 CPU 자체는 실행 장치일 뿐, 컴퓨터를 진정으로 "사용 가능"하게 만들려면 일련의 주변 부품의 협력이 필요합니다.
층별 해부: 컴퓨터 하드웨어 시스템
제1층: CPU 코어 명령어 실행을 담당하며, 제어 장치(제어 신호 발생)와 연산 장치(산술 논리 연산 실행)를 포함합니다
제2층: 레지스터 세트 CPU 내부의 고속 저장 장치로, 범용 레지스터와 전용 레지스터(PC, IR, MAR, MDR 등)를 포함합니다
제3층: 주기억장치 프로그램과 데이터를 저장하는 메모리로, CPU가 주소 버스와 데이터 버스를 통해 접근합니다
제4층: I/O 장치 입출력 장치가 I/O 컨트롤러를 통해 시스템 버스에 연결됩니다
제5층: 시스템 버스 CPU, 메모리, I/O를 연결하는 데이터 통로로, 주소 버스, 데이터 버스, 제어 버스를 포함합니다
1. 폰노이만 구조: 현대 컴퓨터의 "헌법"
1.1 프로그램 내장 방식
1945년, 수학자 존 폰 노이만(John von Neumann)은 획기적인 프로그램 내장(Stored-program) 아키텍처 사상을 제안했습니다. 이 사상은 현대 컴퓨터의 기초를 확립했습니다.
핵심 개념
프로그램 내장: 프로그램 자체가 특수한 데이터로서 일반 데이터와 마찬가지로 메모리에 저장됩니다. CPU는 데이터를 읽고 쓰는 것과 같은 방식으로 메모리에 저장된 프로그램 명령어를 읽고 실행할 수 있습니다.
이것이 의미하는 바:
- 초기 컴퓨터: 프로그램이 고정 배선으로 구현되었고, 프로그램을 변경하려면 회로를 다시 납땜해야 했습니다
- 폰노이만 구조: 프로그램이 메모리에 저장되어, 메모리 내용만 수정하면 프로그램을 변경할 수 있습니다
1.2 5대 구성 요소
폰노이만 구조는 컴퓨터를 5개의 핵심 구성 요소로 나눕니다:
| Feature | Register | Memory (RAM) |
|---|---|---|
| Location | Inside the CPU | Outside the CPU |
| Access speed | Fastest (< 1ns) | Slower (50-100ns) |
| Capacity | Tiny (bytes) | Large (GB) |
| Role | Hold instructions, operands, and results | Store programs and data |
| 부품 | 영문 | 기능 | 주요 구성 |
|---|---|---|---|
| 연산 장치 | ALU (Arithmetic Logic Unit) | 산술 및 논리 연산 실행 | 가산기, 시프터, 비교기 |
| 제어 장치 | CU (Control Unit) | 각 부품의 작업 지휘 및 조정 | 명령어 레지스터, 디코더, 타이밍 발생기 |
| 기억 장치 | Memory | 프로그램과 데이터 저장 | 메모리 주소 레지스터(MAR), 메모리 데이터 레지스터(MDR) |
| 입력 장치 | Input | 정보 입력 | 키보드, 마우스, 스캐너 |
| 출력 장치 | Output | 정보 출력 | 디스플레이, 프린터 |
1.3 데이터 패스
데이터 패스(Data Path)는 데이터가 각 기능 부품 사이를 흐르는 경로입니다. CPU 내부에서 데이터 패스는 다음을 연결합니다:
- 레지스터 세트
- 산술 논리 장치(ALU)
- 메모리 데이터 레지스터(MDR)
데이터 패스의 폭(한 번에 전송할 수 있는 비트 수)은 컴퓨터의 성능에 직접적인 영향을 미칩니다.
1.4 폰노이만 병목
폰노이만 구조에는 유명한 성능 병목이 있습니다:
CPU와 메모리 간의 데이터 전송 속도가 CPU의 처리 속도보다 훨씬 낮습니다.
이로 인해 CPU는 자주 "데이터 대기" 상태가 됩니다. 현대 컴퓨터의 많은 최적화 기술이 이 문제를 중심으로 전개됩니다:
| 최적화 기술 | 원리 |
|---|---|
| 캐시(Cache) | CPU 근처에 소용량 고속 저장 장치 배치 |
| 명령어 파이프라인 | 여러 명령어가 동시에 다른 단계에 있도록 함 |
| 슈퍼스칼라 | 동일 클럭 주기에 여러 명령어 발행 |
| 멀티코어 병렬 | 여러 CPU 코어가 연산 작업 분담 |
2. 명령어 체계: CPU와 소프트웨어의 인터페이스
이전 절에서 폰노이만 구조의 핵심 사상을 알게 되었습니다: 프로그램과 데이터는 동일하게 메모리에 저장됩니다. 하지만 이것은 핵심 질문을 하나 제기합니다 — 메모리에 저장된 "프로그램"은 실제로 어떤 모습일까요? CPU는 어떻게 이해할까요?
그 답이 바로 명령어 체계(Instruction Set Architecture, ISA)입니다. CPU를 하나의 서비스에 비유하면, 명령어 체계는 그 API 문서입니다 — CPU가 이해할 수 있는 모든 명령, 각 명령의 형식, 명령이 조작할 수 있는 데이터 범위를 정의합니다. 여러분이 작성하는 모든 코드는 결국 컴파일러에 의해 이 "API"의 호출 시퀀스로 번역됩니다.
2.1 코드에서 명령어까지: 한 줄 코드의 번역 여정
먼저 전체적인 인식을 가져봅시다: 여러분이 편집기에서 작성하는 코드와 CPU가 실제로 실행하는 것 사이에는 여러 층의 번역이 있습니다.
🔗 From Code to Instructions: One Line Through the Translation Pipeline
Click each stage to see how source code becomes CPU-executable instructions
int a = 10 + 5;
MOV R1, #10 ; put 10 into register R1 MOV R2, #5 ; put 5 into register R2 ADD R3, R1, R2 ; R3 = R1 + R2 STORE R3, [a] ; store the result at variable a
0001 0001 0000 1010 → MOV R1, #10 0001 0010 0000 0101 → MOV R2, #5 0010 0011 0001 0010 → ADD R3, R1, R2 0100 0011 1000 0000 → STORE R3, [a]
Clock 1: fetch → decode → execute MOV R1, #10 Clock 2: fetch → decode → execute MOV R2, #5 Clock 3: fetch → decode → execute ADD R3, R1, R2 Clock 4: fetch → decode → execute STORE R3, [a]
이 번역 체인은 명령어 체계를 이해하는 핵심입니다:
| 계층 | 내용 | 누가 이해할 수 있는가 |
|---|---|---|
| 고급 언어 | int a = 10 + 5; | 인간 |
| 어셈블리 언어 | MOV R1, #10 / ADD R3, R1, R2 | 인간(훈련 필요) |
| 기계어 | 0001 0001 0000 1010 | CPU |
이 체인을 이해해야 하는 이유
- 컴파일 에러를 볼 때, 오류가 "고급 언어 → 어셈블리" 단계에서 발생했다는 것을 알 수 있습니다
- 런타임 크래시를 볼 때, CPU가 명령어를 실행하는 단계에서 문제가 발생했음을 알 수 있습니다
- 성능 최적화를 이해할 때, 컴파일러가 "번역" 과정에서 어떤 최적화를 수행하는지 알 수 있습니다
- CPU 아키텍처 선택 시(x86 vs ARM), 차이가 "명령어 집합 API"에 있음을 알 수 있습니다
2.2 하나의 명령어는 어떤 모습인가?
코드가 명령어로 번역된다는 것을 알게 되었으니, 다음 질문은: 하나의 명령어의 내부 구조는 무엇인가?
각 기계 명령어는 본질적으로 이진수 문자열이지만, 엄격한 내부 형식이 있습니다. 가장 핵심적인 두 부분:
- 연산 코드(Operation Code, Opcode): CPU에게 '무엇을 할 것인가'를 알려줍니다 — 덧셈? 점프? 메모리 읽기?
- 피연산자(Operand): CPU에게 '누구에게 할 것인가'를 알려줍니다 — 어느 레지스터? 어느 메모리 주소? 어떤 상수?
문장에 '동사 + 목적어' 구조가 있듯, 명령어에도 '연산 + 대상' 구조가 있습니다:
명령어: ADD R3, R1, R2
─── ──────────
연산 코드 피연산자
(덧셈 수행) (R3 = R1 + R2)피연산자의 수에 따라 명령어 형식은 단순한 것부터 복잡한 것까지 네 가지로 나뉩니다:
| 형식 | 구조 | 예시 | 사용 시나리오 |
|---|---|---|---|
| 0주소 | 연산 코드만 | RET(복귀) | 스택 컴퓨터, 피연산자가 스택 최상단에 암시 |
| 1주소 | 연산 코드 + 1개 주소 | INC R1(R1을 1 증가) | 단일 피연산자 연산 |
| 2주소 | 연산 코드 + 2개 주소 | MOV R1, R2 | 가장 많이 사용, 데이터 전송 및 연산 |
| 3주소 | 연산 코드 + 3개 주소 | ADD R3, R1, R2 | 원본 피연산자를 파괴하지 않음 |
왜 이렇게 많은 형식이 있을까요?
이것은 공간과 유연성의 트레이드오프입니다. 0주소 명령어는 가장 짧지만(메모리 절약) 추가 스택 조작이 필요하고, 3주소 명령어는 가장 유연하지만(원본 데이터 불변) 더 많은 비트를 차지합니다. 서로 다른 CPU 아키텍처는 서로 다른 명령어 형식 조합을 선택합니다.
2.3 CPU는 어떻게 데이터를 찾을까? — 어드레싱 모드
명령어가 CPU에게 '덧셈을 하라'고 지시하지만, 덧셈의 두 수는 어디에 있을까요? 명령어에 직접 쓰여 있을 수도 있고, 레지스터에 있을 수도 있고, 메모리의 어떤 주소에 있을 수도 있습니다. 어드레싱 모드는 CPU에게 '어디에서 피연산자를 찾을 것인가'를 알려주는 규칙입니다.
일상에서 '사람을 찾는다'는 것에 비유해 봅시다:
| 어드레싱 모드 | 비유 | 명령어 예시 | 설명 |
|---|---|---|---|
| 즉치 어드레싱 | 그 사람이 당신 앞에 서 있음 | MOV R1, #100 | 데이터가 명령어에 직접 포함, 가장 빠름 |
| 레지스터 어드레싱 | 내선 전화로 동료에게 연락 | MOV R1, R2 | 데이터가 CPU 내부 레지스터에 있음, 매우 빠름 |
| 직접 어드레싱 | 문패 번호를 알고 직접 방문 | MOV R1, [0x1000] | 명령어에 메모리 주소가 포함됨 |
| 간접 어드레싱 | 안내 데스크에 "홍길동이 어느 방인가요?"라고 묻기 | MOV R1, [R2] | 레지스터에 주소가 저장되어 있어 한 번 더 조회 필요 |
| 색인 어드레싱 | "3호동 + 5층"으로 방 계산 | MOV R1, [R2+10] | 베이스 주소 + 오프셋, 배열 접근에 사용 |
MOV R1, #100| Addressing mode | Format | Speed | Use case |
|---|---|---|---|
| Immediate addressing | MOV R1, #100 | Fastest | Constant assignment and initialization |
| Register addressing | MOV R1, R2 | Fastest | Register-to-register data transfer |
| Direct addressing | MOV R1, [100] | Relatively fast | Accessing global variables |
| Indirect addressing | MOV R1, [R2] | Relatively fast | Pointers and array traversal |
| Indexed addressing | MOV R1, [R2 + R3] | Relatively fast | Array access and loops |
| Based addressing | MOV R1, [R2 + 100] | Relatively fast | Struct fields and function parameters |
| Relative addressing | JMP LABEL | Fastest | Loops and conditional branches |
왜 이렇게 많은 어드레싱 모드가 필요할까요?
서로 다른 시나리오에 서로 다른 '데이터 찾기' 전략이 필요합니다:
- 상수 할당(
x = 100) → 즉치 어드레싱, 데이터가 명령어 안에 있음 - 변수 연산(
a + b) → 레지스터 어드레싱, 데이터가 이미 레지스터에 로드됨 - 배열 접근(
arr[i]) → 색인 어드레싱, 베이스 주소 + 인덱스 오프셋 - 포인터 조작(
*ptr) → 간접 어드레싱, 레지스터에 주소가 저장되어 있음
arr[i]를 작성할 때 어드레싱 모드를 생각하지 않지만, 컴파일러가 자동으로 가장 적합한 방식을 선택합니다.
2.4 CPU의 능력 목록 — 명령어 분류
명령어의 형식과 어드레싱 모드를 알게 되었으니, 마지막 질문: CPU는 실제로 어떤 일을 할 수 있는가?
모든 명령어는 6대 유형으로 분류될 수 있으며, 컴퓨터가 할 수 있는 모든 작업을 포괄합니다:
| 유형 | 하는 일 | 대표 명령어 | 대응하는 코드 |
|---|---|---|---|
| 데이터 전송 | 데이터 이동 | MOV, LOAD, STORE | let x = y, 함수 매개변수 전달 |
| 산술 연산 | 사칙연산 | ADD, SUB, MUL, DIV | a + b, count++ |
| 논리 연산 | 비트 조작 | AND, OR, NOT, XOR | flags & 0xFF, 권한 판단 |
| 시프트 연산 | 좌우 이동 | SHL, SHR | x << 2(4를 곱하는 것과 동일) |
| 제어 이동 | 점프 및 호출 | JMP, CALL, RET | if, for, 함수 호출 |
| 입출력 | 외부 장치 통신 | IN, OUT | 키보드 읽기, 화면 쓰기 |
핵심 통찰
여러분이 작성하는 모든 코드 — 아무리 복잡한 비즈니스 로직, 아무리 화려한 UI 애니메이션 — 은 결국 이 6가지 기본 작업의 조합으로 분해됩니다. CPU의 "지능"은 복잡한 일을 할 수 있다는 것이 아니라, 이 간단한 작업들을 초당 수십억 번의 속도로 실행할 수 있다는 데 있습니다.
2.5 두 가지 설계 철학: CISC vs RISC
명령어 체계 설계에는 근본적인 분기가 있습니다: 각 명령어를 가능한 한 강력하게 만들 것인가, 아니면 가능한 한 단순하게 만들 것인가?
이 분기는 두 진영을 만들어냈고, 여러분이 오늘 사용하는 모든 기기에 직접적인 영향을 미칩니다:
⚔️ Two Design Philosophies: CISC vs RISC
Click a comparison dimension to see the core differences between instruction set styles
비유로 이해해 봅시다:
- CISC는 스위스 아미 나이프: 칼 한 자루에 가위, 병따개, 드라이버가 통합... 기능은 많지만 각각이 반드시 최고는 아닙니다
- RISC는 전문 도구 세트: 각 도구는 한 가지 일만 하지만, 빠르고 잘합니다
왜 여러분의 스마트폰은 ARM을, 컴퓨터는 x86을 사용할까요?
- x86(CISC)은 PC와 서버 시장을 40년간 지배하며 방대한 소프트웨어 생태계를 축적했습니다. 아키텍처 교체는 모든 소프트웨어의 재컴파일을 의미합니다
- ARM(RISC)은 저전력 소비의 장점으로 모바일 기기를 지배합니다. 휴대폰 배터리가 작아 매 밀리와트가 소중합니다
- Apple Silicon은 RISC도 고성능을 달성할 수 있음을 증명했습니다 — M 시리즈 칩이 성능과 전력 소비 모두에서 x86 경쟁작을 동시에 능가합니다
- RISC-V는 오픈 소스 RISC 아키텍처로, IoT, 교육, AI 칩 분야에서 빠르게 부상하고 있습니다
소결: 명령어 체계는 소프트웨어와 하드웨어를 연결하는 다리입니다. 여러분이 작성한 코드는 컴파일러를 통해 명령어로 번역되고, 명령어는 연산 코드와 피연산자를 통해 CPU에게 무엇을 할지, 누구에게 할지 알려주며, 어드레싱 모드는 데이터가 어디에서 오는지를 결정합니다. 서로 다른 명령어 집합 설계(CISC/RISC)는 CPU의 성능 특성과 적용 시나리오를 결정합니다.
이제 명령어의 '정적 구조' — 어떤 모습인지, 어떤 유형이 있는지 — 를 알게 되었습니다. 다음 질문은: CPU 내부에서 이 명령어들을 어떻게 단계별로 실행할까요? 이것이 제어 장치의 역할입니다.
3. 제어 장치: CPU의 "지휘 센터"
3.1 제어 장치의 구성
제어 장치는 CPU의 "두뇌"로, 각 부품이 명령어 요구에 따라 작업하도록 조정합니다:
| 구성 요소 | 기능 |
|---|---|
| 프로그램 카운터(PC) | 다음 명령어의 주소 저장 |
| 명령어 레지스터(IR) | 현재 실행 중인 명령어 저장 |
| 명령어 디코더 | 명령어의 연산 코드와 피연산자 분석 |
| 타이밍 발생기 | 클럭 비트 신호를 생성하여 각 부품의 타이밍 제어 |
| 마이크로 오퍼레이션 시퀀스 생성기 | 명령어 실행에 필요한 일련의 제어 신호 생성 |
3.2 명령어 사이클
CPU가 하나의 명령어를 실행하려면 완전한 명령어 사이클을 거쳐야 하며, 일반적으로 다음을 포함합니다:
- 인출 사이클(Fetch): 메모리에서 명령어를 읽어 IR로 가져옴
- 해독 사이클(Decode): 명령어의 의미 분석
- 실행 사이클(Execute): 연산 수행
- 메모리 접근 사이클(Memory Access): 메모리 접근이 필요한 경우 메모리에 접근
- 쓰기 사이클(Write Back): 결과를 레지스터나 메모리에 기록
3.3 마이크로 오퍼레이션
마이크로 오퍼레이션은 제어 신호에 의해 구동되는 가장 기본적인 작업입니다. 예를 들어, "인출" 단계는 다음 마이크로 오퍼레이션으로 분해될 수 있습니다:
| 클럭 비트 | 마이크로 오퍼레이션 | 제어 신호 |
|---|---|---|
| T1 | PC → MAR | PCout, MARin |
| T2 | MEM → MDR | MEMout, MDRin |
| T3 | MDR → IR | MDRout, IRin |
| T4 | PC + 1 → PC | PC+1, PCin |
3.4 하드와이어드 vs 마이크로그램 제어 장치
| 특성 | 하드와이어드 제어 장치 | 마이크로그램 제어 장치 |
|---|---|---|
| 구현 방식 | 조합 논리 회로 | 마이크로 명령어 시퀀스(펌웨어) |
| 속도 | 빠름 | 약간 느림 |
| 설계 난이도 | 복잡 | 비교적 간단 |
| 유연성 | 낮음(변경 시 회로 재설계 필요) | 높음(마이크로그램 수정만으로 가능) |
| 대표적 응용 | RISC 프로세서 | 초기 CISC 프로세서 |
4. 저장 체계: 왜 캐시가 필요한가?
4.1 저장 계층 구조
컴퓨터의 저장 장치는 피라미드 구조를 형성합니다:
| Storage level | Access time | Typical capacity | Cost |
|---|---|---|---|
| Registers | < 1 ns | A few KB | Highest |
| L1 cache | ~1 ns | 64 KB | Very high |
| L2 cache | ~3 ns | 256 KB | High |
| L3 cache | ~10 ns | 8 MB | Medium |
| Memory | ~100 ns | 8-32 GB | Medium-low |
| SSD | ~100 μs | 256 GB-2 TB | Low |
| HDD | ~10 ms | 1-10 TB | Lowest |
| 계층 | 저장 유형 | 접근 시간 | 전형적 용량 | 위치 |
|---|---|---|---|---|
| 레지스터 | SRAM | <1ns | 수 KB | CPU 내부 |
| L1 캐시 | SRAM | ~1ns | 32-64KB | CPU 코어 근처 |
| L2 캐시 | SRAM | ~3-10ns | 256KB-1MB | CPU 칩 내부 |
| L3 캐시 | SRAM | ~10-20ns | 2-16MB | CPU 칩 내부/공유 |
| 주기억장치(메모리) | DRAM | ~50-100ns | 8-64GB | 메인보드 |
| SSD | Flash | ~10-100μs | 256GB-2TB | 메인보드 |
| HDD | 자기 디스크 | ~5-10ms | 1-10TB | 케이스 내부 |
속도 차이의 비유
CPU가 L1 캐시에 접근하는 것을 책상 위에서 종이 한 장을 꺼내는 것에 비유한다면:
- 메모리 접근 → 엘리베이터를 타고 아래 편의점에 가서 종이를 사 오는 것
- SSD 접근 → 차를 몰고 다른 도시에 가서 종이를 사 오는 것
- HDD 접근 → 비행기를 타고 다른 나라에 가서 종이를 사 오는 것
속도 차이는 수백만 배에 달할 수 있습니다!
4.2 캐시 원리
캐시(Cache)는 CPU와 메모리 사이의 고속 저장 장치로, 그 핵심 사상은 두 가지 지역성 원리에 기반합니다:
지역성 원리
- 시간 지역성: 방금 접근한 데이터는 곧 다시 접근될 가능성이 높습니다
- 공간 지역성: 어떤 데이터가 접근되면 그 근처의 데이터도 곧 접근될 가능성이 높습니다
캐시의 작동 방식
- 적중(Hit): CPU가 원하는 데이터가 캐시에 있으면 바로 읽기
- 미스(Miss): 데이터가 캐시에 없으면 메모리에서 로드
적중률 = 적중 횟수 / 총 접근 횟수
평균 접근 시간 = 적중률 × 캐시 시간 + (1-적중률) × 메모리 시간4.3 캐시 매핑 방식
| 방식 | 원리 | 장점 | 단점 |
|---|---|---|---|
| 직접 매핑 | 각 메모리 블록이 하나의 고정 위치에만 배치 | 단순하고 빠름 | 충돌률이 높음 |
| 세트 연관 | 각 메모리 블록이 N개 위치에 배치 가능(N-way) | 속도와 적중률의 균형 | 구현이 복잡 |
| 완전 연관 | 임의의 위치에 배치 | 가장 낮은 충돌률 | 구현이 어려움(모든 태그 비교 필요) |
4.4 가상 메모리
가상 메모리는 운영체제가 제공하는 중요한 추상화입니다:
- 각 프로세스는 자신이 완전한 가상 주소 공간을 가지고 있다고 생각합니다
- 운영체제는 가상 주소를 물리 주소로 번역합니다
- 자주 사용하지 않는 페이지는 디스크로 스왑 아웃될 수 있습니다(스왑 공간)
가상 메모리의 비유
가상 메모리를 호텔의 방 관리에 비유해 봅시다:
- 당신(프로세스)은 건물 전체가 자신의 것이라고 생각합니다
- 실제로 호텔(OS)은 현재 필요한 방만 할당합니다
- 사용하지 않는 방은 창고(디스크)로 "스왑 아웃"됩니다
- 필요한 방은 언제든지 "스왑 인"할 수 있습니다
5. 버스와 I/O: 컴퓨터의 "혈관"
5.1 시스템 버스
버스(Bus)는 컴퓨터의 각 부품을 연결하는 데이터 통로입니다:
| 버스 유형 | 기능 | 방향 | 전형적 폭 |
|---|---|---|---|
| 주소 버스 | 메모리 주소 전송 | 단방향(CPU→메모리) | 32비트/64비트 |
| 데이터 버스 | 데이터 전송 | 양방향 | 32비트/64비트 |
| 제어 버스 | 제어 신호 전송 | 양방향 | 다중 신호 라인 |
5.2 버스 중재
여러 장치가 동시에 버스 사용을 요청할 때, 누가 먼저 사용할지 결정하는 중재 메커니즘이 필요합니다:
| 중재 방식 | 설명 |
|---|---|
| 집중 중재 | 중앙 중재기가 통일 결정 |
| 분산 중재 | 각 장치가 자체 협상 |
5.3 I/O 장치 접근 방식
| 방식 | 원리 | 장점 | 단점 |
|---|---|---|---|
| 프로그램 폴링 | CPU가 I/O 상태를 순환 검사 | 단순함 | CPU 활용률 낮음 |
| 인터럽트 방식 | I/O 완료 후 CPU에 능동 통지 | CPU가 병렬 작업 가능 | 인터럽트 처리에 오버헤드 발생 |
| DMA | I/O 장치가 메모리에 직접 접근 | CPU가 전혀 참여하지 않음 | DMA 컨트롤러 필요 |
| Feature | Programmed I/O | Interrupt-driven I/O | DMA |
|---|---|---|---|
| CPU involvement | Involved throughout | Only handles interrupts | Almost uninvolved |
| Data transfer | CPU moves each byte | CPU moves each word | Device transfers directly to memory |
| Pros | Simple and flexible control | High CPU efficiency | CPU is fully freed |
| Cons | Low CPU utilization | Interrupt overhead | Complex hardware |
| Best for | Simple or low-speed devices | Low/medium-speed devices | High-speed bulk transfer |
5.4 DMA 원리
DMA(Direct Memory Access, 직접 메모리 접근)은 I/O 장치가 메모리와 직접 데이터를 교환할 수 있게 합니다:
- DMA 없이: CPU가 데이터 전송에 전 과정 참여, CPU가 다른 작업을 할 수 없음
- DMA 있이: CPU가 DMA 컨트롤러에게 "어디서 어디로, 얼마나 전송할지" 알려준 후 다른 작업 실행, DMA 완료 후 CPU에 통지
DMA의 비유
이것은 배달 주문과 같습니다:
- DMA 없이: 직접 마트에 가서 식재료를 사고, 집에 돌아와 씻고, 요리함(전 과정 참여)
- DMA 있이: 전화로 주문하고, 배달원이 부엌까지 직접 배달(다른 사람이 대신 처리, 마지막에 "수령"만 하면 됨)
5.5 인터럽트 기법
인터럽트는 컴퓨터 시스템에서 매우 중요한 메커니즘입니다:
- I/O 장치가 작업을 완료한 후 CPU에 인터럽트 요청 전송
- CPU가 명령어를 실행 중이면, 현재 명령어 완료 후 인터럽트에 응답
- CPU가 현재 상태를 저장하고 인터럽트 처리 루틴으로 점프
- 처리 완료 후 상태를 복원하고 계속 실행
6. CPU 성능 최적화: 파이프라인 기술
6.1 명령어 파이프라인
명령어 파이프라인은 CPU의 효율을 극대화하는 병렬 기술입니다:
Sequential execution: each instruction finishes before the next starts, so N instructions require N × 5 cycles.
Pipeline execution: multiple instructions occupy different stages at once; ideally CPI ≈ 1.
파이프라인의 작동 원리
순차 실행(5개 명령어, 15 사이클):
명령어1: IF→ID→EX→MEM→WB
명령어2: IF→ID→EX→MEM→WB
명령어3: IF→ID→EX→MEM→WB
...
파이프라인 실행(5개 명령어, 9 사이클):
명령어1: IF→ID→EX→MEM→WB
명령어2: IF→ID→EX→MEM→WB
명령어3: IF→ID→EX→MEM→WB
...이상적으로 N개 명령어의 CPI(명령어당 클럭 사이클 수) ≈ 1
6.2 파이프라인 해저드
파이프라인은 성능을 향상시킬 수 있지만, 해저드(Hazard) 문제도 가져옵니다:
| 유형 | 원인 | 해결책 |
|---|---|---|
| 구조적 해저드 | 하드웨어 자원 충돌 | 하드웨어 추가/실행 시간 조정 |
| 데이터 해저드 | 뒤의 명령어가 앞의 결과를 필요로 함 | 데이터 포워딩/버블/스케줄링 |
| 제어 해저드 | 분기 명령어가 실행 흐름 변경 | 지연 슬롯/분기 예측 |
7. 요약: 컴퓨터는 어떻게 "작동"하는가?
전문 용어로 전체 과정을 연결해 봅시다:
프로그램이 시작되면, 운영체제는 실행 파일을 디스크에서 메모리로 로드합니다. CPU의 인출 장치(IF)가 주소 버스를 통해 메모리에서 명령어를 읽어 명령어 레지스터(IR)로 가져옵니다. 제어 장치가 명령어를 해독(ID)하여 연산 유형을 식별한 후 해당 제어 신호를 발생시킵니다. 연산 장치(EX)가 산술 논리 연산을 수행하고, 메모리 접근이 필요한 경우 데이터 버스를 통해 메모리에 접근(MEM)하며, 마지막으로 결과를 레지스터나 메모리에 기록(WB)합니다. 전체 과정은 클럭에 의해 구동되며, 제어 장치가 발생시키는 마이크로 오퍼레이션 시퀀스가 각 부품이 질서 있게 작동하도록 조정합니다.
더 읽어보기
| 주제 | 추천 심화 학습 내용 |
|---|---|
| 컴퓨터 아키텍처 | "컴퓨터 구성 및 설계: 하드웨어/소프트웨어 인터페이스" - Patterson & Hennessy |
| CPU 마이크로아키텍처 | "컴퓨터 시스템의 이해" - Bryant & O'Hallaron |
| 명령어 집합 아키텍처 | ARMv8 아키텍처 매뉴얼, Intel x64 매뉴얼 |
| 캐시 원리 | 캐시 일관성 프로토콜(MESI), 캐시 쓰기 정책 |
| 운영체제 | 다음 장 "운영체제" |
다음 단계
이제 컴퓨터 구조 원리의 전문 지식을 마스터했습니다. 다음으로 계속 학습할 수 있습니다:
- 운영체제: 프로그램이 운영체제 위에서 어떻게 실행되는지, 프로세스, 스레드, 메모리 관리가 어떻게 구현되는지 이해
- 데이터의 인코딩, 저장과 전송: 데이터가 컴퓨터에서 어떻게 표현되는지 심층 이해