CPU의 구조와 기능

  • CPU는 기억장치에 저장되어 있는 프로그램 코드인 명령어들을 실행하며 '프로그램 수행'이라는 컴퓨터의 기본 기능을 수행
    1. 명령어 인출: 기억장치로부터 명령어를 읽어옴
    2. 명령어 해독: 수행해야 할 동작을 결정하기 위하여 명령어를 해독
    3. 데이터 인출: 명령어 실행을 위하여 데이터가 필요한 경우에는 기억장치 or I/O 장치로부터 그 데이터를 읽어옴
    4. 데이터 처리: 데이터에 대한 산술 or 논리 연산을 수행
    5. 데이터 저장: 수행한 결과를 저장
  • 위 동작들 중 1, 2번 동작은 모든 명령어들에 대하여 공통적으로 수행되지만, 3-5번 동작은 명령어에 따라 필요한 경우에만 수행

1. CPU의 기본 구조

  • CPU의 구성 요소
    • 산술논리연산잔치(ALU): 각종 산술 연산들과 논리 연산들을 수행하는 회로들로 이루어진 하드웨어 모듈
    • 레지스터 세트: CPU 내부에 위치한 기억장치로서, 액세스 속도가 컴퓨터의 기억장치들 중에서 가장 빠름. 그러나 내부 회로가 복잡하여 비교적 큰 공간을 차지하기 때문에, 많은 수의 레지스터들을 CPU의 내부에 포함시키기는 어려워 특수 목적용 레지스터들과 적은 수의 일반 목적용 레지스터들만 포함
    • 제어 유닛: 프로그램 코드를 해석하고, 그것을 실행하기 위한 제어 신호들을 순차적으로 발생하는 하드웨어 모듈
      • 명령어 실행에 필요한 각종 정보들의 전송 통로와 방향을 지정해주고, CPU 내부 요소들과 시스템 구성 요소들의 동작 시간도 결정
      • CPU가 제공하는 명령어들의 수가 많아질 수록 제어 유닛의 내부 회로는 더 복잡해짐
        • 복잡도를 줄이기 위해 제어 유닛의 동작을 SW로 처리해주는 방법이 마이크로프로그래밍
        • 그러나 이 방법을 이용하면 명령어 실행 시간이 길어짐
        • 따라서 최근에는 명령어의 수를 가능한 줄이고 명령어 형식을 단순화함으로써, HW만으로 명령어를 실행할 수 있도록 하는 RISC(Reduced Instruction Set Computer) 설계 개념도 많이 사용되고 있음
  • CPU 내부 버스
    • ALU와 레지스터들 간의 데이터 이동을 위한 데이터 선들과 주소 선들, 그리고 제어 유닛으로부터 발생되는 제어 신호들을 전송하는 선들로 구성
    • 외부의 시스템 버스와 직접 연결되지 않으며, 반드시 버퍼 레지스터나 인터페이스 회로를 통하여 시스템 버스와 접속

2. 명령어 실행

  • CPU가 한 개의 명령어를 실행하는 데 필요한 전체 과정이 명령어 사이클
    • 명령어 사이클은 CPU가 기억장치로부터 명령어를 읽어 오는 명령어 인출 단계와 (인출 사이클)
    • 인출된 명령어를 실행하는 명령어 실행 단계로 이루어짐 (실행 사이클)
  • 명령어 사이클은 CPU가 프로그램 실행을 시작한 순간부터 전원을 끄거나 회복 불가능한 오류가 발생하여 중단될 때 까지 반복 수행
  • 명령어 실행을 위해 기본적으로 필요한 CPU 내부 레지스터
    • 프로그램 카운터(PC): 다음에 인출될 명령어의 주소를 가지고 있는 레지스터
    • 누산기(AC): 데이터를 일시적으로 저장하는 레지스터. CPU가 한 번에 처리할 수 있는 데이터의 비트 수와 크기가 같음
    • 명령어 레지스터(IR): 가장 최근에 인출된 명령어가 저장되어 있는 레지스터
    • 기억장치 주소 레지스터(MAR): 프로그램 카운터에 저장된 명령어 주소가 시스템 주소 버스로 출력되기 전에 일시적으로 저장되는 주소 레지스터
    • 기억장치 버퍼 레지스터(MBR): 기억장치에 저장될 데이터 혹은 이미 읽어온 데이터가 일시적으로 저장되는 버퍼 레지스터

2-1. 인출 사이클

  • CPU는 각 명령어 사이클의 시작 단계에서 PC가 가리키는 기억장치의 위치로부터 명령어를 인출
  • 그런 다음 CPU는 PC의 내용을 1씩 증가시킴으로써 명령어들을 기억장치에 저장되어 있는 순서대로 읽어올 수 있도록 해줌
  • 인출 사이클에서 수행되는 동작의 마이크로 연산(CPU 클록의 각 주기 동안 수행되는 기본적 동작)
    • t0: MAR <- PC // 현재 PC 내용을 CPU 내부 버스를 통하여 MAR로 보냄
    • t1: MBR <- M[MAR], PC <- PC + 1 // 그 주소가 지정하는 기억장치 위치로부터 읽혀진 명령어가 데이터 버스를 통하여 MBR로 적재 + PC 증가
    • t2: IR <- MBR // MBR에 저장되어 있는 명령어 코드가 명령어 레지스터인 IR로 이동
    • cf. t0, t1, t2는 CPU 클록의 각 주기를 가리킴
  • 명령어 인출에는 세 개의 CPU 클록 주기만큼의 시간이 걸림
    • CPU의 클록 주파수가 1GHz라면 클록 주기가 1ns이므로, 인출 사이클은 3ns

2-2. 실행 사이클

  • 인출된 명령어를 CPU가 해독하고, 그 결과에 따라 필요한 연산 수행
  • CPU 수행 연산
    1. 데이터 이동: CPU와 기억장치 간 혹은 CPU와 I/O 장치 간 데이터 이동
      • ex) LOAD addr
      • t0: MAR <- IR(addr)
      • t1: MBR <- M[MAR]
      • t2: AC <- MBR
    2. 데이터 처리: 데이터에 대하여 산술 or 논리 연산 수행
      • ex) ADD addr
      • t0: MAR <- IR(addr)
      • t1: MBR <- M[MAR]
      • t2: AC <- AC + MBR
    3. 데이터 저장: 연산결과 데이터 혹은 입력장치로부터 읽어들인 데이터 기억장치에 저장
      • ex) STA addr
      • t0: MAR <- IR(addr)
      • t1: MBR <- AC
      • t2: M[MAR] <- MBR
    4. 프로그램 제어: 프로그램의 실행 순서 결정
      • ex) JUMP addr
      • t0: PC <- IR(addr)

2-3. 인터럽트 사이클

  • CPU로 하여금 현재 진행 중인 프로그램 처리를 중단하고 다른 프로그램을 처리하도록 요구하는 메커니즘으로서, CPU와 외부장치들 간의 상호작용을 위하여 필요한 기능
  • 인터럽트 서비스 루틴(ISR): 인터럽트 요구를 처리해주기 위해 수행하는 프로그램 루틴
  • 인터럽트 사이클: 인터럽트 요구가 들어왔는지 검사하고, 그 처리에 필요한 동작들을 수행하는 과정
    1. 인터럽트 요구 신호 검사
    2. t0: MBR <- PC // 현재 PC 내용을 스택에 저장(인터럽트 처리 완료 후, 복귀 위함)
    3. t1: MAR <- SP, PC <- ISR의 시작 주소 // PC에 해당 ISP의 시작 주소를 적재
    4. t2: M[MAR] <- MBR, SP <- SP - 1 // 원래 PC의 내용을 스택에 저장 후, SP 감소
  • 프로그램에 따라 **인터럽트 가능 상태(EI)**와 **인터럽트 불가능 상태(DI)**가 있음
  • 인터럽트 사이클로 인해 AC에 저장된 값이 바뀔 수 있기 때문에, 인터럽트 서비스 루틴의 시작 단계에서 레지스터들의 내용을 스택에 저장하였다가, 루틴의 마지막 단계에서 복원시켜주는 절차가 필요함
  • 다중 인터럽트의 처리 방법
      1. CPU가 ISR을 처리하고 있는 도중에는 새로운 인터럽트 요구가 들어오더라도 인터럽트 사이클을 수행하지 않도록 하는 것
      • 이전 루틴을 처리하는 동안 CPU는 DI 상태. 루틴 처리하는 동안 발생한 인터럽트 요구는 대기 상태로 남아 있다가, CPU가 EI 상태로 바뀐 후에 인식됨
      1. 인터럽트 요구들 간에 우선순위를 정하고, 우선순위에 따라 수행 여부 판단
      • 스택에는 원래의 주프로그램으로 복귀하기 위한 주소뿐 아니라, 첫 번째 ISR으로 복귀하는데 사용될 주소도 저장되어야 함

2-4. 간접 사이클

  • 실행 사이클에서 사용될 데이터의 실제 주소를 기억장치로부터 읽어오는 과정
    • t0: MAR <- IR(addr)
    • t1: MBR <- M[MAR]
    • t2: IR(addr) <- MBR
  • 간접 사이클은 항상 수행되는 것이 아니며, 명령어 내의 특정 비트(ex: I 비트)가 1로 세트된 경우에만 수행

3. 명령어 파이프라이닝

  • 명령어를 실행하는데 사용되는 하드웨어를 독립적인 단계로 분할하고, 그들로 하여금 동시에 서로 다른 명령어들을 처리하도록 함으로써 CPU의 성능을 높여주는 기술
  • 분할되는 단계의 수가 많아질수록 처리 속도가 높아짐

3-1. 2단계 명령어 파이프라인

  • 명령어를 실행하는 하드웨어를 인출 단계실행 단계라는 두 개의 파이프라인 단계로 분리 구성
  • 명령어 선인출: 다음에 실핼될 명령어를 미리 인출하는 동작
  • 많은 수의 명령어들을 실행시키는 경우에 얻을 수 있는 최대 속도 향상은 파이프라인 단계의 수와 같은 2배에 접근하게 됨
  • 그러나, 실제로는 실행 단계가 인출 단계보다 더 긴 수행 시간을 보이기 때문에 2배만큼 빨리지지는 못함

3-2. 4단계 명령어 파이프라인

  • 파이프라인 단계들의 처리 시간이 동일하지 않음으로 인하여 발생하는 효율 저하를 방지하는 방법
  • 파이프라인을 명령어 인출(IF) - 명령어 해독(ID) - 오퍼랜드 인출(OF) - 실행(EX)의 4단계로 구성
  • 파이프라이닝을 이용하여 얻을 수 있는 속도 향상의 관계식
    • T = k + (N - 1)
    • 파이프라인 단계의 수 k, 실행할 명령어들의 수 N
    • 첫 번째 명령어를 실행하는 데 k 주기가 걸리고, 나머지 (N-1)개의 명령어들은 각각 한 주기씩만 소요
    • 파이프라이닝을 사용하지 않을 경우, k x N 주기를 소모
  • k-단계 파이프라이닝의 문제
      1. 모든 명령어가 k 단계를 거치지는 않음
      • 어떤 명령어는 실행 과정에서 오퍼랜드의 인출이 필요 없을 수도
      1. 파이프라인 클록은 처리 시간이 가장 오래 걸리는 단계를 기준으로 정해짐 -> 쓸데없는 대기 시간 있을 수 있음
      1. 기억장치 충돌의 문제가 있을 수 있음
      • IF 단계와 OF 단계는 모두 기억장치를 액세스하는데 이 때 기억장치 충돌의 문제 발생
      1. 조건 분기 명령어가 실행된다면, 미리 인출되어 파이프라인에서 처리하고 있던 명령어들이 무효화될 수 있음
  • 슈퍼파이프라이닝: 2번 문제의 해결을 위해 명령어 파이프라인의 단계들을 더욱 잘게 분할하여 처리 속도를 높여주는 기술
    • 최근에는 대부분의 프로세스들이 10 단계 이상의 단계들로 분할된 명령어 파이프라인 구조를 사용
  • 3번 문제의 보완을 위해 IF 단계와 OF 단계가 직접 액세스하는 CPU 내부 캐시를 명령어 캐시와 데이터 캐시로 분리시키는 방법이 사용됨
  • 조건 문기로 인한 성능 저하를 최소화시키기 위한 해결책
    • 분기 예측: 분기가 일어날 것인지를 예측하고, 그에 따라 어느 경로의 명령어를 인출할 지를 결정하는 확률적 방법. 최근 분기 결과들을 저장하여 두는 분기 역사 표를 참조하여 예측하는 방법이 가장 널리 사용
    • 분기 목적지 선인출: 조건 분기가 인식되면, 분기 명령어의 다음 명령어뿐 아니라, 조건이 만족될 경우에 분기하게 될 목적지의 명령어도 함께 인출하는 방법. 이 방법의 사용을 위해서는 분기 목적지 명령어를 별도로 저장해둘 수 있는 기억 장소가 추가되어야 함
    • 루프 버퍼: 파이프라인의 명령어 인출 단계에 포함되어 있는 작은 고속 기억장치로 가장 최근에 인출된 일정 개수의 명령어들이 순서대로 저장됨
    • 지연 분기: 분기 명령어의 위치를 적절히 조정하여 원래보다 나중에 실행되도록 재배치함으로써, 성능 저하를 최소화하는 방법
  • 조건 분기 명령어에서 사용하는 조건들은 CPU 내부의 상태 레지스터에 저장
    • 상태 레지스터: 연산처리 결과 및 시스템 상태를 가리키는 비트들을 저장하는 레지스터

3-3. 슈퍼스칼라

  • CPU 내에 여러 개의 명령어 파이프라인들을 두어, 동시에 그 수만큼의 명령어들을 실행할 수 있도록 한 구조
  • 슈퍼스칼라 프로세서에서 유의할 점으로는 동시에 처리할 명령어들이 서로 간에 영향을 받지 않고 독립적으로 실행될 수 있어야 한다는 것
    • 두 명령어 사이에 데이터 의존성이 존재하지 않아야 함!
    • 명령어들 간 데이터 의존성이 존재하면 파이프라인들의 일부 단계들이 idle 상태에 들어가 속도 향상을 저해
  • m-way 슈퍼스칼라 프로세서가 N개의 명령어들을 실행하는 데 걸리는 전체 시간
    • T(m) = k + N-m/m
    • 처음 m개의 명령어들을 실행하는 k 주기 소요 + 매 주기마다 m개씩의 명령어들이 동시에 실행 완료

3-4. 듀얼 코어 및 멀티 코어

  • 멀티 코어 프로세서: CPU 코어 여러 개를 하나의 칩에 넣은 것
  • 멀티 코어에서는 각 CPU 코어가 슈퍼스칼라의 명령어 파이프라인에 비하여 독립성이 더 높음
    • 별도의 하드웨어 모듈로, 시스템 버스 인터페이스와 내부 캐시만 공유
    • 따라서 각 CPU 코어는 프로그램 실행을 독립적으로 수행하며, 필요한 경우에만 공유 캐시를 통해 정보 교환
  • 독립적인 처리가 가능한 단위로 분할된 태스크 프로그램들이 CPU 코어들에 의해 동시에 처리됨
    • 이와 같은 동시처리 기술을 멀티 태스킹 혹은 멀티 스레딩이라 부름
    • CPU 코어가 많을수록 그 수만큼의 태스크 프로그램들을 동시에 처리할 수 있게 됨


'Software Convergence > Computer Architecture' 카테고리의 다른 글

폰 노이만 아키텍쳐  (0) 2018.09.09
기억장치  (0) 2018.09.08
시스템 버스, I/O 및 인터럽트  (0) 2018.09.07

+ Recent posts