제어장치가 받아들이는 정보는 총 4가지이다.
- 클럭
CPU 내에서 명령어가 처리되는 시간 단위
명령어는 여러 클럭에 걸쳐서 실행 될 수도 있음- 명령어
명령어 레지스터에 저장된 명령어를 받음- 플래그
플래그 레지스터에 저장된 명령어를 받음- 제어버스를 통해 받아온 제어신호
제어 장치뿐만 아니라 메모리나 입출력장치에서도 제어신호를 발생시킴
또한 제어장치가 내보내는 제어신호는 CPU 내부(ALU, 레지스터)와 CPU 외부(메모리, 입출력장치 등)에 전달된다.
레지스터는 CPU마다 이름과 종류가 다양하지만, 그 중 대부분의 CPU에서 사용되는 중요한 레지스터 8가지가 있다.
- 프로그램 카운터
- 명령어 레지스터
- 메모리 주소 레지스터
- 메모리 버퍼 레지스터 (=메모리 데이터 레지스터)
- 플래그 레지스터
- 범용 레지스터
- 스택 포인터
- 베이스 레지스터
프로그램 카운터, 명령어 레지스터, 메모리 주소 레지스터, 메모리 버퍼 레지스터는 명령어 사이클에서 주요한 역할을 한다.
아래 과정을 순차적으로 실행시키면서 CPU는 메모리를 읽는다.
프로그램 카운터
가 읽어들일 메모리 주소를 저장한다.메모리 주소 레지스터
에 프로그램 카운터에 저장된 메모리 주소를 저장한다.- 주소 버스로 메모리 주소 레지스터에 담긴 주소를, 제어 버스로 '메모리 읽기' 제어 신호를 보낸다.
- 데이터 버스로 해당 메모리 주소에 저장된 값(또는 명령어)을
메모리 버퍼 레지스터
에 저장한다. 동시에, 프로그램 카운터는 증가되어 다음 메모리를 읽어들일 준비를 한다.명령어 레지스터
에 메모리 버퍼 레지스터에 저장된 명령어를 저장한다.- 제어장치는 명령어 레지스터에 저장된 명령어를 해석한다.
프로그램 카운터의 값이 갑작스럽게 변경되면, CPU는 메모리를 비순차적으로 읽는다. 이 경우는 프로그램 카운터의 값을 변경시키는 명령어(JUMP, CALL 등) 또는 인터럽트이다.
범용 레지스터
주소값, 데이터값 모두를 저장
플래그 레지스터
ALU는 연산결과에 대한 플래그를 내보내는데, 이 플래그는 플래그 레지스터에 저장됨
부호 | 제로 | 캐리 | 오버플로우 | 인터럽트 | 슈퍼바이저 |
---|---|---|---|---|---|
음수 : 1 | 0이면 1 | 캐리가 있으면 1 | 오버플로우 발생 1 | 인터럽트 가능 1 | 커널모드 1 |
양수 : 0 | 0이 아니면 0 | 캐리가 없으면 0 | 발생 안 하면 0 | 인터럽트 불가능 0 | 사용자모드 0 |
명령어는 연산코드필드, 레지스터필드, 오퍼랜드필드 이렇게 나눌 수 있다.
레지스터에 담긴 정보가 무엇인지에 따라 변위 주소 지정방식은 1. 상대 주소 지정방식 과 2. 베이스 레지스터 주소 지정방식 2가지로 나눌 수 있다.
- 상대 주소 지정방식
상대 주소 지정방식은프로그램 카운터
에 저장된 주소를 기준으로 한다. 기준으로부터 오퍼랜드 필드에 저장된 값만큼의 주소를 가리킨다.
예를 들어서,
프로그램 카운터 : 1000번지, 오퍼랜드필드 값: +3 일때, 1000에서 3을 더한 1003번지로 접근한다.
- 베이스 레지스터 주소 지정방식
이름 그대로베이스 레지스터
에 저장된 주소를 기준으로 한다. 베이스 레지스터는 기준 주소를 저장한다.
예를 들어서,
베이스 레지스터 : 200번지, 오퍼랜드필드 값 : 50 일때, 200에서 50을 더한 250번지로 접근한다.
인터럽트는 CPU의 명령어 사이클을 중단시키고, CPU로하여금 우선되는 업무를 실행하도록 한다. 인터럽트는 발생시킨 주체에 따라 2가지로 나뉜다.
- 폴트
예외가 발생한 명령어부터 실행하는 예외- 트랩
예외가 발생한 다음 명령어부터 실행하는 예외- 중단
프로그램을 강제로 중단시켜야할 때 실행하는 예외- 소프트웨어 인터럽트
시스템 호출이 발생했을 때 실행하는 예외
하드웨어 인터럽트는 입출력장치가 보내는 알림과 비슷하다.
CPU가 입출력장치의 업무 완료 여부를 계속해서 감시하는 건 비효율적이므로, 입출력장치가 업무를 실행할 동안(업무완료 알림인 하드웨어 인터럽트를 발생시킬때까지) CPU도 다른 업무를 실행한다.
하드웨어 인터럽트가 실행되는 순서는 다음과 같다.
- 입출력장치가 CPU에
인터럽트 요청 신호
를 전송한다- CPU는 명령어 인출이 끝날 때마다 인터럽트 요청 신호가 도착했는지를 확인한다.
플래그 레지스터 내의인터럽트 플래그
의 값에 따라 인터럽트를 받아들일지 말지를 결정한다.- 인터럽트 요청을 받기 전, 실행하고 있던 작업을
스택 영역
에 백업한다.- 입출력장치가 함께 전송한
인터럽트 벡터
값을 참조하여, 메모리 내의인터럽트 서비스 루틴
을 실행한다.- 인터럽트 서비스 루틴 실행이 끝나면, 백업해둔 작업을 복구시켜 다시 실행한다.
인터럽트 플래그
플래그 값이 1이면 가능, 0이면 불가능
단, 플래그 값이 0이어도 무조건 인터럽트 요청을 받아야하는 경우도 있다. (정전, 하드웨어 고장 등)
인터럽트 서비스 루틴
메모리에 저장된, 각 인터럽트를 해결할 프로그램
입출력장치의 종류에 따라 인터럽트 서비스 루틴의 내용도 다르다.
인터럽트 벡터
입출력장치는 인터럽트 요청과 함께 인터럽트 벡터를 전송한다.
인터럽트 벡터는 인터럽트 서비스 루틴의 시작 주소를 알려준다.
클럭
클럭의 박자가 빠르다면 (1초당 많은 클럭 신호를 발생시킨다면) 컴퓨터의 작업 성능은 좋아진다.
클럭 속도의 단위는 헤르츠(Hz)이다. 1초에 클럭이 100번 반복되면 100Hz인 셈이다.
CPU는 클럭의 속도를 유연하게 조절한다. 많은 작업이 필요한 경우 클럭 속도를 높인다.
하드웨어 부품을 바꾸거나 해서 오버클럭킹도 가능하다. (강제로 클럭속도를 높이는 방법)
멀티 코어
코어는 명령어를 실행하는 부품이다. (ALU, 제어장치, 레지스터 세트)
요즈음의 컴퓨터는 CPU내에 여러 개의 코어를 가지고 있다. 이를 멀티 코어라 한다.
멀티 스레드
스레드는 하드웨어적 스레드와 소프트웨어적 스레드로 나누어 설명할 수 있다.
아래에서 후술할 스레드는 하드웨어적 스레드를 의미한다.
하드웨어적 스레드
하나의 코어가 동시에 실행할 수 있는 명령어의 개수
2코어 4스레드 : 2개의 코어로 4개의 명령어를 동시에 처리할 수 있다는 의미이다.
소프트웨어적 스레드
하나의 프로그램 내에서 독립적으로 실행되는 단위
단일 코어에서도 소프트웨어적 스레드는 여러 개 실행 가능하다.
CPU를 효율적으로 사용하려면, 계속해서 명령어를 동시에 처리해야한다.
명령어 파이프라인은 위처럼 명령어가 같은 작업을 수행하지 않는다면, 각 단계를 동시에 실행할 수 있다는 가정 하에서 명령어를 실행하는 방법이다.
하지만 명령어 파이프라이닝을 진행하면서, 3가지 위험이 발생할 수 있다.
- 데이터 위험
명령어 간 데이터 의존성에 의해 발생- 제어 위험
프로그램 카운터의 값이 급작스럽게 변하면서, 프로그램 카운터의 값이 변하기 전 실행하면 명령어의 처리 과정이 의미가 없어짐.
단, 이를 막기 위한 분기 예측이라는 기술이 있다.- 구조적 위험
서로 다른 명령어가 같은 CPU 장치에 접근하려고 할 때 발생
슈퍼 스칼라는 명령어 파이프라인을 여러 개 두는 기법이다.
파이프라인의 개수가 늘어난 만큼 처리 속도가 빨라지나, 위 3가지 위험이 발생할 확률도 높아져서 시스템 설계를 정밀히 해야한다.
OoOE는 Out-of-order execution의 약자이다.
각 명령어간 데이터 의존성을 판단하여, 먼저 실행해도 되는 명령어는 순서를 바꾸어 먼저 실행한다.
SISC와 RISC는 대표적인 ISA이다. ISA는 명령어 집합구조(Instruction Set Architecture)의 약자로, 명령어의 생김새, 명령어가 하는 연산, 주소 지정 방식 등을 정리한 집합구조이다.
ISA가 다르다는 건 (소스코드가 같아도) 기계어를 해석한 어셈블리어도 다르다는 뜻이고, 해당 명령어를 처리할 하드웨어의 설계구조도 다르다는 뜻이다.
CISC는 Complex Instruction Set Computer의 약자로, 현재는 인텔의 x86, x86-64 ISA가 CISC를 기반으로 두고있다. CISC의 특징은 다음과 같다.
- 가변길이 명령어
- 복잡하고 다양한 명령어를 제공한다.
- 어셈블리어 코드에서 명령어의 수가 적다
- 여러 클럭에 걸쳐 명령어를 실행한다
- 주소 지정 방식이 다양하다
명령어의 수가 적어 메모리 접근을 최소화한다는 점에서 메모리를 효율적으로 쓸 수 있다.
하지만 가변길이 명령어는 명령어 파이프라인을 구축하는데 어려움이 있고, 복잡하고 다양한 명령어를 제공한다 하더라도 실제로 자주 사용하는 명령어는 전체의 일부뿐이다.
이러한 단점을 개선하기 위해 만든 방법이 RISC 방법이다.
RISC는 Reduced Instruction Set Computer의 약자이다. 아이폰 속 ARM이 RISC를 기반으로 두고있다. RISC의 특징은 다음과 같다.
- 고정길이 명령어
- 최대한 단순한 내용의 명령어
- 어셈블리어 코드 내에서 (CISC에 비해) 명령어의 수가 많다
- 1클럭 내외로 명령어를 수행한다
- 주소 지정 방식이 적다
- 메모리 접근을 최소화 하기 위해 레지스터를 활용한다
고정길이 명령어는 명령어 파이프라인을 구축하는데 유용하고, 복잡한 명령어 대신 단순한 명령어로만 구성해 자주 쓰이지 않는 명령어가 적도록 한다. 이는 앞서 CISC의 단점을 보완한다.
메모리 접근을 단순화, 최소화 하는 대신 RISC는 레지스터를 적극 이용한다. 그래서 RISC형식의 ISA를 기반으로 둔 CPU는 레지스터를 이용하는 경우도 많고 범용 레지스터의 수도 많다.
125p 2번
플래그 레지스터
: 연선 결과 혹은 CPU 상태에 대한 부가 정보를 저장하는 레지스터
프로그램 카운터
: 메모리에서 가져올 명령어의 주소를 저장하는 레지스터
범용 레지스터
: 데이터와 주소를 모두 저장할 수 있는 레지스터
명령어 레지스터
: 해석할 명령어를 저장하는 레지스터
155p 4번
CPU 내에서 ALU와 제어장치, 여러 개의 레지스터를 묶은, 명령어를 실행할 수 있는 부품을 코어
라고 한다.
Ch05-1. 코어와 스레드, 멀티 코어와 멀티 스레드의 개념 정리하기
본문의 4번 목차에서 정리가 되어있으므로 생략합니다~