cpu는 메모리에 저장된 명령어를 읽어 들이고, 해석하고, 실행하는 장치라 하였다

cpu를 좀더 자세히 들여다 봐보자.

ALU

ALU는 산술 연산, 논리 연산 등 다양한 연산을 수행하는 장치이다.

ALU가 수행한 연산의 결과를 메모리에 바로 저장하지 않고, 일시적으로 레지스터에 저장한다.

ALU가 연산할때마다 메모리에 저장한다면, 메모리에 자주 접근하게 되어 프로그램 실행속도가 늦춰지기 때문이다.

플래그

ALU가 실행한 연산에 대한 추가 적인 상태 정보

이 플래그 들은 플래그 레지스터에 저장된다.

플래그의 종류

  • 부호 플래그 - 연산한 결과의 부호
  • 제로 플래그 - 연산의 결과가 0인지 여부
  • 캐리 플래그 - 연산 도중 올림수나 빌림수 발생했는지 여부
  • 오버플로우 플래그 - 오버플로우가 발생했는지 여부 ( 연산 결과가 레지스터보다 큰 상황 )
  • 인터럽트 플래그 - 인터럽트 가능 여부
  • 슈퍼바이저 플래그 - 커널모드로 실행 중인지, 사용자 모드로 실행 중인지 여부

제어장치

컴퓨터 부품들을 관리하고 작동시키기 위한 전기 신호인 제어 신호를 내보내고, 명령어를 해석하는 부품

제어장치가 받아들이는 정보의 종류

  • 클럭 신호 - 컴퓨터의 모든 부품을 움직이는 시간 단위, 주기에 맞춰 컴퓨터가 동작 실행
  • 해석해야 할 명령어 받아들임 ( 명령어 레지스터에 저장 )
  • 플래그 레지스터 속 플래그 값을 참고하여 제어신호 발생시킴
  • 시스템 버스 중, 제어 버스로 전달된 제어 신호를 받아들임

레지스터

프로그램의 명령어와 데이터는 실행 전후로 반드시 레지스터에 저장된다.

  • 프로그램 카운터

메모리에서 가져올 명령어의 주소를 저장한다.

  • 메모리 주소 레지스터

cpu가 메모리에서 읽을 데이터의 주소 값을 주소 버스로 보낼 때 거치는 레지스터

  • 메모리 버퍼 레지스터

메모리와 주고받을 값을 저장하는 레지스터

  • 명령어 레지스터

메모리에서 읽어 들인 명령어를 저장한다.

제어장치가 명령어 레지스터의 명령어를 해석해서 제어 신호를 발생시킨다.

Untitled

  • 범용 레지스터

다양하고 일반적인 상황에서 자유롭게 사용하는 레지스터

  • 플래그 레지스터

ALU의 연산결과에 따른 플래그들을 저장하는 레지스터

인터럽트

cpu가 하나의 명령어를 처리하는 흐름을 명령어 사이클이라고 한다.

이 흐름이 끊어 지는 상황을 인터럽트라 한다.

명령어 사이클

  • 인출 사이클 - 명령어를 메모리에서 cpu로 가져오는 과정
  • 실행 사이클 - cpu로 가져온 명령어를 실행하는 과정
  • 간접 사이클 - 간접 주소 지정 방식의 경우 오퍼랜드에 데이터의 값이 아닌, 데이터의 주소가 저장되어 있기 때문에 다시 접근해야하는 과정

인터럽트의 종류

  • 동기 인터럽트 (예외) cpu가 실행하는 프로그래밍상의 오류와 같은 예외적인 상황에 마주쳤을때 발생하는 인터럽트
  • 비동기 인터럽트 (하드웨어 인터럽트) 입출력 장치에 의해 발생하는 인터럽트

인터럽트가 필요한 이유?

명령어를 효율적으로 처리하기 위해

끝날때 까지 오랜시간이 소요되는 프로세스의 경우 cpu가 그 프로세스만 기다릴 수 없으므로,

해당 프로세스가 종료되었다는 인터럽트를 받기 전까지 다른 프로세스를 처리할 수 있게된다.

동기 인터럽트(예외) 처리 종류

  • 폴트 - 예외를 처리한 직후, 예외가 발생한 명령어부터 실행을 재개
  • 트랩 - 예외를 처리한 직후, 예외가 발생한 명령어의 다음 명령어부터 실행을 재개
  • 중단 - 실행 중인 프로그램을 강제로 중단시킬 수 밖에 없는 심각한 오류일때 cpu가 프로그램을 중단시킴
  • 소프트웨어 인터럽트 - system call에의한 예외

비동기(하드웨어) 인터럽트 처리 순서

  1. 입출력 장치가 cpu에 인터럽트 요청 신호를 보낸다

    인터럽트 플래그가 활성화 되어있다면, 인터럽트 요청 신호를 받아들이고 인터럽트를 처리함

    cpu가 중요한 작업을 처리하고 있다면, 인터럽트 플래그가 비활성화되고 인터럽트 요청이 무시됨

    정전이나 하드웨어 고장으로 인한 인터럽트는 인터럽트 플래그가 비활성화 되었다 해도 요청이 무시되지 않음

  2. 인터럽트를 받아들일 수 있다면 cpu는 인터럽트 요청을 받기 전까지 cpu가 수행하고 있었던 프로그램에 대한 모든 내용을 스택에 백업한다.

  3. cpu는 인터럽트 서비스 루틴의 시작주소를 가르키는 인터럽트 벡터를 통해 그 주소로 프로그램의 카운터 값을 갱신하고 이 주소부터 실행해 나가며 인터럽트 서비스 루틴을 실행한다.

  4. 인터럽트를 처리하고 나면 스택에 저장해 둔 값을 다시 불러온 뒤, 이전까지 수행하던 작업을 재개한다.

CPU의 성능 높이기(멀티 코어, 멀티 스레드)

클럭

컴퓨터 부품은 클럭 신호마다 작동한다. 클럭 속도가 높아지면 cpu는 명령어 사이클을 더 빠르게 반복하므로 클럭 속도가 높으면 cpu의 성능이 좋다.

클럭의 단위는 Hz이다. Hz는 1초에 클럭이 몇 번 반복되는지를 나타낸다.

1초에 한번 클럭이 반복되면 cpu의 클럭 속도는 1Hz인 것이다.

보통 cpu의 클럭 속도는 2.5GHz ~ 4.9GHz이다. 1초에 25억~49억번 깜빡이는 것이다.

cpu는 보통 25GHz를 유지하다, 고성능을 요하는 순간에 속도를 높인다(오버클러킹)

클럭속도만 높이면, cpu의 속도는 빨라지겠지만 발열이 생겨 속도를 올리는 것에는 한계가 있다.

코어와 멀티코어

명령어를 실행하는 부품인 cpu는 코어라는 용어로 사용된다.

과거의 cpu는 하나의 코어로 이루어졌지만 현대의 cpu는 여러개의 코어로 이루어져있다.

스레드와 멀티스레드

  • 하드웨어적 스레드

하드웨어에서 스레드는 하나의 코어가 동시에 처리는 명령어의 단위를 의미한다.

초기의 cpu는 하나의 코어로 한 클럭에 하나의 명령어를 처리하는 1코어 1스레드였다.

현재의 cpu는 하나의 코어로도 여러 개의 명령어를 실행할 수 있다. 이걸 멀티스레드라고 한다.

예를 들어, 8코어 16스레드는 한 번에 16개의 명령어를 처리할 수 있는 코어가 8개가 달린 cpu를 의미한다.

  • 소프트웨어 스레드

소프트웨어에서 스레드는 하나의 프로그램에서 독립적으로 실행하는 단위를 의미한다.

멀티스레드의 원리

명령어를 처리하기 위해선 프로그램 카운터, 메모리 주소 레지스터, 메모리 버퍼 레지스터, 명령어 레지스터 등 여러 레지스터들의 협력이 필요 했다.

이렇게 하나의 코어에 명령어를 처리하는 레지스터 세트들을 여러개 가지고 있으면 멀티스레드가 가능하다.

논리프로세서

스레드를 이용해 하나의 코어로도 여러개의 명령어를 동시에 처리할 수 있다 하였다.

그러나 프로그램의 입장에선 스레드도 하나의 명령어를 처리하는 cpu이기 떄문에,

2코어 4스레드의 cpu를 프로그램이 봤을때는 4개의 cpu가 있는 것 처럼 보인다.

따라서 하드웨어 스레드를 논리프로세서라고 부르기도 한다.

CPU의 성능 높이기(명령어 병렬처리 기법)

cpu가 명령어를 처리할때,

프로그램 카운터로 메모리에서 가져올 명령어의 주소를 저장하고

메모리 주소 레지스터로 읽을 데이터의 주소 값을 저장하고

메모리 버퍼 레지스터로 메모리에서 가져온 값을 저장하고

명령어 레지스터로 메모리에서 읽어들인 명령어를 실행한다.

이러한 단계가 겹치지만 않는다면 레지스터들을 나누어 여러개의 명령어를 병렬적으로 처리할 수 있다.

이걸 명령어 파이프 라이닝이라고 한다.

하지만 명령어 파이프라이닝 방법은 실패하는 경우가 있는데, 이를 파이프라인 위험이라 하고,

파이프라인 위험에는 데이터 위험, 제어위험, 구조적 위험이 있다.

파이프라인 위험

  • 데이터 위험

데이터 위험은 데이터 의존성에 의해 발생한다. 명령어2가 명령어1이 끝나야만 수행할 수 있는 명령어라면, 파이프라인은 제대로 작동하지 않는다.

  • 제어 위험

기본적으로 프로그램 카운터는 현재 실행 중인 명령어의 다음 주소로 갱신된다.

하지만, 프로그램 실행 흐름이 바뀌어 명령어가 실행면 프로그램 카운터 값이 갑작스럽게 변경되면서 파이프라인에 미리 가지고 와서 처리중이였던 명령어들은 아무 쓸모가 없어진다.

  • 구조적 위험

구조적 위험은 서로 다른 명령어가 동시에 cpu의 같은 부품을 실행하려 할때 발생한다.

슈퍼스칼라

슈퍼스칼라는 여러개의 파이프라인을 구동하는 것과 같다.

여러개의 파이프라인을 사용한다면 속도는 빨라지지만, 스레드는 하나만 사용하기

때문에 하나의 파이프라인을 사용할때보다 파이프라인 위험들을 피하기 어려워진다.

따라서 슈퍼스칼라 방식을 사용하는 cpu는 보다 정교하게 설계하여야한다.

비순차적 명령어 처리

비순차적 명령어 처리 기법은 명령어들을 순차적으로 실행하지 않는 기법이다.

파이프라인기법은 예상치 못한 위험들로 인해 명령어가 곧바로 처리되지 못하는 경

우가 많았다. 하지만 비순차적 명령어 처리 기법을 사용하면 순서를 바꿔 실행해도

무방한 명령어를 먼저 실행하여 명령어 파이프라인이 멈추는 것을 방지하는 기법이

다.

ISA

cpu가 파이프라이닝과 슈퍼스칼라 기법을 효과적으로 사용하려면 명령어가 파이프라이닝 하기 쉽게 생겨야한다.

ISA기반으로 설계된 CISC와 RISC

ISA란?

명령어의 기본적인 구조와 작동원리는 cpu마다 거의 차이가 없지만, 명령어의 생김새, 명령어로 할 수 있는 연산, 주소 지정 방식등은 cpu마다 창가 있다. 이렇게 cpu가 이해할 수 있는 명령어의 모음을 ISA라 하고 cpu마다 ISA는 다르다.

ISA가 다르면 같은 소스 코드로 만들어진 같은 프로그램이라 할지라도 어셈블리어도, 명령어도 달라진다.

ISA가 같으면 서로의 명령어를 이해할 수 있지만, ISA가 다르면 서로의 명령어를 이해할 수 없다.

즉 ISA는 cpu의 언어이자 하드웨어가 소프트웨어를 어떻게 이해할자에 대한 약속인 것이다. 현대의 ISA에는 CISC와 RISC가 존재한다

  • CISC

CISC는 복잡한 명령어 집합을 활용한다. 이는 다양하고 강력한 기능의 명령어 집합

을 활용하기 때문에 명령어의 형태와 크기가 다양한 가변 길이 명령어를 활용한다.

이는 적은 수의 명령어 만으로 프로그램을 동작시킬 수 있어, 메모리 공간을 절약할

수 있다.

예로 인텔의 x86-64가 CISC를 사용하는데 ARM명령어 여러 개로 수행할 수 있는

일을 x86-64명령어 몇 개 만으로 수행할 수 있음을 의미한다.

하지만 CISC는 명령어 수행시간이 길고 길이가 가지각색이기 때문에 파이프라인이

효율적으로 명령어를 처리 할 수 없고, 이는 cpu성장에 한계가 있다는 것을 의미한

다.

  • RISC

따라서 등장한 것이 RISC이다. RISC는 명령어의 종류가 CISC에 비해 적고, 짧고

규칙화된 명령어 위주로 사용된다. 따라서 파이프라이닝에 최적화 된 것이다.

RISC는 메모리 접근을 최소화 하는 대신 레지스터를 적극적으로 활용하기 때문에,

CISC보다 레지스터를 이용하는 연산이 많고 레지스터 개수도 더 많다.

그리고 고정길이 명령어를 사용하여 사용 가능한 명령어가 적기 떄문에 RISC보다 \

더 많은 명령을 해야 프로그램을 작동시킬 수 있다.

profile
https://www.youtube.com/watch?v=__9qLP846JE

0개의 댓글

관련 채용 정보