🔧 CPU 설계
- 컴퓨터 부품들은 ‘클럭 신호’에 맞춰 작동
- CPU는 ‘명령어 사이클’ 이라는 정해진 흐름에 맞춰 명령어 실행
클럭 신호가 빠르게 반복되면, CPU를 비롯한 모든 컴퓨터 부품들은 그만큼 빠르게 움직인다
클럭 속도 ⬆️ → CPU 성능 ⬆️
클럭은 일정한 속도를 유지하지 않고, 고성능을 요하는 순간에는 클럭 속도를 높이고, 그렇지 않을 때에는 클럭 속도를 낮추기도 한다.
클럭 속도를 무작정 높여버리면 발열 문제가 심각 → 클럭 속도만으로 향상시키는 CPU 성능은 한계가 있다.
CPU의 코어를 늘린다면 성능을 높일 수 있다.
코어를 여러 개 포함하고 있는 CPU
CPU 내에 명령어를 처리하는 일꾼이 많다
조별 과제를 생각해보면 답이 나온다
코어마다 처리할 연산이 적절히 분배되지 않는다면, 코어 수에 비례하여 연산 속도가 증가하진 않는다.
하드웨어적 스레드
하나의 코어가 동시에 처리하는 명령어 단위
소프트웨어적 스레드
하나의 프로그램에서 독립적으로 실행되는 단위
1코어 1스레드 CPU도 소프트웨어적 스레드를 수십 개 실행할 수 있다.
(소프트웨어적, 하드웨어적 스레드가 다르기 때문!!)
멀티스레드 프로세서를 설계할 때 가장 큰 핵심은 레지스터이다.
하나의 코어로 여러 명령어를 동시에 처리하도록 만들려면?
→ 프로그램 카운터, 스택 포인터, 데이터 버퍼 레지스터, 데이터 주소 레지스터 등과 같이 하나의 명령어를 처리하기 위해 꼭 필요한 레지스터를 여러 개 가지고 있으면 된다!
레지스터 세트가 2개 = 스레드가 2개
프로그램 입장에선 스레드가 여러 개 있으면 CPU가 여러 개 있는 것처럼 보인다
→ 따라서, 하드웨어 스레드를 논리 프로세서 라고 부르기도 한다.
🔧 멀티코어와 멀티스레드의 차이
코어: 명령어를 실행할 수 있는 하드웨어 부품
스레드: 명령어를 실행하는 단위
명령어 간 ‘데이터 의존성’에 의해 발생한다. 따라서 동시에 실행하려고 하면 파이프라인이 제대로 작동하지 않는 것
예시) 명령어 1을 수행해야만 명령어 2를 수행할 수 있는 경우
주로 분기로 인한 프로그램 카운터의 갑작스러운 변화에 의해 발생
프로그램 카운터는 보통 ‘현재 실행 중인 명령어의 다음 주소’로 갱신이 되는데, 분기를 만나면, 다음 명령어를 준비했던 게 헛수고가 되어버린다.
cf. 분기 예측
명령어들을 겹쳐 실행하는 과정에서 서로 다른 명령어가 동시에 ALU, 레지스터 등과 같은 CPU 부품을 사용하려고 할 때 발생
CPU 내부에 여러 개의 파이프라인 구조
순서를 바꿔 실행해도 무방한 명령어를 먼저 실행해, 명령어 파이프라인이 멈추는 것을 방지하는 기법
🔧 좋은 명령어 집합
- 령어 길이와 수행 시간이 짧고, 규격화
- 자주 쓰이는 기본적인 명령어를 작고 빠르게 만드는 것이 중요
→ RISC
CPU가 이해할 수 있는 명령어들의 모음
많은 CPU 제조사와, 규격, 기능 만듦새가 다 다른 CPU이기 떄문에 각 CPU마다 ISA가 다를 수도 있다.
가변 길이 명령어 활용 → 다양하고 강력한 기능
따라서, 적은 수의 명령어로도 프로그램을 실행할 수 있다 → 프로그램의 크기가 작다, 메모리 공간 절약 가능
→ 그래도 복잡한 명령어는 사용 빈도가 낮다
고정 길이 명령어 활용 → 규격화, 되도록이면 1클럭 내외로 실행되는 명령어
CISC에 비해 명령어 종류가 적다.
메모리 접근을 단순화, 최소화하는 대신 레지스터 적극 활용
→ 레지스터를 이용하는 연산이 많고, 범용 레지스터 개수도 더 많다
CISC | RISC |
---|---|
복잡, 다양 명령어 | 단순, 적은 명령어 |
가변 길이 명령어 | 고정 길이 명령어 |
다양한 주소 지정 방식 | 적은 주소 지정 방식 |
프로그램을 이루는 명령어 수 적음 | 프로그램을 이루는 명령어 수 많음 |
여러 클럭에 걸쳐 명령어 수행 | 1클럭 내외로 명령어 수행 |
파이프라이닝 어려움 | 파이프라이닝 쉬움 |