어떻게하면 CPU가 시간낭비없이 메모리에 있는 명령어들을 처리할 수 있을까?

 

명령어 병렬기법

1. 명령어 파이프라인

여러개의 명령어를 겹쳐서 실행하는 방법이다.

명령어가 처리되는 과정을 비슷한 시간 간격으로 나누면?

  1. 명령어 인출 (Instruction Fetch) : 메모리에서 명령어를 가져온다.
  2. 명령어 해석 (Instruction Decode)
  3. 명령어 실행 (Execute Instruction)
  4. 결과 저장 (Write Back)

같은 단계가 겹치지만 않는다면 CPU는 '각 단계를 동시에 실행할 수 있다'

CPU 동시처리
명령어 파이프라인

 

 

명령어 파이프라인이 항상 이상적으로 실행되는 것은 아니다. 동시에 처리할 수 없는 경우도 있는데 그것이 파이프라인 위험이다.

(병렬로 명령어 처리가 되지 않는 경우)

 

파이프라인 위험 : 명령어 파이프라인이 성능 향상에 실패하는 경우

  • 데이터 위험
  • 제어 위험
  • 구조적 위험

1) 데이터 위험 : 명령어 간의 의존성에 의해 야기된다. 모든 명령어를 동시에 처리할 수는 없다.

                         (이전 명령어를 끝까지 실행해야만 비로소 실행할 수 있는 경우)

데이터 위험

 

위의 그림에서 명령어1에서 R1이 계산되기전에 명령어2를 처리할 수는 없다.

 

 

2) 제어 위험 : 프로그램 카운터의 갑작스러운 변화

제어 위험

 

 

3) 구조 위험 : 서로 다른 명령어가 같은 CPU 부품(ALU, 레지스터)를 쓰려고 할 때

 

 

2. 슈퍼스칼라

CPU 내부에 여러 개의 명령어 파이프라인을 포함한 구조 (오늘날의 멀티스레드 프로세서)

슈퍼스칼라
슈퍼스칼라(2)

 

이론적으로는 파이프라인 개수에 비례하여 처리 속도가 증가한다. 그러나 파이프라인 위험도 증가하기 때문에 파이프라인 개수에 비례하여 처리 속도가 증가하진 않는다.

 

 

 

3. 비순차적 명령어 처리

비유하자면 합법적인 새치기이다.

비순차적 명령어 처리

 

명령어를 순차적으로 처리하면 결과적으로 순차적으로 처리할 수 없게된다.

명령어의 순차적 처리 불가

 

그렇다면 3번순서의 명령어를 의존성이 없는 순서로 변경하면 어떻게 될까?

순서 변경

 

결과에는 변함이 없다. 하지만 이렇게 순서를 변경하게 되면 원활한 파이프라이닝이 가능하다.

 

하지만 아무 명령어의 순서를 변경할 수 있는 것은 아니다.

 

위의 예시를 보면 1번과 3번의 순서를 바꿀 수 없다. (3 수행을 위해 M(100)이 필요하다)

1번과 4번의 순서를 바꿀 수도 없다. (1을 토대로 3이 수행되고, 3을 토대로 4가 수행된다)

 

4번과 5번의 순서는 변경 가능하다.

 

이렇게 변경하여도 전체 프로그램 실행 흐름에는 영향이 없다.

'컴퓨터구조와 운영체제' 카테고리의 다른 글

RAM의 특성과 종류  (1) 2024.07.03
명령어 집합 구조  (2) 2024.07.02
빠른 CPU를 위한 설계 기법  (0) 2024.06.28
명령어 사이클과 인터럽트  (1) 2024.06.27
레지스터  (1) 2024.06.26

CPU를 어떻게 하면 빠르게 설계 할 수 있을까? 

 

단순하게 생각해보면 CPU는 클럭 신호에 맞춰 움직이기 떄문에 클럭 속도를 빠르게 하면 되지 않을까? 클럭 신호에 맞춰 명령어 사이클이 실행되기 때문에 명령어 사이클 주기도 빨리 돌 것 같다.

 

'그럼 클럭 신호가 빠르게 반복되면 CPU를 비롯한 컴퓨터 부품들은 그만큼 빠른 박자에 맞춰 움직이겠네?'

 

꼭 그런건 아니지만 일반적으로는 맞다.

 

클럭 속도

  • 클럭 속도 : 헤르츠(Hz) 단위로 측정
  • 헤르츠(Hz) : 1초에 클럭이 반복되는 횟수
  • 클럭이 '똑-딱-' 하고 1초에 한 번 반복되면 1Hz
  • 클럭이 1초에 100번 반복되면 100Hz   

실제 CPU의 클럭 속도는 어떨까?

 

1초에 클럭이 기본적으로 25억(2.5x4 109)번, 순간적으로 최대 49억(4.9 x 109)번 반복된다.

 

그럼 클럭 신호를 계속해서 높이면 CPU가 무지막지하게 빨라지지 않을까? CPU의 클럭 속도를 필요 이상으로 높이면 발열이 심각해지기ㅔ 때문에 불가능하다.

 

그럼 클럭 속도에는 한계가 있는데 클럭 속도 말고 CPU의 속도를 높이는 방법은 무엇이 있을까?

  • 코어 수를 늘리는 방법 (듀얼 코어, 멀티 코어...)
  • 스레드 수를 늘리는 방법 (멀티 스레드...)

 

코어

코어란?

코어를 이해하기 위해서는 현대적인 관점에서 CPU라는 용어를 재해석 해야 한다. 전통적으로 명령어를 실행하는 부품은 원칙적으로 하나만 존재했다. 그러나 오늘날에는 CPU에는 명령어를 실행하는 부품이 여러개 존재한다.

코어와 멀티 코어

 

 

 

멀티 코어와 종류

 

CPU내부에 코어수와 속도는 비례하지 않는다.

 

 

스레드

스레드의 종류

 

스레드란 실행 흐름의 단위이다.

 

  • 하드웨어 스레드(=논리 프로세서) : 하나의 코어가 동시에 처리하는 명령어 단위

 

위 그림처럼 여러개의 명령어를 동시에 처리할 수 있는 프로세서, CPU를 멀티 스레드 프로세서, 멀티스레드 CPU라고 부른다.

 

멀티스레드 프로세서를 실제로 설계한는 일은 매우 복잡하지만, 가장 큰 핵심은 레지스터이다. 레지스터 세트가 코어에 여러개가 있으면 하나의 코어가 여러 명령어를 동시에 처리할 수 있다.

레지스터 세트

 

  • 소프트웨어 스레드 : 하나의 프로그램에서 독립적으로 실행되는 단위

소프트웨어 스레드

 

예를 들어 

  1. 사용자로부터 입력받은 내용을 화면에 보여 주는 기능
  2. 사요자가 입력한 내용이 맞춤법에 맞는지 검사하는 기능
  3. 사용자가 입력한 내용을 수시로 저장하는 기능

위 3가지 기능을 동시에 하고 싶으면 스레드를 3개 만들면 된다.

멀티 스레드

 

근데 여기서 중요한게 있다.

1코어 1스레드 CPU도 여러 소프트웨어적 스레드를 만들 수 있다.

 

'컴퓨터구조와 운영체제' 카테고리의 다른 글

명령어 집합 구조  (2) 2024.07.02
명령어 병렬 처리 기법(CPU)  (3) 2024.07.01
명령어 사이클과 인터럽트  (1) 2024.06.27
레지스터  (1) 2024.06.26
ALU와 제어장치  (1) 2024.06.25

 

프로그램 속 명령어들은 일정한 주기가 반복되며 실행 된다. 이 주기를 명령어 사이클이라고 하며, 이 주기를 끊어내는 것을 인터럽트라고 한다.

인터럽트

 

명령어나 프로그램을 CPU가 처리하기 위해서는 가장 먼저 메모리에 있는 명령어를 가져와야 한다. 

  • 인출 사이클 : 가장 먼저 CPU로 가져온다.

인출

이렇게 가져온 명령어를 실행한다.

  • 실행 사이클 : 가져온 명령어를 실행한다.

실행

 

일반적으로 CPU는 위 2가지 사이클이 계속해서 반복되며 동작한다. 인출-실행-인출-실행-......

사이클 주기

 

그런데 CPU로 명령어를 가지고 왔지만 바로 실행이 불가능한 경우도 있다.

아래 그림과 같이 인출을 하더라도 추가적으로 메모리에 접근해야 하는 경우가 있다. ex) 간접 주소 지정 방식

명령어 실행 불가능

 

이런 경우 간접사이클이 추가된다. 

간접 사이클

 

 

인터럽트

CPU가 꼭 주목해야 할 때, CPU가 우선적으로 처리해야 하는 작업이 생겼을 때 발생한다.

 

인터럽트의 종류

  • 동기 인터럽트 (예외) : CPU가 예기치 못한 상황을 접했을 때 발생

동기 인터럽트의 종류

  • 비동기 인터럽트 (하드웨어 인터럽트) : 주로 입출력장치에 의해 발생한다. ex) 알림(세탁기 완료 알림, 전자레인지 조리 알림)과 같은 역할

비동기 인터럽트 예시

 

비동기 인터럽트 예시2

 

왜 존재할까? 

 

CPU가 입출력 작업 도중에서도 효율적으로 명령어를 처리하기 위해 하드웨어 인터럽트를 사용한다.

 

입출력장치는 CPU에 비해 느리다. 그렇기 때문에 인터럽트가 없다면 CPU는 프린트 완료 여부를 확인하기 위해 주기적으로 확인을 해야한다.

CPU의 주기적 확인

 

하지만 인터럽트가 있다면 CPU는 계속해서 자기 일을 할 수 있다. 

 

 

 

하드웨어 인터럽트 처리 순서

하드웨어 인터럽트 처리 순서

 

처리 순서 중 

  • 인터럽트 요청 신호
  • 인터럽트 플래그
  • 인터럽트 벡터
  • 인터럽트 서비스 루틴

에 대해 알아보자.

 

  • 인터럽트 요청 신호 : 말 그대로 CPU의 정상적인 흐름을 끊는 것이기 때문에 요청 신호를 보내게 된다.

인터럽트 요청 신호

 

 

CPU가 인터럽트 요청을 받아들이려면 ??

인터럽트 플래그를 확인한다. 현재 인터럽트를 받아들일 수 있는지 없는지 확인이 가능하다. 

  • 인터럽트 플래그 : 현재 인터럽트를 받아들일 수 있는 상태인지 아닌지 관리

다만 모든 인터럽트를 인터럽트 플래그로 막을 수 있는건 아니다.

 

 

이후 CPU가 인터럽트를 받아들이기로 했다면 인터럽트 서비스 루틴(=프로그램)을 실행한다.

  • 인터럽트 서비스 루틴 : 인터럽트가 발생했을 때, 해당 인터럽트를 어떻게 처리하기 위한 프로그램

인터럽트 서비스 루틴 예시

 

인터럽트 서비스 루틴도 프로그램이기 때문에 메모리에 저장되어 있다. 메모리에 시작주소를 가지고 있다.

메모리에 저장되어 있는 인터럽트 서비스 루틴

 

  • 인터럽트 벡처 : 각각의 인터럽트를 구분하기 위한 정보. CPU가 해당 인터럽스 서비스의 시작주소를 알기 위해 

인터럽트 벡터

 

"CPU가 인터럽트를 처리한다" == "인터럽트 서비스 루틴을 실행하고, 본래 수행하던 작업으로 다시 되돌아온다." 

(+인터럽트의 시작 주소는 인터럽트 벡터를 통해 알 수 있다.)

 

 

근데 문제가 있다. 

아래 그림과 같이 이미 CPU 레지스터 안에는 여러 정보가 저장되어 있을것이다. 이런 것들은 버리고 인터럽트를 먼저 실행해야 할까?

인터럽트를 끝내고 나면 되돌아와 이전에 수행하던 작업을 이어서 실행해야 하기 때문에 인터럽트를 실행하기 전 백업을 해둬야 한다.

 

이러한 백업을 메모리 스택에 저장해두게 된다.

메모리 스택에 백업

 

 

인터럽트의 처리 순서 정리

인터럽트 처리 순서

 

인터럽트가 추가된 명령어 사이클

 

'컴퓨터구조와 운영체제' 카테고리의 다른 글

명령어 병렬 처리 기법(CPU)  (3) 2024.07.01
빠른 CPU를 위한 설계 기법  (0) 2024.06.28
레지스터  (1) 2024.06.26
ALU와 제어장치  (1) 2024.06.25
소스 코드와 명령어  (0) 2024.06.24

+ Recent posts