컴퓨터 구조

컴퓨터 구조 [1] CPU 내부 구조 완벽 분석 - 명령어 사이클부터 파이프라이닝까지

준뜨 2025. 12. 23. 15:20
컴퓨터 구조 [1] CPU 내부 구조 완벽 분석 - 명령어 사이클부터 파이프라이닝까지 [2025]
컴퓨터 구조 시리즈 #2

컴퓨터 구조 [1]
CPU 내부 구조 완벽 분석

명령어 사이클부터 파이프라이닝까지 - 컴퓨터의 두뇌를 해부하다

📚 이전 편 복습

[0] 기초편에서 우리는 컴퓨터의 5가지 핵심 구성 요소(CPU, 메모리, 입력장치, 출력장치, 시스템 버스)와 폰 노이만 구조를 배웠습니다. 이번 편에서는 그 중 가장 중요한 CPU의 내부 구조를 깊이 있게 파헤쳐 보겠습니다.

📑 목차

  1. CPU란 무엇인가? - 컴퓨터의 두뇌
  2. CPU의 3대 핵심 구성 요소
  3. 레지스터의 종류와 역할
  4. 명령어 사이클 - Fetch, Decode, Execute
  5. 클럭(Clock)과 처리 속도의 비밀
  6. 파이프라이닝 - CPU 성능 향상 기법
  7. 실무 적용 사례
  8. 다음 편 예고

⚡ CPU란 무엇인가? - 컴퓨터의 두뇌

CPU(Central Processing Unit, 중앙처리장치)는 컴퓨터에서 가장 중요한 부품입니다. 모든 연산과 제어를 담당하는 "컴퓨터의 두뇌"라고 불립니다.

CPU가 하는 일

  • 명령어 해석: 프로그램의 명령어를 읽고 이해
  • 연산 수행: 산술 연산(+, -, ×, ÷)과 논리 연산(AND, OR, NOT) 처리
  • 데이터 이동: 메모리와 레지스터 사이에서 데이터 전송
  • 흐름 제어: 프로그램 실행 순서 결정

💡 실무 예시

Delphi로 설비 모니터링 프로그램을 만들 때, if 문으로 센서 값을 체크하는 코드를 작성하면 CPU는 이를 비교 연산조건 분기 명령어로 변환해서 실행합니다.

if SensorValue > Threshold then
  AlarmOn := True;  // CPU가 비교 연산 → 분기 → 대입 순서로 처리

CPU의 성능 지표

성능 지표 설명 단위
클럭 속도 1초에 수행하는 사이클 수 GHz (기가헤르츠)
코어 수 동시 작업 가능한 CPU 개수 개 (예: 8코어)
캐시 크기 CPU 내부 초고속 메모리 MB (메가바이트)
IPC 클럭당 처리 명령어 수 명령어/클럭

🔧 CPU의 3대 핵심 구성 요소

CPU는 크게 제어장치, 연산장치, 레지스터 세 부분으로 구성됩니다.

CPU 내부 구조도

┌─────────────────────────────────────────────┐
│                    CPU                       │
│                                              │
│  ┌──────────────────┐  ┌─────────────────┐ │
│  │   제어장치 (CU)   │  │  연산장치 (ALU)  │ │
│  │                  │  │                 │ │
│  │ • 명령어 해석    │  │ • 산술 연산     │ │
│  │ • 제어 신호 발생 │  │ • 논리 연산     │ │
│  │ • 실행 순서 결정 │  │ • 비교 연산     │ │
│  └──────────────────┘  └─────────────────┘ │
│            ↕                    ↕           │
│  ┌─────────────────────────────────────┐   │
│  │        레지스터 (Registers)         │   │
│  │  PC | IR | AC | MAR | MBR | SR ...  │   │
│  └─────────────────────────────────────┘   │
│                     ↕                       │
└─────────────────────┼───────────────────────┘
                      ↕
              [시스템 버스]
                      ↕
                  [메모리]

1. 제어장치 (Control Unit, CU)

CPU의 지휘자 역할을 합니다. 명령어를 해석하고 각 구성 요소에게 무엇을 해야 할지 지시합니다.

주요 기능:

  • 명령어 인출: 메모리에서 다음 실행할 명령어 가져오기
  • 명령어 해독: 명령어가 무엇을 의미하는지 분석
  • 제어 신호 생성: ALU, 레지스터, 메모리에 동작 신호 전달
  • 프로그램 카운터 관리: 다음 실행할 명령어 주소 추적

2. 연산장치 (Arithmetic Logic Unit, ALU)

실제 계산을 수행하는 부분입니다. 모든 수학적 연산과 논리 판단을 담당합니다.

수행하는 연산:

산술 연산 (Arithmetic Operations)

  • 덧셈 (ADD): A + B
  • 뺄셈 (SUB): A - B
  • 곱셈 (MUL): A × B
  • 나눗셈 (DIV): A ÷ B

논리 연산 (Logical Operations)

  • AND: 두 비트가 모두 1일 때만 1
  • OR: 두 비트 중 하나라도 1이면 1
  • NOT: 비트 반전 (0↔1)
  • XOR: 두 비트가 다르면 1

비교 연산 (Comparison)

  • 크다 (>), 작다 (<), 같다 (=)
  • 결과를 플래그 레지스터에 저장

🔍 실무 활용

설비 모니터링에서 센서 값을 비교할 때:

// Delphi 코드
if (SensorA > 100) and (SensorB < 50) then
  ShowAlarm;

// CPU는 이렇게 처리:
// 1. SensorA와 100을 ALU에서 비교 (CMP 명령어)
// 2. SensorB와 50을 ALU에서 비교
// 3. 두 결과를 AND 논리 연산
// 4. 결과가 True면 ShowAlarm으로 분기

3. 레지스터 (Registers)

CPU 내부의 초고속 임시 저장 공간입니다. RAM보다 100배 이상 빠릅니다.

특징:

  • 크기: 일반적으로 32비트 또는 64비트
  • 속도: 0.1 나노초 수준 (RAM의 1/100)
  • 개수: CPU마다 다르지만 보통 수십 개
  • 용도: 데이터, 주소, 제어 정보 저장

💾 레지스터의 종류와 역할

CPU에는 여러 종류의 레지스터가 있으며, 각각 특별한 역할을 담당합니다.

범용 레지스터 (General Purpose Registers)

  • 데이터 레지스터: 연산에 사용할 데이터 임시 저장
  • 주소 레지스터: 메모리 주소 계산에 사용
  • 누산기(AC): ALU 연산 결과를 저장하는 특수 레지스터

특수 목적 레지스터 (Special Purpose Registers)

레지스터 이름 역할
PC Program Counter 다음 실행할 명령어의 주소 저장
IR Instruction Register 현재 실행 중인 명령어 저장
MAR Memory Address Register 접근할 메모리 주소 저장
MBR Memory Buffer Register 메모리에서 읽거나 쓸 데이터 저장
SR Status Register 연산 결과의 상태 플래그 저장

상태 레지스터 (Status Register) 플래그

상태 레지스터는 여러 개의 플래그(Flag)로 구성됩니다:

  • Zero Flag (Z): 연산 결과가 0이면 1
  • Carry Flag (C): 자리 올림이 발생하면 1
  • Overflow Flag (V): 오버플로우 발생 시 1
  • Negative Flag (N): 연산 결과가 음수이면 1

이 플래그들은 조건 분기 명령어(if, while)를 실행할 때 사용됩니다.

🔄 명령어 사이클 - Fetch, Decode, Execute

CPU는 명령어 사이클(Instruction Cycle)이라는 반복 과정을 통해 프로그램을 실행합니다.

3단계 명령어 사이클

1

인출 (Fetch)

메모리에서 다음 실행할 명령어를 가져옵니다.

  • PC(프로그램 카운터)가 가리키는 주소를 MAR에 저장
  • 해당 주소의 명령어를 MBR로 읽어옴
  • MBR의 내용을 IR(명령어 레지스터)에 저장
  • PC 값을 1 증가 (다음 명령어 준비)
2

해독 (Decode)

명령어가 무엇을 의미하는지 분석합니다.

  • 제어장치가 IR의 명령어를 해석
  • 어떤 연산을 해야 하는지 파악
  • 필요한 데이터의 위치 확인
  • 각 구성 요소에 제어 신호 준비
3

실행 (Execute)

해독된 명령어를 실제로 수행합니다.

  • ALU에서 필요한 연산 수행
  • 메모리 읽기/쓰기 작업 실행
  • 레지스터 간 데이터 이동
  • 결과를 적절한 위치에 저장
4

반복

프로그램이 끝날 때까지 1→2→3을 계속 반복합니다.

명령어 사이클 상세 예시

예제: C = A + B 연산을 CPU가 처리하는 과정

메모리 상태:
주소 100: LOAD A    // A 값을 레지스터로 로드
주소 101: ADD B     // B 값을 더함
주소 102: STORE C   // 결과를 C에 저장

1단계: Fetch (주소 100)
   PC = 100 → MAR
   메모리[100] → MBR
   MBR → IR ("LOAD A")
   PC = PC + 1 (101)

2단계: Decode
   제어장치: "LOAD 명령어 → 메모리에서 데이터 읽기"
   A의 주소 확인

3단계: Execute
   메모리에서 A 값을 읽어 누산기(AC)에 저장
   AC = A

[다음 사이클로 반복]
1단계: Fetch (주소 101)
   PC = 101 → MAR
   메모리[101] → MBR ("ADD B")
   PC = 102

2단계: Decode
   "ADD 명령어 → ALU에서 덧셈"
   B의 주소 확인

3단계: Execute
   ALU: AC + B 계산
   AC = A + B

[다음 사이클]
1단계: Fetch (주소 102)
   "STORE C"
   PC = 103

2단계: Decode
   "STORE → 메모리에 쓰기"

3단계: Execute
   AC 값을 메모리 C 위치에 저장
   C = A + B (완료!)

⏱️ 클럭(Clock)과 처리 속도의 비밀

클럭(Clock)은 CPU의 심장박동과 같습니다. CPU의 모든 동작은 클럭 신호에 맞춰 동기화됩니다.

클럭이란?

일정한 간격으로 발생하는 전기적 펄스 신호입니다. 이 신호에 맞춰 CPU의 모든 회로가 동작합니다.

클럭 신호 파형

전압
 ↑
 │  ┌─┐  ┌─┐  ┌─┐  ┌─┐
 │  │ │  │ │  │ │  │ │
 │──┘ └──┘ └──┘ └──┘ └──→ 시간
 │  ← 1클럭 사이클 →
 └─────────────────────→

클럭 속도 (Clock Speed)

클럭 속도는 1초에 발생하는 클럭 사이클 수를 의미하며, Hz(헤르츠) 단위로 표현합니다.

1 GHz = 1,000,000,000 Hz = 초당 10억 번의 클럭

예시:

  • 3.5 GHz CPU: 1초에 35억 번 클럭 발생
  • 1클럭 = 약 0.286 나노초 (ns)
  • 매우 짧은 시간에 명령어 처리 가능

CPI와 IPC

용어 의미 설명
CPI Cycles Per Instruction 명령어 하나를 실행하는데 필요한 클럭 사이클 수
IPC Instructions Per Cycle 1클럭에 처리할 수 있는 명령어 수 (CPI의 역수)
CPU 성능 = 클럭 속도 × IPC × 코어 수

⚠️ 클럭 속도만으로는 성능을 판단할 수 없다!

2000년대 초반, 인텔은 Pentium 4를 3.8GHz까지 올렸지만, AMD의 2.4GHz CPU보다 느린 경우가 많았습니다. 이유는 IPC아키텍처의 차이 때문입니다.

현대 CPU는 클럭 속도보다 효율성병렬 처리를 중시합니다.

실무 팁: 코어 수 vs 클럭 속도

멀티스레드 작업 (예: 영상 편집, 3D 렌더링, 대용량 데이터 처리)

  • 코어 수가 많은 CPU 선택 (8코어, 16코어)

싱글스레드 작업 (예: 게임, 일부 시뮬레이션, 실시간 제어)

  • 클럭 속도가 높은 CPU 선택 (4.5GHz 이상)

설비 모니터링 (실시간 데이터 처리)

  • → 클럭 속도 우선, 안정성 중시 (보통 클럭 CPU로 충분)

🚀 파이프라이닝 - CPU 성능 향상 기법

파이프라이닝(Pipelining)은 명령어 처리 과정을 여러 단계로 나누어 동시에 여러 명령어를 처리하는 기법입니다.

파이프라이닝 없이 (순차 처리)

시간 →
명령어1: [Fetch] [Decode] [Execute]
명령어2:                    [Fetch] [Decode] [Execute]
명령어3:                                     [Fetch] [Decode] [Execute]

총 시간: 9 클럭

각 명령어가 완전히 끝나야 다음 명령어를 시작합니다.

파이프라이닝 적용 (병렬 처리)

시간 →
명령어1: [Fetch] [Decode] [Execute]
명령어2:         [Fetch] [Decode] [Execute]
명령어3:                 [Fetch] [Decode] [Execute]

총 시간: 5 클럭 (44% 시간 단축!)

한 명령어가 Decode 단계에 있을 때, 다음 명령어는 Fetch를 시작합니다.

파이프라이닝 단계

현대 CPU는 보통 5단계 파이프라인을 사용합니다:

  1. IF (Instruction Fetch): 명령어 인출
  2. ID (Instruction Decode): 명령어 해독
  3. EX (Execute): 실행
  4. MEM (Memory Access): 메모리 접근
  5. WB (Write Back): 결과 저장

5단계 파이프라인 동작

클럭  1    2    3    4    5    6    7    8
명령1 [IF][ID][EX][MEM][WB]
명령2      [IF][ID][EX][MEM][WB]
명령3           [IF][ID][EX][MEM][WB]
명령4                [IF][ID][EX][MEM][WB]
명령5                     [IF][ID][EX][MEM]

이상적으로는 매 클럭마다 1개의 명령어 완료!

파이프라인 해저드 (Pipeline Hazard)

파이프라이닝이 항상 완벽하게 작동하는 것은 아닙니다. 다음과 같은 해저드(위험)가 발생할 수 있습니다:

1. 데이터 해저드 (Data Hazard)

이전 명령어의 결과를 다음 명령어가 사용해야 할 때 발생

명령1: ADD R1, R2, R3  // R1 = R2 + R3
명령2: SUB R4, R1, R5  // R4 = R1 - R5 (R1이 아직 준비 안됨!)

해결: Forwarding (결과를 미리 전달) 또는 Stall (대기)

2. 제어 해저드 (Control Hazard)

분기 명령어(if, goto)로 인해 다음 명령어를 예측할 수 없을 때

명령1: CMP R1, R2      // R1과 R2 비교
명령2: JEQ Target      // 같으면 Target으로 점프
명령3: ADD ...         // 이 명령어를 실행해야 할지 알 수 없음

해결: Branch Prediction (분기 예측)

3. 구조적 해저드 (Structural Hazard)

하드웨어 자원 부족으로 여러 명령어가 동시에 같은 자원을 사용하려 할 때

분기 예측 (Branch Prediction)

현대 CPU는 분기 예측기를 사용해 제어 해저드를 최소화합니다:

  • 정적 예측: 항상 "분기함" 또는 "분기 안함"으로 예측
  • 동적 예측: 과거 분기 이력을 학습해서 예측 (정확도 95% 이상)

예측이 틀리면 파이프라인을 비워야 하므로(Flush), 예측 정확도가 매우 중요합니다.

슈퍼스칼라 (Superscalar)

슈퍼스칼라는 여러 개의 파이프라인을 병렬로 운영해서 한 클럭에 여러 명령어를 동시 실행하는 기법입니다.

예시: 4-Way 슈퍼스칼라

  • 4개의 명령어를 동시에 처리
  • 이론적으로 IPC = 4 (클럭당 4개 명령어)
  • Intel Core i7, AMD Ryzen 등 대부분의 현대 CPU가 슈퍼스칼라 구조

💼 실무 적용 사례

사례 1: 설비 모니터링 프로그램 최적화

문제 상황: 1초마다 16채널 센서 데이터를 수집하는데, CPU 사용률이 80%까지 올라감

원인 분석:

  • 모든 센서를 순차적으로 읽어서 비효율적
  • 분기문(if)이 많아 파이프라인 효율 저하

해결 방법:

// 개선 전 (순차 처리)
for i := 0 to 15 do
begin
  SensorData[i] := ReadSensor(i);  // 매번 함수 호출
  if SensorData[i] > Threshold then
    ProcessAlarm(i);  // 분기 발생
end;

// 개선 후 (배치 처리 + 분기 최소화)
// 1. 모든 센서 값을 한번에 읽기 (DMA 사용)
ReadAllSensors(@SensorData);

// 2. 분기 없이 플래그만 설정
for i := 0 to 15 do
  AlarmFlags[i] := SensorData[i] > Threshold;

// 3. 알람 처리를 별도 스레드로 분리
if HasAlarm(AlarmFlags) then
  TriggerAlarmThread;

결과: CPU 사용률 30%로 감소!

사례 2: 캐시 친화적 코드 작성

CPU는 메모리 접근 시 캐시(Cache)를 사용합니다. 캐시 히트율을 높이면 성능이 크게 향상됩니다.

// 나쁜 예: 캐시 미스 많이 발생
type
  TLogData = record
    Time: TDateTime;
    Ch01: Double;
    Ch02: Double;
    // ... Ch16까지
  end;

// 각 채널별로 통계 계산 → 메모리 점프가 많음
for ch := 1 to 16 do
  for i := 0 to 999 do
    Sum[ch] := Sum[ch] + LogData[i].Channels[ch];

// 좋은 예: 순차 접근으로 캐시 효율 향상
// 시간 순서대로 모든 채널 처리
for i := 0 to 999 do
  for ch := 1 to 16 do
    Sum[ch] := Sum[ch] + LogData[i].Channels[ch];

성능 차이: 약 3~5배 향상 (캐시 덕분)

사례 3: 루프 언롤링 (Loop Unrolling)

반복문의 오버헤드를 줄이고 파이프라인 효율을 높이는 기법

// 일반 루프 (분기 명령어 1000번)
for i := 0 to 999 do
  Sum := Sum + Data[i];

// 언롤링 (분기 명령어 250번)
for i := 0 to 249 do
begin
  Sum := Sum + Data[i*4];
  Sum := Sum + Data[i*4+1];
  Sum := Sum + Data[i*4+2];
  Sum := Sum + Data[i*4+3];
end;

장점: 분기 예측 미스 감소, ILP(Instruction Level Parallelism) 향상
주의: 코드 크기 증가, 과도한 언롤링은 캐시 미스 유발 가능

🚀 다음 편 예고: 컴퓨터 구조 [2] - 메모리 계층 구조

다음 포스팅에서는 메모리 시스템을 깊이 있게 다룰 예정입니다.

다룰 내용:

  • 메모리 계층 구조 (레지스터 → 캐시 → RAM → 디스크)
  • 캐시 메모리의 동작 원리와 매핑 기법
  • 가상 메모리와 페이징
  • 메모리 접근 속도 최적화 기법
  • 설비 모니터링에서의 메모리 관리 전략

📌 핵심 요약

  • CPU는 제어장치, 연산장치, 레지스터 3가지 핵심 구성으로 이루어짐
  • 명령어 사이클은 Fetch → Decode → Execute 과정을 반복
  • 레지스터는 CPU 내부의 초고속 임시 저장 공간 (RAM보다 100배 빠름)
  • 클럭 속도만으로는 성능을 판단할 수 없으며, IPC와 아키텍처도 중요
  • 파이프라이닝은 여러 명령어를 동시 처리해 성능 향상 (해저드 주의)
  • 실무에서는 캐시 효율, 분기 최소화, 병렬 처리를 고려한 코드 작성 중요

🏷️ 태그

#CPU구조 #중앙처리장치 #명령어사이클 #레지스터 #ALU #제어장치 #클럭속도 #파이프라이닝 #컴퓨터구조 #프로그래밍최적화

💬 여러분의 경험을 공유해주세요!

CPU 구조를 이해하고 나서 코드 최적화에 성공한 경험이 있으신가요?
또는 파이프라이닝, 캐시 등에 대해 더 궁금한 점이 있다면 댓글로 남겨주세요!

728x90
SMALL