레지스터
CPU안에 있는 작은 임시 저장장치
CPU안엔 다양한 레스터들이 있고 각기 다른 이름과 역할이 있다.
레지스터에 저장된 값만 잘 관찰해도 비교적 낮은 수준의 프로그램이 어떻게 작동하는지 파악 가능
디버깅 도구는?
- WinDbg(윈도우 운영체제)
- gdb(리눅스, 맥)
CPU의 주요 레지스터
1. 프로그램 카운터 (Program Counter, PC)
- CPU가 다음에 어디로 가야하는지 기억하는 네비게이션
- CPU가 다음에 실행할 명령어의 주소를 저장하는 레지스터
- 보통 메모리 주소를 저장하고 있다가, CPU가 명령어를 실행하면 다음 명령어의 주소로 자동 증가하거나, 분기 명령어가 실행되면 특정한 주소로 점프하게 된다.
2. 명령어 레지스터 (Instruction Register, IR)
- 현재 CPU가 실행할 명령어를 임시로 저장하는 곳.
- 프로그램 카운터(PC)가 가리키는 주소에서 명령어를 가져오면, 그 명령어가 저장되는 곳
- CPU가 명령어를 해석하고 실행하는 동안 이 레지스터에서 계속 참조하게 된다.
3. 범용 레지스터 (General Purpose Register, GPR)
- 다양한 용도로 사용할 수 있는 레지스터( 말 그대로 범용(General Purpose) )
- 쉽게 생각하면 "계산기에서 숫자를 임시로 저장하는 메모리 공간" 같은 것
- 연산을 할 때 데이터를 임시로 저장하거나, 특정한 연산 결과를 보관하는 용도로 사용된다.
- 대표적으로 x86 아키텍처에서는 AX, BX, CX, DX 같은 레지스터들이 있다.
4. 플래그 레지스터 (Flag Register)
- 연산의 결과 ,플래그 값(CPU 상태에 대한 부가 정보)을 저장하는 레지스터
- CPU가 연산 → 그 결과가 특별한 상황일 때가 있다. 근데 CPU는 아! 이게 특별한 상황이구나! 바로 알수가 없다. 이런 “특별한 정보를 기록” 해두는게 플래그 레지스터다.
- 예를 들어, 덧셈을 했는데 결과가 0이면 **Zero Flag(ZF)**가 1이 되고, 연산 결과가 음수면 **Sign Flag(SF)**가 1이 되는 식 플래그(flag) : CPU가 명령어를 처리하는 과정에서 반드시 참조해야 할 상태 정보를 의미하는 비트
- 대표적인 플래그:
- Sign Flag (SF): 결과가 음수인지 (MSB가 1인지)
- Zero Flag (ZF): 연산 결과가 0이면 1, 아니면 0
- Carry Flag (CF): 덧셈/뺄셈 시 자리올림(캐리)이 발생했는지
- Overflow Flag (OF): 정수 오버플로우가 발생했는지
- Interrupt Flag (IF) : CPU가 인터럽트를 받을 수 있는지 결정 (멀티태스킹,인터럽트 기반 I/O)
- Supervisor Flag (SF) : CPU실행중인 코드가 커널모드인지,유저모드인지 구분
- 이 플래그들은 CPU가 조건 분기(예: if문 같은 거)를 할 때 중요한 역할을 한다.
5. 스택 포인터 (Stack Pointer, SP)
- "쌓이는 접시의 맨 위를 가리키는 포스트잇" 같은 역
- 스택 구조에서 현재 스택의 최상단(Top)을 가리키는 레지스터
- 함수 호출을 하면 지역 변수나 리턴 주소 같은 것들이 스택에 저장되는데, 이걸 관리하는 역할을 한다.
- 보통 스택은 메모리의 높은 주소에서 낮은 주소로 감소하면서 쌓임.
📌 정리하면
- PC (프로그램 카운터) → 다음 실행할 명령어의 메모리 주소
- IR (명령어 레지스터) → 현재 실행 중인 명령어 저장
- GPR (범용 레지스터) → 계산할 때 필요한 데이터를 저장하는 공간
- FR (플래그 레지스터) → 연산 결과에 대한 상태 저장 (0인지, 음수인지 등)
- SP (스택 포인터) → 스택의 맨 위를 가리키는 포인터
인터럽트
‘방해하다,중단시키다’
CPU가 수행중인 작업은 방해를 받아 잠시 중단 될 수 있는데, 이렇게 CPU의 작업을 방해하는 신호를 인터럽트라고 한다.
인터럽트 벡터 - 특정 인터럽트 발생 시 실행할 코드 주소를 저장한 테이블
백터 테이블이란?
특정 이벤트나 인터럽트 발생 시 , 실행할 코드의 주소를 저장하는 테이블
컴퓨터 시스템에서 인터럽트 발생 → 어떤 루틴을 실행할지 결정하는 데이터 구조
인터럽트 사이클이란?
- 컴퓨터 시스템에서 인터럽트 발생
- CPU가 현재 수행중인 작업 일시중단
- 인터럽트 백터 테이블 참조
- 인터럽트 서비스 루틴(ISR) 실행
- 복귀
동기 인터럽트 & 비동기 인터럽트
구분 동기 인터럽트 (Synchronous) 비동기 인터럽트 (Asynchronous)
발생 시점 | 프로그램 실행 중 발생 | 외부 이벤트나 하드웨어에서 발생 |
예시 | 0으로 나누기 오류, 잘못된 메모리 접근 | 타이머 인터럽트, 키보드 입력 |
예측 가능성 | 예측 가능 | 예측 불가능 |
처리 방식 | 예외 처리 | 외부 장치나 이벤트 처리 |
하드웨어 인터럽트
컴퓨터 시스템에서 하드웨어 장치나 외부 장치가 발생시키는 인터럽트
CPU의 작업 흐름을 방해하지 않고 외부 장치와의 상호작용을 효율적으로 처리할 수 있도록 도와준다.
- 외부 장치에서 발생 (키보드,마우스 등)
- 인터럽트 발생 → 백터 테이블 참조 → ISR 실행 → 작업 재개
예시
- 타이머 인터럽트
- 컴터엔 일정 시간 간격으로 인터럽트 발생시키는 타이머가 있음.
- 입출력 장치 인터럽트
- 디스크 I/O 인터럽트 : 하드디스크 사용 가능! 빠졌음! CPU에 알려주는 거
- 네트워크 인터럽트
- 입력 장치 인터럽트
인터럽트 요청 신호(IRQ , Interrupt Request)
하드웨어 장치나 외부 시스템에서 CPU에게 특정 작업을 처리하라고 알리는 신호
종류 여러 종류의 IRQ가 있으며, 각 장치는 고유한 IRQ 번호를 가집니다. 예를 들어, 0번 IRQ는 시스템 타이머, 1번 IRQ는 키보드와 관련이 있다.
예시
- IRQ 0: 시스템 타이머
- IRQ 1: 키보드
- IRQ 12: 마우스
인터럽트 플러그 (Interrupt Controller)
- 인터럽트 중요한 순서대로 시키고 우선순위 알려주는 간부 (하드웨어)
- 역할: 여러 하드웨어 장치가 보낼 수 있는 인터럽트 요청을 관리하고, 우선순위를 설정하여 CPU에 어떤 인터럽트를 처리할지 알려준다.
막을 수 있는 인터럽트 , 막을 수 없는 인터럽트
인터럽트 발생 → CPU가 그 인터럽트를 차단하거나 무시할 수 있는지 여부에 달려 있다.
1. 막을 수 있는 인터럽트 (Maskable Interrupt, IRQ)
- 정의: 막을 수 있는 인터럽트는 CPU가 일정 조건에서 이를 무시하거나 차단할 수 있는 인터럽트다. CPU가 중요한 작업을 처리하고 있을 때 이를 처리하지 않고 건너뛰거나 잠시 무시 ㄱㄴ
- 동작 원리: 막을 수 있는 인터럽트는 CPU가 인터럽트 마스크 레지스터(Interrupt Mask Register)를 통해 차단 ㄱㄴ 마스크를 설정하면 해당 인터럽트가 발생하더라도 CPU는 이를 무시하고 계속해서 현재 작업을 수행
- 예시:
- 외부 장치의 요청: 예를 들어, 외부 장치에서 데이터를 보내면 해당 장치에서 발생한 인터럽트를 CPU가 처리할 필요가 있을 때까지 무시할 수 있습니다.
- 일시적인 I/O 작업: I/O 장치에서 발생하는 인터럽트도 CPU가 필요에 따라 처리하지 않고 일시적으로 차단할 수 있습니다.
- 사용 이유: 중요한 작업을 수행하는 도중에 시스템에서 발생하는 다른 인터럽트를 잠시 무시하고, 처리할 우선순위가 높은 작업을 먼저 처리하기 위해 사용됩니다.
2. 막을 수 없는 인터럽트 (Non-Maskable Interrupt, NMI)
- 정의: 막을 수 없는 인터럽트는 CPU가 이를 차단할 수 없으며 반드시 처리해야 하는 인터럽트 이 인터럽트는 매우 중요한 사건이나 오류를 나타내며, 시스템이 반드시 이에 대응해야 하기 때문에 CPU가 무시할 수 없다.
- 동작 원리: 막을 수 없는 인터럽트는 시스템의 중대한 오류나 긴급한 상황을 처리하기 위해 설계되었으며, 이를 무시하거나 차단할 수 없다. 따라서 이런 인터럽트가 발생하면, CPU는 현재 작업을 즉시 중단하고 이를 처리해야 한다.
- 예시:
- 하드웨어 오류: 예를 들어, 메모리 오류나 CPU 오류 같은 심각한 시스템 문제가 발생했을 때 이를 알려주는 인터럽트.
- 전원 장애: 시스템이 전원 문제로 시스템을 안전하게 종료해야 하는 경우
- 핫플러그 이벤트: 예를 들어, 중요 하드웨어가 갑자기 연결되거나 분리될 때
- 사용 이유: 시스템의 안전성이나 무결성을 보장하기 위해서, 중요한 오류나 긴급 상황에 대한 즉각적인 반응을 요구한다.
인터럽트 벡터(Interrupt Vector)
인터럽트가 발생했을 때, CPU가 해당 인터럽트를 처리할 수 있도록 가르키는 주소다.
CPU내의 특정 주소영역에 위치(메모리 시작부분)하거나 메모리 상의 고정된 위치에 존재한다.
CPU는 인터럽트 서비스 루틴을 실행하기 전에 프로그램 카운터 값 등
현재 프로그램을 재개하기 위해 필요한 모든 내용을 메모리 내 스택에 백업한다.
예외 발생 시 인터럽트 처리 방법
1. 폴트 (Fault)
- 예외가 발생한 명령어부터 실행을 재개하는 예외.
- 오류를 처리하고 명령어를 다시 실행할 수 있다.
2. 트랩 (Trap)
- 예외가 발생한 명령어의 다음 명령어부터 실행을 재개하는 예외
- 디버깅이나 시스템 호출 등에서 사용
3. 중단 (Abort)
- 치명적인 오류가 발생했을 때 프로그램을 강제로 종료하는 예외.
- 복구 불가능한 오류로, 프로그램을 종료하고 시스템을 보호한다.
4. 소프트웨어 인터럽트 (Software Interrupt)
- 프로그램에서 의도적으로 발생시키는 인터럽트.
- 운영 체제나 시스템 호출을 할 때 사용된다.
폴링 (Polling)
💡 개념
- CPU가 계속 장치에게 "너 준비됐어?"라고 물어봄
- 장치가 준비될 때까지 무한 반복
⏳ 동작 과정:
1️⃣ CPU는 주기적으로 장치 상태를 확인
2️⃣ 장치가 "아직 준비 안 됐어" 하면 CPU는 또 확인
3️⃣ 장치가 "이제 됐어" 하면 CPU가 데이터 처리
- CPU가 프린터한테 계속 "출력 끝났어?"라고 물어보는 방식
- 장점
- 단순한 구조라 구현이 쉬움
- 특정 장치를 빠르게 반응하게 할 수 있음
단점
- CPU가 계속 확인해야 해서 비효율적
- 다른 작업 못 하고 계속 체크하느라 성능 낭비
CPU 클럭 속도
클럭(clock) : 컴퓨터의 부품을 일사불란하게 움직일 수 있게 하는 시간의 단위
‘똑-딱,똑-딱’
주기에 맞춰 이 레지스터에서 다른 레지스터로 데이터가 이동하거나 ALU에서 연산이 수행되고,
메모리에 저장된 명령어를 읽어들이는 것이다.
클럭 속도 : Hz단위 . 클럭이 1초에 몇 번 반복되는지?
1초에 100번 → 100Hz
4.2Ghz → 1초에 42억번
멀티코어 , 멀티 스레드
멀티코어 (Multi-Core)
- 정의: 하나의 CPU에 여러 개의 독립적인 처리 코어가 있는 구조.
- 특징: 각 코어가 별도로 작업을 처리할 수 있어 병렬 처리 성능이 향상됩니다.
코어 : CPU 내에서 명령어 읽고 해석 → 실행하는 부품 (포괄적)
스레드
- 하드웨어 스레드
- 스레드 (소프트웨어적인 스레드, 하나의 프로그램에서 독립적으로 실행되는 단위)
멀티스레드 (Multi-Thread)
- 정의: 하나의 CPU 코어에서 여러 개의 스레드가 실행되는 구조.
- 특징: 하나의 코어가 여러 작업을 동시에 처리하는 것처럼 보이게 하며, 작업 분할과 효율적 자원 사용을 가능하게 합니다.
차이점:
- 멀티코어는 실제로 여러 개의 코어가 동시에 작동하여 성능을 향상시키고,
- 멀티스레드는 하나의 코어에서 여러 스레드를 병렬로 실행하여 성능을 최적화
명령어를 읽고 해석, 실행 부품 2개가 한번에 4개 명령어 처리하면 ⇒ 2코어 4스레드 CPU
논리 프로세서
1개 물리적 코어 → 멀티스레딩(Hyper-Threading)을 이용해 여러 작업을 동시에 처리할 수 있도록 가상으로 만들어진 프로세서
Hyper-Threading?
인텔 CPU : 1코어 → 2개 논리 프로세서 만들어서 한번에 두 개의 스레드를 처리
- 병렬성 : 작업을 물리적으로 동시에 처리하는 성질
- ex ) 하드웨어 스레드 4개 → 명령어 4개 동시 실행
- 동시성 : 동시에 작업을 처리하는 것처럼 보이는 성질
- CPU가 빠르게 작업을 번갈아 가며 처리할 경우 → 사용자 눈엔 동시에 처리되는 거 같이 보임
하드웨어 스레드는 ‘병렬성’을 구현하기 위한 물리적인 실행 단위에 가깝고
소프트웨어 스레드는 ‘동시성’을 구현하기 위한 논리적인 실행 단위에 가깝다.
명령어 병렬 처리 기법
여러 명령어를 동시에 처리하여 CPU를 한시도 쉬지 않고 작동시킴으로써 CPU의 성능을 높이는 기법
파이프라이닝(Pipelining)
명령어를 여러 단계로 나누어 동시에 처리하는 기술 (동시성) `
명령어 병렬 처리를 통해 다수의 명령어를 동시에 처리하는 것처럼 보인다.
단계 분할 - CPU가 명령어를 처리할 때, 그 과정을 여러 개의 단계로 나누고, 각 단계를 독립적으로 처리할 수 있게 한다.
파이프라인의 단계
- 명령어 인출 (Instruction Fetch, IF): 명령어를 메모리에서 가져옴
- ↓
- 명령어 해석 (Instruction Decode, ID): 명령어를 해석하고 필요한 데이터를 준비
- ↓
- 실행 (Execution, EX): 실제 연산을 수행
- ↓
- 메모리 접근 (Memory Access, MEM): 필요 시 데이터를 메모리에서 읽거나 씁니다.
- ↓
- 결과 쓰기 (Write Back, WB): 계산 결과를 레지스터에 저장합니다.
슈퍼 스칼라
CPU 내부에 여러 명령어 파이프라인을 포함하는 구조
ex ) CPU : 슈퍼스칼라 프로세서 or 슈퍼스칼라 CPU라고 부른다.
파이프라이닝 성능차이를 보이는 명령어 집합 유형
1. CISC (Complex Instruction Set Computing)
- 복잡한 명령어 집합을 사용하여 하나의 명령어로 여러 작업을 처리
- 각 명령어는 다양한 기능을 수행하고, 메모리 접근을 포함할 수 있음
- 명령어 길이가 다양하고, 명령어 해석 시간이 길어 성능이 떨어질 수 있음
- CPU는 적은 수의 명령어로 복잡한 작업을 처리할 수 있음
- 예시: x86 아키텍처.
2. RISC (Reduced Instruction Set Computing)
- 단순하고 빠른 명령어 집합을 사용하여 각 명령어는 하나의 작업만 수행
- 고정 길이 명령어를 사용하며, 빠른 실행을 위해 명령어 해석 시간이 짧음
- 많은 수의 명령어를 사용하지만, 하나의 명령어가 간단하여 실행 속도가 빠름
- 병렬 처리와 파이프라이닝에 적합한 구조를 가짐
- 예시: ARM, MIPS 아키텍처.
파이프라인 위험(pipeline hazard) - CPU 성능 향상에 실패하는 경우
1. 데이터 위험 (Data Hazard)
- 의존성 문제: 명령어 간에 데이터 의존성이 있어, 이전 명령어가 끝나야만 다음 명령어를 실행할 수 있는 상황에서 발생
- 예시: 명령어 2가 명령어 1의 결과를 기다려야 하는 경우.
2. 제어 위험 (Control Hazard)
- 분기 명령어에서 발생: 분기 명령어가 실행되기 전에, 어떤 명령어를 실행할지 결정할 수 없어서 파이프라인이 예기치 않게 중단되는 상황
- 예시: 조건문이나 분기 명령어 후, 어떤 경로를 따라갈지 결정하지 못할 때.
3. 구조적 위험 (Structural Hazard)
- 하드웨어 자원 부족: CPU의 하드웨어 자원(예: ALU, 레지스터 등)이 부족하여 명령어를 동시에 처리할 수 없는 상황에서 발생
- 예시: 동일한 하드웨어 자원을 여러 명령어가 동시에 요청할 때.
'Study > CS' 카테고리의 다른 글
03-2 프로세스와 스레드 (1) | 2025.02.12 |
---|---|
03-1 운영체제 큰그림 (0) | 2025.02.12 |
02-5 보조기억장치와 입출력 장치 (0) | 2025.02.05 |
02-4 메모리 (0) | 2025.02.05 |
02.컴퓨터 구조 (2) | 2025.01.22 |