오늘은 책을 읽고 정리해 본 CS 개념이다! (공부할 겸 정리해서 올려본다.)
1. 컴퓨터 구조의 큰 그림
컴퓨터가 이해하는 정보
- 컴퓨터가 다루는 것: 데이터 + 명령어
컴퓨터의 핵심 부품
-> CPU(중앙처리장치), 메모리(주기억장치), 캐시메모리, 보조기억장치, 입출력장치
CPU
CPU는 명령어를 읽고, 해석하고, 실행하는 핵심 부품이다.
- 산술논리연산장치(ALU): 사칙연산, 논리연산을 수행한다.
- 제어장치(CU): 명령어를 해석하고 각 부품에 제어 신호를 보낸다.
- 레지스터: CPU 내부의 임시 저장장치로, 처리 과정에서 필요한 데이터를 일시 저장한다.
메모리와 캐시 메모리
- 메모리(RAM)는 현재 실행 중인 프로그램의 데이터와 명령어를 저장한다. 메모리는 주소를 통해 접근하며, 휘발성이기 때문에 전원이 꺼지면 내용이 사라진다.
- 캐시 메모리는 CPU가 메모리 접근 속도를 높이기 위해 사용하는 고속 저장장치로, CPU 내부(L1, L2, L3 캐시)에 위치하기도 한다.
보조기억장치
- 보조기억장치는 전원이 꺼져도 데이터가 유지되는 비휘발성 저장장치이다.
- 대표적으로 하드디스크, SSD, USB, SD카드 등이 있으며, 메모리를 보조하는 역할을 한다.
- 프로그램은 보조기억장치에 저장되어 있다가 실행 시 메모리로 복사되어 동작한다.
입출력장치
- 입출력장치는 컴퓨터 외부와 내부가 정보를 주고받는 장치이다.
- 입력장치(키보드, 마우스)와 출력장치(모니터, 프린터)가 있다.
- 보조기억장치도 넓은 의미에서는 특별한 입출력장치로 볼 수 있다.
메인보드와 버스
- 메인보드(마더보드)는 모든 핵심 부품을 물리적으로 연결하는 기판이다.
- 부품 간에는 버스(bus)라는 데이터 통로를 통해 신호가 전달된다. 이 중 시스템 버스가 가장 핵심적인 역할을 한다.
저장장치의 계층 구조
- CPU와 가까운 저장장치는 빠르고 용량이 작으며 비싸고, 멀리 있을수록 느리고 용량이 크며 싸다.
- 일반적인 계층 구조는 레지스터 → 캐시(L1/L2/L3 캐시) → 메모리 → 보조기억장치 순이다.
2. 컴퓨터가 이해하는 정보
명령어
- 명령어 = 연산코드(OPCODE) + 오퍼랜드(데이터/주소)
- 명령어는 수행할 동작과 수행할 대상으로 이루어짐.
- 오퍼랜드에 주소필드가 명시되어 있다면 명령어를 실행하기 위해 추가 메모리 접근(간접 단계)이 필요할 수 있음.
기계어와 어셈블리어
- 기계어 - 0과 1로 표현된 CPU가 직접 이해하는 언어
- 어셈블리어 - 기계어를 사람이 읽기 쉽게 변환한 형태로, CPU마다 명령 체계가 다르다.
명령어 사이클
- CPU는 프로그램을 실행할 때 명령어 인출(Fetch)과 실행(Execute) 과정을 반복한다.
- 필요시 오퍼랜드를 추가로 읽는 간접 사이클이 포함될 수 있다.
- ex. 인출사이클 → 실행사이클 → 인출사이클 →.. 이런 식 / 인출 사이클 → 간접 사이클 → 실행사이클 이런 형식도 추가됨
명령어 사이클: 프로그램 속 각각 명령어는 일정한 주기를 반복하며 실행되는데 이 주기를 뜻한다.
- 인출 사이클: 메모리에 있는 명령어를 CPU로 가져오는 단계
- 실행 사이클: CPU로 가져온 명령어를 실행하는 단계
- 간접 사이클: 명령어를 실행하기 위해 한번 더 메모리에 접근하는 단계
3. CPU
레지스터
CPU안에 있는 작은 임시 저장장치. 다양한 레지스터가 있고, 서로 다른 이름과 역할이 있다.
- PC(프로그램 카운터): 메모리에서 다음 인출할 명령어 주소 저장(분기 시 연속적 증가 아님)
- IR(명령어 레지스터): 해석할 명령어, 메모리에서 방금 가져온 명령어 저장(제어장치가 이 명령어를 해석)
- 범용 레지스터: 다양하고 일반적인 상황에서 자유롭게 사용. 연산 중간값/주소/데이터 임시 저장
- 플래그 레지스터: 부호/제로/캐리/오버플로우 등 부가 정보인 플래그 저장
- 스택 포인터: 콜/리턴, 지역변수 등 스택 프레임(실행 중인 프로그램들) 관리
인터럽트
인터럽트(interrupt)는 CPU가 수행 중인 작업이 일시적으로 중단되는 현상이다.
원인에 따라 다음과 같이 구분된다.
- 동기 인터럽트(예외): CPU 내부에서 발생 (예: 0으로 나누기, 잘못된 메모리 접근)
- 비동기 인터럽트(하드웨어 인터럽트): 입출력장치 등 외부 요인으로 발생 (예: 키보드 입력, 프린터 완료 신호)
- 막을 수 있는 인터럽트
- 막을 수 없는 인터럽트
하드웨어 인터럽트
CPU는 효율적으로 명령어를 처리하기 위해 하드웨어 인터럽트 사용한다.
보통 입출력장치 속도는 CPU에 비해 느리기 때문에 바로 결과를 받아볼 수 없다. 따라서 인터럽트를 사용하지 않는다면 주기적으로 완료 여부를 확인해야 한다(폴링). 하지만 하드웨어 인터럽트를 사용하면 입출력장치가 완료될 동안 다른 작업을 처리할 수 있다.
-> 따라서 CPU 사이클 낭비를 최소화하고, CPU가 다른 일을 수행할 시간을 벌어줌으로써 효율적으로 명령어 처리 가능
하드웨어 인터럽트의 동작 순서
- 입출력장치가 CPU에 인터럽트 요청 신호를 보냄
- CPU는 명령 실행 후 항상 인터럽트 요청 여부를 확인
- 인터럽트 플래그를 통해 인터럽트 수용 가능 시 현재 작업 상태를 백업
- CPU는 인터럽트 벡터를 참조해 해당 인터럽트 서비스 루틴을 실행
- 인터럽트 서비스 루틴이 끝나면 백업된 상태를 복구하고 원래 작업으로 복귀
인터럽트 플래그는 인터럽트를 허용할지 여부를 결정한다. 모든 하드웨어 인터럽트를 막을 수 있는 것은 아니고, 일부 중요한 인터럽트(정전, 하드웨어 고장 등)는 우선순위가 높아 가장 먼저 처리해야 한다.
인터럽트 서비스 루틴(인터럽트 핸들러)은 인터럽트를 처리하기 위한 프로그램이다. 어떤 인터럽트가 발생했을 때 어떻게 처리하고 작동해야 할지에 대한 정보이다.
인터럽트 백터는 인터럽트 서비스 루틴을 식별하기 위한 정보이다. 서비스 루틴의 시작주소를 포함하고 있다.
인터럽트 사이클은 1. 인터럽트 서비스 루틴을 실행하고, 2. 본래 수행하던 작업으로 되돌아오는 것이다.
예외(동기 인터럽트)
예외(Exception)는 동기 인터럽트의 일종으로, 다음과 같이 분류된다.
- 폴트(Fault): 예외 처리 후 해당 명령어부터 재실행
- 트랩(Trap): 예외 처리 후 다음 명령어 실행
- 중단(Abort): CPU가 실행 중인 프로그램을 강제 종료(심각한 오류)
- 소프트웨어 인터럽트: 시스템 콜 등에서 발생
CPU 성능 향상을 위한 설계
클럭 속도
- 클럭(clock)은 CPU가 명령어를 수행하는 리듬 단위이다.
- 클럭 속도(Hz)는 초당 몇 번의 클럭이 발생하는지를 나타내며, 높을수록 빠르다. (요즘은 빨라져서 GHz, 기가 헤르츠로 측정)
- 하지만 클럭 속도를 지나치게 높이면 발열이 커지고 효율이 떨어진다.
멀티코어와 멀티스레드
멀티 코어
- 코어(core)는 CPU 안에서 명령어를 읽고 해석하고 실행하는 독립적인 처리 단위이다.
- 여러 코어를 가진 CPU를 멀티코어 프로세서(멀티코어 CPU)라고 한다.
예를 들어 ‘8코어 CPU’라면 CPU 내부에 명령어를 처리할 수 있는 코어가 8개 존재하는 것이며, 이러한 구조의 CPU를 멀티코어 프로세서(Multi-core Processor)라고 한다. 멀티코어는 여러 프로그램이나 스레드를 병렬로 실행하여 전체 처리량(throughput)을 크게 높일 수 있다.
멀티스레드(Multi-thread)
- 스레드는 실행 흐름의 단위이다.
- CPU 입장에서는 한 코어가 동시에 여러 명령어 흐름을 처리할 수 있음을 의미한다.
하드웨어 스레드는 코어가 물리적으로 동시에 처리할 수 있는 명령어의 개수를 뜻하며, 한 코어에서 여러 스레드를 병렬로 실행하는 기술을 하이퍼스레딩(Hyper-threading)이라고 부른다.
- 1코어 1스레드 CPU → 한 번에 1개의 명령어 처리
- 2코어 4스레드 CPU → 두 코어가 각각 2개씩, 총 4개의 명령어를 동시에 처리
운영체제는 이를 각각의 논리 프로세서(logical processor)로 인식한다.
‘스레드’는 CPU 구조뿐 아니라 프로그램 영역에서도 사용된다. 따라서 두 용어를 구분해 이해해야 한다.
- 하드웨어 스레드: 코어가 동시에 처리할 수 있는 물리적 실행 단위. 병렬성(parallelism)을 구현.
- 소프트웨어 스레드: 하나의 프로그램 내에서 독립적으로 실행되는 논리적 단위. 동시성(concurrency)을 구현.
즉, 하드웨어 스레드는 실제 동시에 여러 작업을 수행하는 구조이고, 소프트웨어 스레드는 단일 코어에서도 번갈아가며 실행되어 ‘동시에 동작하는 것처럼’ 보이게 한다.
병렬성과 동시성
- 병렬성(Parallelism)은 여러 작업을 물리적으로 동시에 처리하는 성질
- 동시성(Concurrency)은 (싱글 코어에서) 여러 작업을 빠르게 번갈아 처리해 동시에 실행되는 것처럼 보이게 하는 성질
하드웨어 스레드는 병렬성을 구현하기 위한 물리적 단위이고, 소프트웨어 스레드는 동시성을 구현하기 위한 논리적 단위라고 할 수 있다.
파이프라이닝을 통한 명령어 병렬 처리
명령어 병렬 처리 기법
- CPU는 여러 명령어를 동시에 처리하여 쉬지 않고 작동하게 함으로써 성능을 높인다.
- 다양한 종류가 있지만 중요한 명령어 병렬 처리 기법은 명령어 파이프라이닝이다.
명령어 파이프라이닝
하나의 명령어를 처리하는 과정을 여러 단계로 나누고, 서로 다른 단계의 명령어를 (하나의 스레드 안에서) 동시에 실행하는 기법이다. 즉, 공장에서 생산라인을 구성하듯 명령어 파이프라인을 겹쳐서 실행하는 것이다.
명령어 처리 과정은 일반적으로 다음 4단계로 구분된다.
- 명령어 인출(Fetch)
- 명령어 해석(Decode)
- 명령어 실행(Execute)
- 결과 저장(Write Back)
예를 들어, 명령어 1이 실행 단계에 있을 때 명령어 2는 해석 단계, 명령어 3은 인출 단계에 있을 수 있다. 이렇게 하면 각 단계가 겹쳐 작동하면서 CPU의 유휴 시간이 줄어들고 처리율이 증가한다.
슈퍼스칼라(Superscalar) 구조
오늘날 대부분의 CPU는 여러 개의 파이프라인을 이용한다. 즉, 여러 명령어를 동시에 파이프라인에 투입할 수 있다. 이처럼 병렬 파이프라인 구조를 가진 CPU를 슈퍼스칼라 프로세서(슈퍼스칼라 CPU)라 한다.
CISC와 RISC
CPU 명령어 집합 구조는 크게 CISC와 RISC로 나뉜다. (명령어를 어떻게 자르는지에 대한 방법이라고 생각하면 될 것 같다.)
- CISC (Complex Instruction Set Computer): 다양한 기능을 가진 복잡한 명령어로 구성되어, 적은 수의 명령어로 많은 일을 수행할 수 있다. 명령어가 복잡하고 길이가 일정하지 않아 파이프라이닝에 비효율적이다.
- RISC (Reduced Instruction Set Computer): 단순하고 규격화된 명령어 집합으로 구성되어, 대부분의 명령이 한 클럭 내에 실행된다. 같은 프로그램이라도 CISC보다 많은 명령어가 필요하다. 명령어 크기가 일정하고 단순해 파이프라이닝 효율이 높다.
파이프라인 해저드(Pipeline Hazard)
- 데이터 위험(Data hazard): 명령어 간 데이터 의존성 때문에 뒤의 명령이 앞의 결과를 기다려야 하는 상황.
- 제어 위험(Control hazard / Branch hazard): 분기(JUMP/조건분기, 인터럽트 등)로 프로그램 카운터(PC)가 갑자기 바뀌며, 미리 인출/해석한 명령이 무효가 되어 버림.
- 구조적 위험(Structural hazard/ =자원위험): 두 명령이 동일 자원(ALU, 레지스터 파일, 메모리 포트 등)을 동시에 쓰려할 때 충돌.
이러한 상황에서는 파이프라인이 멈추거나(flush) 재조정되어 성능 저하가 발생한다.
4. 메모리
실행 중인 프로그램은 메모리에 저장되며, CPU는 메모리에 있는 데이터를 읽고 실행한다.
RAM
- RAM은 휘발성 저장장치로, 전원이 꺼지면 내용이 사라진다. CPU가 실행할 프로그램과 데이터를 저장하며, 저장된 요소에 순차적으로 접근할 필요 없이 곧장 접근 가능한 직접 접근(임의접근)이 가능하다.
ROM은 비휘발성으로, 펌웨어처럼 변경되지 않는 데이터를 저장한다. - RAM의 용량이 클수록 더 많은 프로그램을 동시에 실행할 수 있다. (다만 일정 이상 용량이 커진다고 해서 CPU 성능이 비례적으로 향상되지는 않는다.)
RAM의 종류
- DRAM (Dynamic RAM): 시간이 지나면 저장된 데이터가 소멸되어 일정 주기로 재활성화가 필요함. 소비 전력이 낮고 저렴하고 집적도가 높아 대용량 메모리에 적합해서 일반적으로 사용한다.
- SRAM (Static RAM): 저장된 데이터가 사라지지 않으며 속도가 매우 빠르다. 대신 가격이 비싸고 전력소모가 커, 주로 캐시 메모리에 사용된다.
- SDRAM (Synchronous DRAM): 클럭 신호와 동기화되어 CPU와 데이터를 주고받는 DRAM. 타이밍에 맞춰 CPU와 정보를 주고받을 수 있다.
- DDR SDRAM (Double Data Rate SDRAM): 대역폭을 넓혀 속도를 빠르게 만든 SDRAM. 한 클럭당 2회 데이터 전송이 가능하다. DDR2, DDR3, DDR4, DDR5 등으로 발전하며, 세대가 높을수록 대역폭이 넓고 전송 속도가 빠르다.
메모리에 바이트를 밀어 넣는 순서 - 빅 엔디안과 리틀 엔디안
CPU가 여러(4, 8, 워드단위) 바이트로 구성된 데이터를 메모리에 저장할 때, 어떤 순서로 저장할지에 따라 구분된다.
- 빅 엔디안(Big-endian): 상위 바이트를 낮은 주소에 저장
- 리틀 엔디안(Little-endian): 하위 바이트를 낮은 주소에 저장
현대 대부분의 CPU(x86 등)는 리틀 엔디언을 사용한다. 리틀 엔디언은 연산 시 효율적이고, 빅 엔디언은 사람이 읽기 쉬운 구조다.
MSB는 숫자의 크기에 가장 큰 영향을 미치는 유효숫자로 가장 왼쪽의 비트를 말하고, LSB는 숫자의 크기에 가장 적은 영향을 미치는 유효숫자로 가장 오른쪽의 비트를 말한다. 1234라면 MSB는 1, LSB는 4일 것이다. 따라서 빅 엔디안이 MSB가 있는 바이트, 즉 중요하고 큰 데이터부터 저장해 나가는 방식이라면, 리틀 엔디안은 LSB가 있는 바이트, 즉 덜 중요하고 작은 데이터부터 저장해 나가는 방식이다.
캐시 메모리(Cache Memory)
CPU와 메모리의 속도 차이를 줄이기 위한 CPU와 메모리 사이에 위치한 SRAM 기반의 저장장치이다. 자주 사용할 데이터를 예측하여 미리 저장함으로써 CPU 접근 속도를 높인다.
일반적으로,
- L1 캐시: 각 코어별로 존재, 가장 빠르지만 용량이 작다.
- L2 캐시: 각 코어별로 존재, L1보다 느리지만 용량이 크다.
- L3 캐시: 여러 코어가 공유, 가장 느리지만 대용량이다.
L1 캐시 메모리는 명령어만 저장하는 L1 캐시인 L1I 캐시와 데이터만을 저장하는 L1캐시인 L1D 캐시로 구분되기도 한다. 이는 분리형 캐시라고 한다.
캐시 히트와 캐시 미스
- 보조저장장치는 전원이 꺼져도 보관할 것을 저장하고, 메모리가 실행 중인 것을 저장한다면, 캐시 메모리는 CPU가 사용할 법한 것을 저장한다.
- 캐시 히트(Cache Hit)는 요청한 데이터가 캐시에 있는 경우, 캐시 미스(Cache Miss)는 없는 경우로, CPU 성능은 캐시 히트율에 큰 영향을 받는다.
- 캐시 적중률 = 캐시 히트 횟수 / (캐시 히트 횟수 + 캐시 미스 횟수)
참조 지역성의 원리(Locality of Reference)
CPU가 사용할 법한 데이터 예측 방법이다. 캐시 메모리는 참조 지역성의 원리라는 특정한 원칙에 따라 메모리로부터 가져올 데이터를 결정한다.
- 시간 지역성: 최근 접근한 데이터는 다시 접근할 가능성이 높다. (가장 잘 보이는 사례: 변수)
- 공간 지역성: 접근한 데이터 근처의 데이터도 곧 접근될 가능성이 높다. (가장 잘 보이는 사례: 배열)
캐시 메모리의 쓰기 정책과 일관성
CPU가 캐시 메모리에 데이터를 쓸 때는 캐시와 메모리의 내용이 일관되게 유지되어야 한다. 이를 위해 두 가지 쓰기 방식이 사용된다.
1. 즉시 쓰기(Write-through)
- 데이터를 캐시에 쓸 때 메모리에도 동시에 즉시 반영하는 방식
- 항상 최신 상태 유지 → 일관성 보장.
- 하지만 매번 메모리에 접근해야 하므로 속도가 느림(버스 사용 시간 + 쓰기 시간)
2. 지연 쓰기(Write-back)
- 데이터를 우선 캐시에만 기록하고, 나중에 한 번에 메모리에 반영하는 방식
- 속도는 빠르지만, 메모리와 캐시 사이에 데이터 불일치 위험 존재.
또한 멀티코어 환경에서는 각 코어가 가진 캐시 간에도 데이터가 달라질 수 있어 캐시 일관성(Cache Coherency) 문제가 발생한다. 이런 문제를 해결하기 위해 캐시 일관성 프로토콜이 사용된다.
네트워크에서도 캐시는 등장한다. 자주 사용할 법한 대상을 가까이 위치함으로써 성능 향상을 꾀한다는 점이 같다.
5. 보조기억장치와 입출력장치
보조기억장치는 메모리의 휘발성을 보완하고, 더 큰 저장 공간을 제공한다.
주요 기능 2가지
- 전원이 꺼져도 데이터를 안전하게 보관
- CPU가 필요로 하는 정보를 빠른 속도로 메모리로 전달
오늘날 널리 사용되는 보조기억장치는 크게 두 가지이다.
(1) 하드 디스크 드라이브 (HDD)
- 자기적인 방식으로 데이터를 읽고 쓰는 장치
- 내부 구조
- 플래터(Platter): 원판 모양의 저장 매체
- 헤드(Head): 플래터 위의 데이터를 읽고 쓰는 장치
- 스핀들(Spindle): 플래터를 고속 회전시키는 축
- 장점: 대용량, 저가격
- 단점: 속도 느림, 기계적 충격에 약함
(2) 플래시 메모리 기반 저장장치 (Flash Memory)
- 전기적 방식으로 데이터를 읽고 쓰는 반도체 저장장치
- 대표 예시: USB 메모리, SD카드, SSD
- 특히 SSD(Solid-State Drive)는 플래시 메모리를 이용한 고속 보조기억장치로, 노트북이나 데스크탑의 기본 저장장치로 자리 잡음
- 장점: 빠른 속도, 내충격성, 소음 없음
- 단점: 상대적으로 고가, 수명 제한(쓰기 횟수)
보조기억장치는 “데이터를 얼마나 안전하고 빠르게 관리할 수 있는가" 가 중요하다. 이를 위해 사용되는 대표 기술이 바로 RAID이다.
RAID
RAID(Redundant Array of Independent Disks)는 여러 개의 디스크를 하나처럼 묶어 성능이나 안정성을 높이는 기술이다. RAID를 구성하는 방법에는 여러 가지가 있고 이를 RAID 레벨이라고 표현한다. RAID0, 1,.. 6이 대표적이며 10, 50 등이 파생되었다.
| RAID 0 | 단순하게 나누어 저장하는 구성 방식(스트라이핑, Striping), 빠르지만 복구 불가하기 떄문에 정보가 안전하지 않음 |
| RAID 1 | 완전한 복사본을 만들어 저장하는 구성 방식(미러링, Mirroring), 복구가 간단하고 안정성 높지만 용량 절반 감소 |
| RAID 4 | 패리티 정보를 저장하는 디스크를 따로 두는 방식, 패리티란 오류를 검출할 수 있는 정보. 1에 비해 적은 하드 디스크로 안전하게 보관 가능하지만 저장하는 장치에 병목 현상 발생 |
| RAID 5 | 패리티를 분산 저장하는 구성 방식, 4에 비해 병목 현상 보완 가능 |
| RAID 6 | 서로 다른 패리티 2개 두는 구성 방식(오류 검출, 복구 수단이 2개), 안정성 강화, 속도는 5에 비해 느림 |
RAID는 성능 향상 목적(0), 복구 목적(1), 또는 균형 목적(5,6)으로 구성된다. 예외로 RAID 레벨을 혼합해서 사용하는 방식, Nested RAID가 있다.
입출력 기법
입출력장치는 CPU와 외부 장치를 연결하는 통로이다. 입력장치(키보드, 마우스)와 출력장치(모니터, 프린터)가 있으며,
보조기억장치(메모리를 보조하는 임무를 수행하는 특별한 입출력장치)도 넓은 의미의 입출력장치로 포함된다.
장치 컨트롤러와 장치 드라이버
장치 컨트롤러(Device Controller): CPU와 각 입출력장치 사이를 중개하는 하드웨어이다.
- 장치별 전기/프로토콜 차이를 표준화해 레지스터로 노출
- 내부에 버퍼(RAM 성격)를 갖기도 하며, 전송 중간값을 임시 저장
- 작업 중 분리하면 데이터 손상 위험 → 따라서 안전하게 제거 필요
장치 드라이버(Device Driver): 컨트롤러의 동작을 알리고, 컨트롤러를 제어하는 운영체제 내부 프로그램(커널 모듈)이다.
- 컨트롤러 레지스터 맵, 명령셋을 이해하고 OS API로 추상화
- 일반 장치는 OS 기본 드라이버로 동작, 특수 장치는 별도 설치 필요
장치 컨트롤러는 하드웨어, 장치 드라이버는 소프트웨어이다. CPU는 드라이버를 통해 컨트롤러에 명령을 전달한다.
프로그램 입출력(Programmed I/O)
CPU가 프로그램 명령어로 컨트롤러와 직접 상호작용하는 방식이다. 즉, CPU가 모든 입출력 과정을 직접 관리한다.
CPU는 장치가 준비되었는지 계속 확인(polling)하면서 데이터를 주고받는다. 구현은 단순하지만 CPU의 자원 낭비가 심하다.
고립형 I/O (Isolated I/O)
- 메모리와 입출력 주소 공간이 분리되어 있다.
- 입출력 전용 명령어(IN, OUT 등)가 필요하다.
메모리 맵 I/O (Memory-Mapped I/O)
- 입출력 장치의 레지스터를 메모리 주소공간 일부로 매핑한다.
- 별도의 명령어 없이 메모리 접근 명령으로 I/O가 가능하다.
인터럽트 기반 입출력(Interrupt-Driven I/O): 다중 인터럽트
장치가 작업을 마치면 인터럽트 신호를 발생시켜 CPU에 알리는 방식이다. CPU는 다른 일을 하다가 인터럽트를 받으면 즉시 해당 장치의 인터럽트 서비스 루틴을 실행한다. 덕분에 CPU는 폴링으로 시간을 낭비하지 않고 효율적으로 동작한다. 하지만 우선순위나 중첩 처리 등 관리가 복잡하다.
다중 인터럽트 처리
- 여러 장치가 동시에 인터럽트를 발생시킬 수 있다.
- 이때는 우선순위(priority)가 높은 장치부터 처리한다.
- 이를 처리하기 위한 하드웨어는 프로그래머블 인터럽트 컨트롤러(PIC, Programmable Interrupt Controller)이다.
- PIC는 여러 장치의 인터럽트 요청을 받아 우선순서를 판별한 뒤 CPU에 전달한다.
- 일반적으로 PIC는 많은 하드웨어 인터럽트를 관리하기 위해 2개 이상의 계층으로 구성된다.
인터럽트 종류
- 마스커블 인터럽트(Maskable) : 필요 시 허용 또는 차단 가능하다.
- 비마스커블 인터럽트(NMI, Non-Maskable) : 무시할 수 없는 중요한 인터럽트이다.
DMA 입출력(Direct Memory Access)
프로그램 기반의 입출력과 인터럽트 기반의 입출력의 공통점이 있다면 CPU가 입출력장치와 메모리 간의 데이터 이동을 주도해야 하며, 이동하는 데이터들도 반드시 CPU를 거친다는 것이다. (ex. 입출력장치의 데이터를 메모리에 저장하는 경우 1. 장치 컨트롤러로부터 데이터를 하나씩 읽어 레지스터에 적재 2. 적재한 데이터를 하나씩 메모리에 저장)
DMA는 직접 메모리에 접근할 수 있는 입출력 기능이다. DMA 컨트롤러가 CPU 대신 장치와 메모리 간의 데이터를 직접 전송한다. DMA 컨트롤러는 시스템 버스에 연결되고, 입출력장치들의 장치 컨트롤러들은 입출력 버스라는 입출력 버스에 연결된다.
CPU는 이 주소로 이만큼 전송하라는 명령만 내리고, 나머지 전송은 DMA가 자동으로 처리한다. 전송이 완료되면 DMA가 인터럽트를 통해 CPU에 결과를 알린다.
동작 과정
- CPU가 DMA 컨트롤러에게 입출력장치의 주소, 수행할 연산, 연산할 메모리 등의 정보와 함께 입출력 작업을 명령한다.
- DMA 컨트롤러가 CPU 대신 장치 컨트롤러와 상호작용해서 입출력 작업을 수행한다. DMA 컨트롤러는 필요한 경우 메모리에 직접 접근해서 정보를 읽고 쓴다. 입출력장치와 메모리 사이에 주고받을 데이터가 CPU를 거치지 않는다.
- 완료 후 DMA는 인터럽트로 CPU에 보고한다.
DMA는 CPU를 거치지 않고 장치가 메모리에 직접 접근하는 방식이다. 고속 대용량 데이터 전송에 적합하며, CPU 부담을 크게 줄인다.
사이클 스틸링(Cycle Stealing)
버스는 공용 자원이라 두 장치가 동시에 사용할 수 없다. 따라서 DMA가 시스템 버스를 사용할 때 CPU는 잠시 버스를 사용할 수 없다. DMA가 버스 접근 사이클을 조금씩 가져다 쓰는 현상을 사이클 스틸링이라 한다.
PCIe (Peripheral Component Interconnect Express)
- 현대 컴퓨터의 대표적인 입출력 버스이다.
- SSD, GPU, 네트워크 카드 등 다양한 입출력장치가 메인보드와 연결되는 통로로 사용된다.
- 버전(1.0, 2.0 … 7.0) 이 높을수록 최대 속도가 빨라진다.
- 여러 레인(버스를 통해 정보를 송수신하는 단위)을 이용해 정보를 주고 받을 수 있다.
- Lane 수(x1, x4, x8, x16) 가 많을수록 한 번에 주고받을 수 있는 데이터 양도 비례하게 늘어난다.
정리하자면, 입출력장치는 CPU와 통신하기 위해 장치 컨트롤러(하드웨어)와 장치 드라이버(소프트웨어)를 통해 연결되고, 데이터의 전송은 Programmed I/O, Interrupt I/O, DMA I/O 같은 입출력 기법으로 수행된다. 이 모든 과정이 실제로 이루어지는 물리적 통로가 바로 PCIe 버스이다.
GPU의 용도와 처리 방식
GPU(Graphics Processing Unit) 는 그래픽 처리 장치이다. 화면에 이미지를 그리거나 3D 렌더링을 수행하는 등 대량의 그래픽 연산을 빠르게 처리하기 위해 만들어진 하드웨어이다. 초기에는 그래픽 전용으로 사용되었으나, 현재는 딥러닝, 암호화폐 채굴, 과학 연산 등 범용 연산(GPGPU, General-Purpose computing on GPU)으로 활용 범위가 확대되었다. 오늘날 GPU는 데스크탑, 노트북, 스마트폰 등 대부분의 컴퓨터 장치에 내장되어 있다.
GPU의 가장 큰 특징은 코어의 개수이다.
- GPU는 수백 개에서 많게는 수천 개의 코어를 포함한다.
- 개별 코어의 성능은 CPU보다 낮지만, 대량 병렬처리에 최적화되어 있다.
병렬처리(Parallel Processing)
- 큰 문제를 여러 개의 작은 연산 단위로 쪼개고, 각 코어가 이를 동시에 처리한다.
- 복잡한 연산을 빠르게 수행할 수 있는 이유가 바로 이 구조에 있다.
GPU는 자체적으로 캐시 메모리와 전용 메모리(GPU Memory)를 가지고 있으며, 일부 고성능 GPU는 수십 GB에 이르는 메모리를 탑재한다.