포스트

CPU 성능 향상 기법

CPU 성능 향상 기법

인터럽트(Interrupt)

CPU가 프로그램을 실행하는 도중, 입출력 장치나 예외 상황 같은 긴급한 처리가 필요할 경우 이를 CPU에 알려주는 신호입니다. CPU가 주변 장치의 상태를 계속 확인하는 폴링(Polling) 방식의 비효율성을 해결하기 위해 고안되었습니다.

외부 인터럽트(Hardware Interrupt)

일반적으로 인터럽트는 외부 인터럽트를 가리키며, 입출력 장치(키보드, 마우스), 타이머 이벤트, 네트워크 패킷 도착 등 CPU 외부의 요인으로 발생합니다.

내부 인터럽트(Software Interrupt, Trap)

내부 인터럽트는 크게 예외(Exception)트랩(Trap) 으로 나뉘며 프로그램 내부에서 발생합니다.

예외는 0으로 나누기, 메모리 접근 오류처럼 프로그램의 오류로 인해 발생하는 동기적(Synchronous) 인터럽트이며, 트랩System Call처럼 프로그래머가 의도적으로 커널의 기능을 호출하기 위해 발생시키는 동기적 인터럽트를 말합니다.

인터럽트 처리 과정

CPU는 인터럽트 신호를 받으면, 하던 일을 잠시 멈추고 정해진 절차에 따라 인터럽트를 처리합니다.

  1. 인터럽트 요청 신호 발생
    • 주변 장치가 CPU에 인터럽트 신호(IRQ)를 보냅니다.
  2. 실행 중단 및 현재 상태 저장
    • CPU는 현재 실핼중인 명령어까지는 완료하고, 다음 명령어의 주소(PC 값)와 현재 레지스터 상태(PSW 등)를 스택(Stack) 메모리에 안전하게 저장합니다. 이는 인터럽트 처리가 끝난 후 원래 작업으로 돌아오기 위함입니다.
  3. 인터럽트 서비스 루틴(ISR) 실행
    • CPU는 인터럽트 벡터 테이블(IVT) 을 참조하여, 해당 인터럽트 신호에 맞는 인터럽트 서비스 루틴(ISR) 또는 인터럽트 핸들러의 시작 주소를 찾아 PC에 로드합니다. ISR은 인터럽트를 처리하기 위해 미리 작성된 커널 코드입니다.
  4. 인터럽트 처리
    • CPU는 확인된 주소로 점프하여 ISR 코드를 실행, 인터럽트를 처리합니다. (키보드 버퍼에서 데이터 읽기 등)
  5. 상태 복원 및 실행 재개
    • ISR 실행이 끝나면, 스택에 저장해두었던 PC 값과 레지스터 상태를 다시 원래대로 복원합니다. 그 후, 중단되었던 바로 그 지점부터 원래 프로그램을 계속 실행합니다.

Stack : 기존 처리하던 작업 정보를 담고 있으며 주기억 장치의 일부를 차지
IVT : 각 인터럽트 요청에 대응하는 인터럽트 서비스 루틴의 주소를 저장
ISR : 특정 인터럽트를 처리하는 작업이 정의되어 있음

명령어 파이프라이닝(Instruction Pipelining)

하나의 명령어를 처리하는 과정을 여러 단계로 나누고, 각 단계를 서로 다른 하드웨어에서 동시에 처리하여 CPU의 전체 처리량(Throughput)을 높이는 기술입니다.

각 단계에 드는 시간이 명령어마다 동일하지 않으면 파이프라이닝에 의한 속도 향상을 기대할 수 없으므로 파이프라인의 단계 수를 증가시켜 각 단계의 명령어 처리 시간을 같게(시간 차이가 거의 없도록) 해야 합니다.

  • 2단계 명령어 파이프라이닝 : 명령어 처리 과정을 인출 단계, 실행 단계라는 2단계로 나누며, 한 클록에서 2개의 명령어를 각기 다른 단계를 동시에 실행합니다.
  • 4단계 명령어 파이프라이닝 : 명령어 인출, 명령어 해독, 오퍼랜드 인출, 명령어 실행 단계로 나누며, 한 클록에서 4개의 명령어의 각기 다른 단계를 동시에 실행합니다.
  • 6단계 명령어 파이프라이닝 : 명령어 인출, 명령어 해독, 오퍼랜드 계산, 오퍼랜드 인출, 명령어 실행, 오퍼랜드 저장 단계로 나누며, 한 클록에서 6개의 명령어의 각기 다른 단계를 동시에 실행합니다.
클록 주기1 클록2 클록3 클록4 클록5 클록6 클록7클록
명령어1명령어 인출명령어 해독오퍼랜드 계산오퍼랜드 인출명령어 실행오퍼랜드 저장 
명령어 2 명령어 인출명령어 해독오퍼랜드 계산오퍼랜드 인출명령어 실행오퍼랜드 저장
명령어 3  명령어 인출명령어 해독오퍼랜드 계산오퍼랜드 인출명령어 실행
  • 이처럼 명령어의 각기 다른 단계를 한 클록에서 동시에 실행할 수 있으며 명령어가 추가되더라도 해당 클록이 진행하고 있지 않은 단계를 진행함으로써 여러 명령어를 동시에 실행합니다.

클록

  • CPU의 동작을 동기화하고 명령어 실행 속도를 결정하는 신호로, 초당 주기(Hz)로 측정
  • 클록의 주기는 CPU가 한 작업을 처리하는 기본 단위로 사용

파이프라인 해저드(Pipeline Hazard)

파이프라이닝이 항상 순조롭게 진행되는 것은 아닙니다. 데이터 의존성(앞선 명령어의 결과가 필요할 때), 제어 의존성(분기문으로 실행 흐름이 바뀔 때) 등으로 인해 파이프라인이 잠시 멈추는 ‘스톨(Stall)’ 현상이 발생할 수 있으며, 이를 해저드라고 합니다. 현대 CPU는 이런 해저드를 예측하고 해결하기 위한 다양한 기법(분기 예측, 데이터 포워딩 등)을 사용합니다.

  • 구조적 해저드 (Structural Hazard) : 서로 다른 명령어가 같은 하드웨어 자원(메모리, ALU 등)을 동시에 사용하려고 할 때 발생합니다.
  • 데이터 해저드 (Data Hazard) : 이전 명령어가 아직 데이터를 쓰기 전인데, 다음 명령어가 그 데이터를 읽으려고 할 때 발생합니다. (Read After Write, RAW) (ADD R1, R2, R3 직후 SUB R4, R1, R5 실행)
  • 제어 해저드 (Control Hazard) : JUMPBRANCH 같은 분기 명령어로 인해 다음에 실행할 명령어를 미리 예측하기 어려워 파이프라인에 잘못된 명령어가 들어올 때 발생합니다. 이를 해결하기 위해 분기 예측(Branch Prediction) 기법이 사용됩니다.

분기 예측(Branch Prediction) 기법

CPU는 분기문의 조건 결과가 나오기 전에 어떤 분기로 갈지 ‘예측’하여 해당 경로의 명령어를 미리 파이프라인에 채워 넣습니다. 예측이 성공하면 성능 향상을, 실패하면 파이프라인을 비우고 다시 채워야 하는 페널티(penalty)를 받습니다.

파이프라이닝에 의한 속도 향상

\(T = k + (N -1)\)

파이프라인의 단계 수를 k, 실행할 명령어의 수는 N, 각 파이프라인 단계가 한 클록 주기씩 걸린다고 가정하면 전체 명령어 실행 시간은 이와 같다.

\(S = \frac{kN}{k + (N - 1)}\)

파이프라이닝이 적용되지 않으면 실행 시간은 단순히 k와 N의 곱이다.
따라서 파이프라이닝에 의한 속도 향상은 이와 같다.

\(\lim_{N\to\infty} S = \lim_{N\to\infty} \frac{kN}{k + (N - 1)} = k\)

명령어의 수(N)가 매우 많아질 때 속도 향상은 다음과 같이 표현된다.
즉, 이상적인 상황에서 k 단계 명령어 파이프라이닝 기법에서는 k 배의 속도 향상을 기대할 수 있다.

추가적인 기법들

슈퍼 스칼라 프로세서(Superscalar)

파이프라이닝 기법에 병렬 처리를 지원하는 것(CPU 내부에 파이프라인을 여러 개 배치)으로 매 클럭마다 여러 개의 명령어를 동시에 처리하는 기술입니다.

한 번에 n개의 명령어를 병렬 처리할 수 있는 n등급의 슈퍼 스칼라 프로세서는 이론적으로 단일 파이프라이닝 기법에 비해 n 배의 성능 향상을 기대할 수 있습니다.

슈퍼 파이프라이닝(Superpipelining)

기존 파이프라이닝 기법에서 각 단계를 더 잘게 쪼개어(클록 주기를 n분의 1로) 전체 파이프라인의 단계(depth)를 늘리는 기법입니다.

예를 들어, ‘명령어 인출’ 단계를 ‘주소 계산’과 ‘캐시 접근’ 두 단계로 나누는 식입니다. 이렇게 각 단계가 처리하는 일이 단순해지므로 하나의 단계를 더 빠른 클럭으로 동작시킬 수 있게 되어(클럭 주기 단축) 전체적인 성능이 향상됩니다.

명령어 수(N)가 매우 많아지면 기존 파이프라이닝 기법에 비해 n 배의 속도 향상을 기대할 수 있습니다.

\[\lim_{N\to\infty}\frac{k + N - 1}{k + k + \frac{N - 1}{n}} = n\]

슈퍼 파이프라이닝 슈퍼 스칼라

슈퍼 파이프라이닝과 슈퍼 스칼라 프로세서를 결합한 기법입니다.

클록 주기를 n분의 1로 줄이고 m 등급의 슈퍼 스칼라 프로세서를 사용한다고 할 때, 명령어 수(N)가 매우 많아지면 기존 파이프라이닝 기법에 비해 mn 배의 속도 향상을 기대할 수 있습니다.

\[\lim_{N\to\infty}\frac{k + N - 1}{k + \frac{N - 1}{nm}} = mn\]

비순차적 명령어 처리 (Out-of-Order Execution, OoOE)

명령어를 코드에 적힌 순서대로 처리하지 않고, 실행 순서를 바꿔서 처리 가능한 명령어부터 먼저 실행하는 기술입니다.

파이프라인 해저드로 인해 멈춰있는 동안, 뒤에 있는 상관없는 명령어를 먼저 처리하여 CPU가 노는 시간을 최소화합니다.

멀티코어 (Multi-core)

하나의 반도체 칩 안에 여러 개의 독립적인 CPU 코어(Core) 를 집적하는 기술입니다.

병렬 처리에 매우 효과적이며, 현대 거의 모든 CPU의 표준입니다.

SMT (Simultaneous Multi-Threading) / 하이퍼스레딩 (Hyper-threading)

하나의 물리적인 코어를 운영체제(OS)에게 두 개 이상의 논리적인 코어인 것처럼 보이게 하는 기술입니다.

하나의 CPU 코어 안에는 정수 연산을 담당하는 ALU, 실수 연산을 담당하는 FPU 등 여러 종류의 실행 유닛(Execution Unit) 이 있습니다. 하지만 하나의 스레드는 특정 순간에 이 모든 유닛을 동시에 사용하지 않는 경우가 많습니다.

SMT는 이렇게 쉬고 있는(idle) 실행 유닛을 다른 스레드가 사용할 수 있도록 하여, 하나의 코어가 동시에 두 스레드의 작업을 처리하는 것처럼 만들어 성능을 높이는 기술입니다.

이 기사는 저작권자의 CC BY-NC 4.0 라이센스를 따릅니다.