01
09

ALU와 제어장치

 

1.ALU(계산장치)

계산을 하기 위해서는 피연산자와 수행할 연산이 필요하므로 ALU는 레지스터로부터 피연산자를, 제어장치로부터 수행할 연산(제어신호)를 받아들여 연산을 수행한다.

CPU가 메모리에 자주 접근한다면 프로그램 수행 속도에 영향을 미칠 수 있기 때문에 연산을 수행하고나면 결과값을 메모리에 바로 저장하지 않고 레지스터에 저장하게된다. 그러면서 동시에 플래그 레지스터에 플래그(추가정보)를 저장한다.

부호 플래그 얀신한 결과의 부호 1 이면 음수 0이면 양수
제로 플래그 연산값이 0인지 아닌지  1이면 0 0이면 0이 아님
캐리 플래그 결과값에서 올림수나 빌림수가 발생했는지 1이면 발생함 0이면 발생하지 않음
오버플러우 플래그 오버플로우가 발생했는지 1이면 발생함 0이면 발생하지 않음
인터럽트 플래그 인터럽트가 가능한지 1이면 가능함 0이면 불가능함 
슈퍼바이저 플래그 커널모드/사용자모드로 실행중인지 1이면 커널모드 0이면 사용자모드

 

 

2.제어장치

제어장치는 제어 신호를 내보내고 명령어를 해석한다. 

제어 장치가 받아들이는 신호는 아래와 같다

 

  • 클럭 신호를 받아들인다.  

      클럭 신호란? 컴퓨터 부품을 움직일 수 있게 하는 시간 단위로 클럭의 주기에 맞춰서 데이터가 이동되거나 ALU가 수행 된다. 

  • 해석해야 할 명령어를 받아들인다.

    명령어를 받아들이고 해석한 뒤 제어 신호를 발생시켜서 컴퓨터가 수행할 내용을 알려준다

  • 플래그 값을 받아들인다

받아들인 플래그 값을 참고해 제어 신호를 발생시킨다.

  • 제어버스로 전달된 제어신호를 받아들인다.

외부에서 전달한 제어신호를 받아들인다. 이런 제어신호에는 메모리에 전달하는 제어신호와 입출력장치에 전달하는 제어신호가 있다.

 

* CPU 외부에 전달하는 제어신호 : 메모리, 입출력장치

CPU내부에 전달하는 제어신호 : ALU, 레지스터

 

 

레지스터

레지스터는 CPU마다 이름과 크기, 종류가 다양하다. 그 중에서도 공통으로 사용하고 있는 여덟 개의 레지스터가 존대한다.

  • 프로그램 카운터(명령어 포인터:IP) : 메모리에서 읽어들일 명령어의 주소를 저장하는 레지스터. 변위주소 지정방식 차용
  • 명령어 레지스터 : 받아들인 명령어를 저장하는 레지스터. 이 명령어를 받아들이고 해석한 뒤 제어신호를 내보낸다.
  • 메모리주소 레지스터: 메모리의 주소를 저장하는 레지스터. CPU가 읽을 주소를 주소 버스로 보낼 때 이곳을 거친다.
  • 메모리 버퍼 레지스터 : 메모리와 주고받을 값(데이터, 명령어)을 저장하는 레지스터. 메모리에 쓰거나 메모리에서 받을 값은 이곳을 거친다. 데이터 버스로 주고받을 값이 저쳐가는 곳.
  • 플래그 레지스터 : ALU연산 결과에 따른 플래그를 저장한다. CPU상태에 대한 부가적인 정보를 저장한다.
  • 범용 레지스터 : 다양하고 일반적인 상황에서 자유롭게 사용할 수 있는 레지스터. 데이터와 주소를 모두 저장할 수 있다.
  • 스택 포인터:  스택 주소 지정방식이라는 주소 지정에 사용될 수 있는 레지스터.
  • 베이스 레지스터: 변위 주소 지정 방식이라는 지정 방식에 사용되는 레지스터

 

스택 주소 지정 방식 

스택과 스택 포인터를 이용한 주소 저장 방식.

스택이란 한쪽 끝이 막혀 있는 저장공간이다. 후입선출로 마지막에 저장한 값 부터 꺼낼 수 있다. 메모리에 스택처럼 사용하는 스택 영역이 있다.

스택포인터는 스택의 꼭대기를 가리키므로 곧 가장 최근에 저장한 값의 위치를 저장한다. 

* 스택과 큐 참고(https://dsluna.tistory.com/180)

 

 

변위 주소 지정 방식 

오퍼랜드의 필드 값(변위)과 특정 레지스터의 값을 더해 유효 주소를 얻어내는 주소 지정 방식.

변위 주소 지정 방식을 사용하는 명령어는 연산코드, 레지스터 필드, 오퍼랜드 필드가 존재한다.

오퍼랜드 필드의 주소와 어떤 레지스터와 더하는지에 따라 상대주소 지정방식, 베이스 레지스터 지정방식으로 나뉜다.

 

상대 주소 지정방식 :  오퍼랜드 + 프로그램 카운터로 유효주소를 얻는다. (ex. 오퍼랜드가  -3이라면 CPU는 읽어들이기로 한 명령어로부터 3번째 전 번지로 접근해 실행한다. if문과 유사하게 분기해 특정 주소의 코드를 실행할 때 사용된다.

 

베이스 레지스터 주소 지정 방식 : 오퍼랜드+베이스 레지스터 값

베이스 레지스터 : 기준주소. 기준 주소로부터 떨어진 거리의 역할을 한다. 

이 베이스 레지스터 속 기준 주소로부터 얼마나 떨어져 있는 주소에 접근할지를 연산하게 된다. (ex,  기준 주소 200번지로부터 40만큼 떨어진 240번지로 접근하라/ 베이스 레지스터 = 550, 오퍼랜드 = 50일때 600번지로 접근하게된다) 

 

 

명령어 사이클과 인터럽트

명령어 사이클

CPU가 명령어를 처리하는 정형화된 흐름. 프로그램 속 각각의 명령어들은 명령어 사이클이 반복되며 실행된다. 주로 인출사이클과 실행사이클이 반복되며 필요한 경우 간접사이클도 실행된다.

 

  • 인출사이클 

명령어를 메모리에서 가져오는 단계.

  • 실행사이클

가져온 명령어를 실행하는 단계

  • 간접사이클

간접 주소 지정 방식과 같이 메모리 접근을 한 번 더 해야하는경우에는 인출 사이클 이후에 바로 실행되지 않고 메모리 접근을 한 번 더 한다

 

인터럽트

CPU의 작업을 방해하는 신호로 CPU가 꼭 주목해야하거나 CPU가 처리해야하는 상황에 발생한다.

다른 페이지 로직을 구현하다가 이전에 작업한 페이지 로직에서 에러가 나면 에러를 고치러 가는데 이게 인터럽트인듯하다... 그냥 내 잘못인지도...

  • 동기 인터럽트

CPU에서 발생하는 인터럽트.. CPU가 실행하는 프로그래밍상의 오류와 같은 예외적인 상황에 발생한다.예외 라고도 부른다.

  • 비동기 인터럽트

주로 입출력 장치에 의해 발생하는 인터럽트로 조리 완료 알림과 같은 알림 역할을 한다. 

입출력장치가 작업을 끝냈거나 어떤 입력을 받아들였을 떄 CPU에게 입력 신호를 보낸다. 일반적으로 인터럽트라고 한다. 책에서는 하드웨어 인터럽트라는 용어를 사용했다.

 

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

  1. 압출력 장치가 CPU에 인터럽트 요청 신호를 보낸다
  2. CPU는 실행 사이클이 끝나고 명령어를 인출하기 전 항상 인터럽트 여부를 확인한다
  3. CPU가 인터럽트 요청을 확인하고 인터럽트 플래그를 통해 인터럽트를 받아들일 수 있는지 여부를 확인한다
  4. 받아들일 수 있다면 지금까지의 작업을 백업한다
  5. 인터럽트 벡터를 사용해 인터럽트 서비스 루틴을 실행한다.
  6. 인터럽트 서비스 루틴 실행이 끝나면 4.에서 백업해둔 작업을 복구해서 실행한다.

인터럽트 요청 신호 : 인터럽트는 CPU의 정상적인 실행 흐름을 끊는 것이기 때문에 끼어들어도 되는지 물어봐야한다. 이것을 묻는 신호.

인터럽트 플래그 : 인터럽트 플래그가 활성화되어있으면 인터럽트를 받아들이고 그렇지 않으면 인터럽트를 무시한다.. 하지만 무시할 수 없는 인터럽트도 있는데 정전이나 하드웨어 고장으로 인한 인터럽트가 이에 해당한다.

인터럽트 서비스 루틴(인터럽트 핸들러): 인터럽트를 처리하기 위한 프로그램.CPU가 인터럽트를 받아들이기로 하면 이 서비스 루틴이 실행된다. 어떤 것이 어떤 인터럽트 요청을 보내면 어떻게 해결할지에 대한 정보로 이루어진 프로그램이다. 

인터럽트 벡터: 서비스마다 다른 인터럽트 서비스 루틴을 구분하기 위한 정보. 인터럽트 벡터로 인터럽트 서비스 루틴의 시작주소를 파악하고 특정 인터럽트 서비스 루틴을 수행한다. 

CPU가 인터럽트 서비스를 수행하는 동안 원래 작업하던 것들은 스택에 백업된다. (후입선출)

 

CPU 성능 향상 기법

CPU의 속도에 영향을 미치는 요소는 각각 클럭, 멀티코어, 멀티 스레드가 있다.

 

클럭

컴퓨터 부품은 클럭 신호에 맞춰 움직이며 CPU는 명령어 사이클이라는 흐름에 맞춰 명령어를 실행한다. 따라서 클럭 속도가 높으면 일반적으로 CPU의 성능이 좋다.

 

클럭속도 : Hz(헤르츠)단위로 측정되며 1초에  클럭이 몇 번 반복되는 지를 나타낸다. ex) 2.5GHz = 1초에 25억번  반복됨.

 

선택미션 

코어, 멀티코어

코어:  명령어를 실행하는 부품 (ALU, 레지스터, 제어장치를 포함). 싱글코어

멀티코어 (멀티코어 프로세서): 코어가 여러개인 것. 듀얼코어, 트리플코어, 쿼드코어 등등

 

스레드, 멀티스레드

 

스레드 : 실행 흐름의 단위. 하드웨어적 스레드와 소프트웨어적 스레드가 있다.

 

하드웨어적 스레드

하나의 코어가 동시에 처리하는 명령어 단위. CPU입장에서의 스레드로 2코어 4스레드라면 명령어를 실행하는 부품을 두 개 포함하고 4개의 명령어를 처리할 수 있는 CPU를 의미한다.

하드웨어의 멀티스레드 프로세서(논리 프로세서): 하나의 코어로 여러개의 명령어를 동시에 실행할 수 있는 CPU

이를 위해서는 레지스터가 더 많이 필요하기 때문에 여러 레지스터 세트가 존재한다. 

 

*하이퍼스레딩 :인텔의 멀티스레드 기술 

 

소프트웨어적 스레드

하나의 프로그램에서 독립적으로 실행되는 단위. 프로그래밍 언어나 운영체제에서는 주로 소프트웨어적으로 정의된 스레드를 의미한다. 

ex) 입력받은 나용을 화면에 보여주는 기능 / 맞춤법이 맞는지 검사하는 기능/ 입력된 내용을 수시로 자동저장하는 기능의 코드를 스레드로 만들면 동시에 실행이 가능하다.

 

명령어 병렬 처리 기법

CPU의 휴식을 최소화 해 작동시키는 기법. 명령어 파이프라이닝, 슈퍼스칼라, 비순차적 명령어 처리가 있다. 

 

명령어 파이프라인

일반적으로 명령어의 처리는

  1. 명령어 인출
  2. 명령어 해석
  3. 명령어 실행
  4. 결과 저장

의 순으로 이루어진다. 반드시 이 순서대로 이루어지는 것은 아니지만.

CPU는 겹치지만 않는다면 각 단계륻 동시에 실행할 수 있다. ex) 인출 하는 동안 다른 명령어를 실행하고, 명령어가 실행되는 동안 다른 연산 결과를 저장할 수 있다. 

이런식으로 명령어들을 명령어 파이프라인에 넣고 동시에 처리하는 것을 명령어 파이프라이닝이라고 한다.

 

파이프라인의 위험 

  • 데이터 위험

데이터 간의 의존성으로 인해 발생한다. 이전 명령어를 반드시 실행해야만 비로소 실행할 수 있는 의존관계에 있는 경우에 제대로 작동하지 않는 것을 말한다.

  • 제어 위험

프로그램 카운터의 갑작스러운 변화에 의해 발생함. 현재 실행중인 명령어의 다음 주소로 카운터가 갱신되는데 실행 흐름이 바뀌어 값에 갑작스러운 변화가 생기면 미리 처리하고 있던 명령어는 쓸모가 없게 되어버린다. 이를 해결하기 위해 분기예측을 사용한다.

  • 구조적 위험

자원 위험. 명령어들을 겹쳐 실행하는 과정에서 서로 다른 명령어가 동시에 같은 부품을 사용하려고 할 때 발생한다.

 

슈퍼스칼라

CPU내부에 여러 개의 명령어 파이프라인을 포함한 구조. 공장에 여러개의 생산라인이 존재하는 것과 같다.

이론적으로 파이프라인 개수에 비례해 속도가 빨라지나 그만큼 위험 처리가 복잡하기 때문에 고도로 설계된다. 

 

비순차적 명령어 처리

OoOE. CPU성능 향상에 가장 크게 기여한 방법이다. 명령어들을 순차적으로 처리하지 않는 것으로, 의존성을 가지고 있는 명령어들을 후순위로 밀어놓고 다른 명령어에 의존하지 않는 것들을 먼저 실행한다.

 

 

CISC와 RISC

ISA

명령어 집합, 명령어 집합 구조. CPU들이 이해할 수 있는 명령어들의 모음으로 CPU언어라고도 할 수 있으며, 하드웨어가 소프트웨어를 어떻게 이해할지에 대한 약속이라고도 할 수 있다.

인텔의 x-84와 애플의 ARM은 서로 다른 ISA를 이해하기 때문에 같은 코드를 컴파일 해도 어셈블리어는 달라진다.

 

CISC

ISA 중의 하나로 복잡한 명령어 집합을 활용하는 컴퓨터. x86, x86-64가 대표적이다.

다양하고 강력한 기능의 명령어 집합을 활용하기 떄문에 명령어의 형태와 크기가 다양한 가변길이 명령어를 활용한다. 

메모리에 접근하는 주소 지정 방식도 다양하다.

장점: 상대적으로 적은 수의 명령어로도 프로그램을 실행할 수 있음. 메모리 공간을 절약할 수 있음

단점: 명령어 하나에 여러 클럭 주기를 필요로 함.→명령어 파이프라인 구축이 어렵다.

         대체로 단순한 명령어를 주로 사용한다.

 

RISC

ISA중 하나로 명령어의 종류가 적고, 짧고 규격화된 명령어, 1클럭 내외로 실행되는 명령어를 추구한다. 

고정길이 명령어를 사용하며 메모리에 직접 접근하는 명령어도 load, store 두 개로 제한한다.

대신 레지스터를 적극적으로 활용하며, CISC보다 많은 명령프로그램을 작동시킬 수 있다.


125p 2번

1.플래그 레지스터

2.프로그램 카운터

3. 범용 레지스터

4. 명령어 레지스터

 

 

155p 4번

코어

COMMENT