레지스터
레지스터는 CPU 안에 있는 작은 임시 저장장치
- CPU 안에는 다양한 레지스터들이 있고, 각기 다른 이름과 역할이 있다.
- 프로그램을 이루는 데이터와 명령어가 프로그램의 실행 전후로 레지스터에 저장
1. 프로그램 카운터
- 프로그램 카운터(PC, Program Counter)는 메모리에서 다음으로 읽어 들일 명령어의 주소를 저장
- 프로그램 카운터를 명령어 포인터(IP, Instruction Pointer)라고 부르는 CPU도 있음
- 일반적으로 프로그램 카운터는 1씩 증가, 이는 곧 다음으로 읽어 들일 메모리 주소가 1씩 증가하는 것과 같음
2. 명령어 레지스터
- 명령어 레지스터(IR, Instruction Register)는 해석할 명령어, 즉 메모리에서 방금 읽어 들인 명령어를 저장
- CPU 내의 제어장치는 명령어 레지스터 속 명령어를 해석한 뒤 ALU(산술논리연산장치)로 하여금 연산하도록 시키거나 다른 부품으로 제어 신호를 보내 해당 부품을 작동시킴
3. 범용 레지스터
- 범용 레지스터(general purpose register)는 일반적인 상황에서 자유롭게 사용할 수 있는 레지스터
- 데이터와 명령어, 주소 모두를 저장할 수 있음
- 일반적으로 CPU 안에는 여러 개의 범용 레지스터들이 있음
4. 플래그 레지스터
- 플래그 레지스터(flag register)는 연산의 결과 혹은 CPU 상태에 대한 부가 정보인 플래그(flag) 값을 저장
5. 스택 포인터
- 스택 포인터(stack pointer)는 메모리 내 스택 영역의 최상단 스택 데이터 위치를 가리키는 특별한 레지스터
인터럽트
인터럽트(interrupt) : CPU의 작업을 방해하는 신호
- 동기 인터럽트(synchronous interrupts)
- CPU에 의해 발생하는 인터럽트. 예외(exception)라고도 부름
- CPU가 프로그래밍 오류와 같은 예외적인 상황을 마주쳤을 때 발생하는 인터럽트
- CPU에 의해 발생하는 인터럽트. 예외(exception)라고도 부름
- 비동기 인터럽트(asynchronous interrupts)
- 주로 입출력장치에 의해 발생하는 인터럽트. 알림의 역할
- (일반적으로 비동기 인터럽트를 인터럽트라고 지칭하지만, 책에서는 혼동 방지위해 하드웨어 인터럽트라는 용어를 사용)
하드웨어 인터럽트
CPU는 효율적으로 명령어를 처리하기 위해 하드웨어 인터럽트를 사용.
하드웨어 인터럽트를 사용하면 CPU는 작업이 끝나기를 마냥 기다릴 필요없이 다른 작업을 처리할 수 있으므로, 입출력 완료 여부를 확인하기 위한 CPU 사이클 낭비를 최소화하고 CPU가 다른 일을 수행할 수 있는 시간을 벌어 줌으로써 효율적으로 명령어를 처리할 수 있도록 돕는다
CPU가 하드웨어 인터럽트를 처리하는 순서
- 입출력장치는 CPU에게 인터럽트 요청 신호를 보낸다
- CPU는 실행 사이클이 끝나고 명령어를 인출하기 전에 항상 인터럽트 여부를 확인한다
- CPU는 인터럽트 요청을 확인하고, 인터럽트 플래그를 통해 현재 인터럽트를 받아들일 수 있는지 여부를 확인한다
- 인터럽트를 받아들일 수 있다면 CPU가 지금까지의 작업을 백업한다
- CPU는 인터럽트 벡터를 참조하여 인터럽트 서비스 루틴을 실행한다
- 인터럽트 서비스 루틴 실행이 끝나면 4에서 백업해 둔 작업을 복구하여 실행을 재개한다
인터럽트 요청(interrupt request) 신호
인터럽트는 CPU의 정상적인 실행 흐름을 끊는 것이기 때문에 인터럽트하기 전에 CPU에게 인터럽트의 가능 여부를 확인해야 한다.
인터럽트 플래그(interrupt flag)
CPU가 인터럽트 요청을 수용하기 위해서는 플래그 레지스터의 인터럽트 플래그가 활성화되어 있어야 한다. 인터럽트 플래그는 하드웨어 인터럽트를 받아들일지, 무시할지를 결정하는 플래그다. 다만, 모든 하드웨어 인터럽트를 막을 수 있는 것은 아니므로 막을 수 있는 인터럽트(maskable interrupt), 막을 수 없는 인터럽트(non maskable interrupt)가 있다.
인터럽트 서비스 루틴(ISR, Interrupt Service Routine)
CPU가 인터럽트 요청을 받아들이기로 했다면 CPU는 인터럽트 서비스 루틴을 실행한다. 인터럽트 핸들러라고도 부르며, 인터럽트 서비스 루틴은 어떤 인터럽트가 발생했을 때 해당 인터럽트를 어떻게 처리하고 작동해야 할지에 대한 정보로 이루어진 프로그램이다.
즉 CPU가 인터럽트를 처리한다는 말은 인터럽트 서비스 루틴을 실행하고, 본래 수행하던 작업으로 다시 되돌아온다는 의미
인터럽트 벡터(interrupt vector)
입출력장치마다 각기 다른 인터럽트 서비스 루틴을 가지고 있음. CPU는 이들을 구분하기 위해 인터럽트 벡터를 이용
인터럽트 벡터는 인터럽트 서비스 루틴의 시작 주소를 포함하고 있기 때문에 CPU는 이를 이용해 특정 인터럽트 서비스 루틴을 실행할 수 있다
CPU는 인터럽트 서비스 루틴을 실행하기 전에 프로그램 카운터 값 등 현재 프로그램을 재개하기 위해 필요한 모든 내용을 메모리 내 스택에 백업한다.
인터럽트를 처리하는 인터럽트 사이클까지 추가한 명령어 사이클
예외
폴트(fault)
예외를 처리한 직후에 예외가 발생한 명령어부터 실행을 재개하는 예외
트랩(trap)
예외를 처리한 직후에 예외가 발생한 명령어의 다음 명령어부터 실행을 재개하는 예외
대표적인 사례 - 디버깅의 브레이크 포인트
중단(abort)
CPU가 실행 중인 프로그램을 강제로 중단시킬 수 밖에 없는 심각한 오류를 발견했을 때 발생하는 예외
소프트웨어 인터럽트(software interrupt)
시스템 콜이 발생했을 때 발생하는 예외
CPU 성능 향상을 위한 설계
CPU 클럭 속도
클럭(clock) : 컴퓨터의 부품을 일사불란하게 움직일 수 있게 하는 시간의 단위
클럭 속도는 헤르트(Hz) 단위로 측정. 이는 클럭이 1초에 몇 번 반복되는지를 나타냄
예) 1초에 100번 반복되는 CPU가 있다면, 이 CPU의 클럭 속도는 100Hz
클럭 속도는 CPU의 속도 단위로 간주되기도 하지만, 필요 이상으로 높이면 컴퓨터의 발열이 심해질 수 있기 때문에 클럭 속도를 높이는 것만으로 CPU의 성능을 높이는 데에는 한계가 있다
멀티코어와 멀티스레드
코어(core) : CPU 내에서 명령어를 읽어 들이고, 해석하고, 실행하는 부품
CPU 내부에 여러 개의 코어를 포함하고 있으면 이를 멀티코어 CPU, 혹은 멀티코어 프로세서라고 부른다
스레드(thread)
- CPU에서 사용하는 하드웨어적인 스레드 (= 하드웨어 스레드)
- 프로그래밍 언어 및 운영체제에서 사용하는 소프트웨어적인 스레드 (= 스레드)
하드웨어 스레드 : 하나의 코어가 동시에 처리하는 명령어의 단위
하나의 코어로 여러 명령어를 동시에 처리하는 CPU를 멀티스레드(multithread) 프로세서, 혹은 멀티스레드 CPU라고 한다.
소프트웨어 스레드 : 하나의 프로그램에서 독립적으로 실행되는 단위
하드웨어 스레드와 소프트웨어 스레드의 차이는 동시성과 병렬성이라는 키워드 차이가 있다
병렬성(parallelism) : 작업을 물리적으로 동시에 처리하는 성질
- 4코어 8스레드 CPU가 4개의 명령어를 동시에 실행
- 하드웨어 스레드는 ‘병렬성’을 구현하기 위한 물리적인 실행 단위에 가깝다
동시성(concurrency) : 동시에 작업을 처리하는 것처럼 보이는 성질
- 빠르게 작업을 번갈아 가며 처리할 경우, 사용자의 눈에는 동시에 처리되는 것으로 보임
- 소프트웨어 스레드는 ‘동시성’을 구현하기 위한 논리적인 실행 단위에 가깝다
파이프라이닝을 통한 명령어 병렬 처리
명령어 병렬 처리 기법(ILP, Instruction-Level Parallelism)
- 여러 명령어를 동시에 처리하여 CPU를 한시도 쉬지 않고 작동시킴으로써 CPU의 성능을 높이는 기법
- 명령어 파이프라이닝
하나의 명령어가 처리되는 과정을 비슷한 시간 간격으로 나누면
- 명령어 인출(Instruction Fetch)
- 명령어 해석(Instruction Decode)
- 명령어 실행(Excute Instruction)
- 결과 저장(Write Back)
같은 단계가 겹치지만 않는다면 CPU가 각각의 단계를 동시에 실행할 수 있다.
공장의 생산 라인과 같이 명령어들을 명령어 파이프라인(instruction pipeline)에 넣고 동시에 처리하는 기법을 명령어 파이프라이팅(instruction pipelining)이라고 한다.
파이프라이닝 성능의 차이를 보이는 대표적인 명령어 집합 유형으로 CISC와 RISC가 있다
CISC(Complex Instruction Set Computer)
- 이름 그대로 다채로운 기능을 지원하는 복잡한 명령어들로 구성된 명령어 집합
- 적은 수의 명령어로도 프로그램을 실행할 수 있다
- 하나의 명령어 실행에 여러 클럭 주기가 필요해 파이프라이닝에 비효율적이다
RISC(Reduced Instruction Set Computer)
- CISC에 비해 활용 가능한 명령어의 종류가 적다
- 같은 프로그램이라도 CISC보다 많은 명령어가 필요하다
- CISC에 비해 크기가 규격화되어 있고, 하나의 명령어가 1클럭 내외로 실행되기 때문에 파이프라이닝에 최적화되어 있다
파이프라인 위험(pipeline hazard) : 파이프라이닝이 실패하여 성능 향상이 이루어지지 않는 상황
- 데이터 위험(data hazard)
- 명령어 간의 데이터 의존성에 의해 발생
- 제어 위험(control hazard)
- 프로그램 카운터의 갑작스러운 변화에 의해 발생
- 구조적 위험(structural hazard)
- 명령어들을 겹쳐 실행하는 과정에서 서로 다른 명령어가 동시에 ALU, 레지스터 등 같은 CPU 부품을 사용하려고 할 때 발생
출처 : 이것이 취업을 위한 컴퓨터 과학이다 with CS 기술 면접 책,
'책 > 이것이 취업을 위한 컴퓨터 과학이다' 카테고리의 다른 글
2-2. 컴퓨터가 이해하는 정보 (0) | 2025.04.01 |
---|---|
2-1. 컴퓨터 구조의 큰 그림 (1) | 2025.03.31 |