맨위로가기

명령어 파이프라인

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

명령어 파이프라인은 컴퓨터의 명령어 처리 과정을 여러 단계로 나누어 각 단계를 동시에 처리하는 기술이다. 이는 CPU의 처리량을 늘리고 사이클 시간을 단축시키지만, 해저드 발생으로 인한 성능 저하, 명령어 지연 시간 증가, 복잡성 증가 등의 단점도 존재한다. 파이프라인은 데이터 해저드, 제어 해저드, 구조적 해저드와 같은 문제에 직면하며, 분기 예측, 피연산자 전달, 비순차적 실행 등의 기술을 통해 이를 해결한다. 초기에는 ILLIAC II와 IBM 스트레치 프로젝트에서 사용되었으며, 슈퍼컴퓨터와 메인프레임을 거쳐 현재는 대부분의 마이크로프로세서에 널리 사용되고 있다.

더 읽어볼만한 페이지

  • 슈퍼스칼라 마이크로프로세서 - 펜티엄 II
    펜티엄 II는 인텔이 펜티엄 프로의 P6 마이크로아키텍처를 기반으로 개발하여 일반 소비자 시장을 공략하기 위해 CPU 코어와 캐시 메모리를 분리하고 슬롯 1 인터페이스를 도입, MMX 명령어 세트 추가, 16비트 코드 성능 개선 등을 특징으로 하는 x86 마이크로프로세서이다.
  • 슈퍼스칼라 마이크로프로세서 - 애슬론
    AMD가 1999년부터 출시한 애슬론은 x86 아키텍처 기반의 데스크톱, 모바일용 마이크로프로세서 제품군으로, 인텔 펜티엄 III에 대항하기 위해 개발되어 K7, K8 등 다양한 아키텍처를 거치며 성능이 향상되었고 슬롯 A에서 소켓 A, 소켓 AM4 등으로 인터페이스가 변경되었다.
  • 명령어 처리 - 멀티스레딩
    멀티스레딩은 프로세스 내에서 여러 스레드를 동시 실행하여 처리 능력을 향상시키는 기술로, 응답성 향상과 자원 공유 등의 장점이 있지만, 자원 간섭과 소프트웨어 복잡성 증가 등의 단점도 존재하며, 다양한 모델과 구현 방식, 스레드 스케줄러, 가상 머신 활성화 가능성 등을 고려해야 한다.
  • 명령어 처리 - 마이크로아키텍처
    마이크로아키텍처는 명령어 집합 아키텍처를 구현하는 프로세서의 구성 요소, 상호 연결, 작동 방식을 포괄하는 개념으로, 동일 ISA에서 반도체 기술 발전과 새로운 구조 및 회로를 통해 성능 향상을 가능하게 한다.
명령어 파이프라인
개요
이름명령어 파이프라인
분야컴퓨터 아키텍처
목표명령어 수준 병렬성 향상
설명명령어 실행을 여러 단계로 분할하여 동시에 처리하는 기술
기본 원리
단계 분할하나의 명령어를 여러 개의 작은 단계로 분할 (예: 명령어 인출, 디코딩, 실행, 메모리 접근, 쓰기)
동시 실행각 단계에서 서로 다른 명령어를 동시에 실행하여 전체 처리량 증가
파이프라인 깊이파이프라인 단계의 수 (깊이가 깊을수록 이론적 성능 향상 가능)
성능 향상
명령어 처리량 증가단위 시간당 처리하는 명령어 수 증가
이상적인 경우각 클럭 사이클마다 하나의 명령어 완료
실제 성능 제한 요소데이터 의존성 (Data Dependency)
제어 의존성 (Control Dependency)
자원 제약 (Resource Constraints)
위험 요소 (Hazard)
데이터 위험이전 명령어의 결과가 필요한 경우 (해결 방법: 데이터 포워딩, 파이프라인 스톨)
제어 위험분기 명령어 때문에 다음에 실행할 명령어를 알 수 없는 경우 (해결 방법: 분기 예측)
구조적 위험여러 명령어가 동일한 자원을 동시에 사용하려 할 경우 (해결 방법: 자원 복제)
해결 방법
데이터 포워딩 (Data Forwarding)필요한 데이터를 파이프라인 중간에서 직접 전달하여 대기 시간 감소
분기 예측 (Branch Prediction)분기 명령어의 결과를 예측하여 미리 명령어 인출 (정확도에 따라 성능 영향)
파이프라인 스톨 (Pipeline Stall)위험이 발생했을 때 파이프라인의 진행을 멈추고 대기 (성능 저하의 원인)
고급 기술
슈퍼스칼라 (Superscalar)여러 개의 파이프라인을 사용하여 동시에 여러 명령어 실행
동적 스케줄링 (Dynamic Scheduling)명령어 실행 순서를 하드웨어가 동적으로 결정하여 효율성 향상
아웃 오브 오더 실행 (Out-of-Order Execution)명령어의 의존성을 분석하여 실행 가능한 명령어부터 먼저 실행
장점
처리량 향상전체적인 명령어 처리 속도 증가
효율적인 자원 활용CPU 내부 자원을 효율적으로 사용
단점
설계 복잡성 증가파이프라인 설계 및 제어 로직이 복잡해짐
위험 요소 처리 필요데이터, 제어, 구조적 위험을 해결하기 위한 추가적인 하드웨어 필요
명령어 지연 시간 증가 가능성파이프라인 스톨 등으로 인해 개별 명령어의 지연 시간 증가 가능
활용 분야
CPU현대 CPU의 핵심 기술 중 하나
GPU병렬 처리 능력을 극대화하기 위해 사용
DSP실시간 신호 처리 시스템
기타
관련 용어명령어 수준 병렬성 (Instruction-Level Parallelism, ILP)
데이터 의존성 (Data Dependency)
제어 의존성 (Control Dependency)
분기 예측 (Branch Prediction)
슈퍼스칼라 (Superscalar)
아웃 오브 오더 실행 (Out-of-Order Execution)

2. 개념 및 동기

명령어 파이프라인은 컴퓨터의 명령어 처리를 여러 개의 독립적인 단계로 나누어 처리하는 방식이다. 각 단계는 폰 노이만 사이클의 각 단계(명령어 가져오기, 피연산자 가져오기, 명령어 실행, 결과 기록)에 해당할 수 있다. 각 단계 뒤에는 "파이프라인 레지스터"가 있어 명령어와 계산 정보를 저장하여 다음 단계에서 사용할 수 있도록 한다.

이러한 구성을 통해 중앙 처리 장치(CPU)는 각 클럭 사이클마다 명령어를 완료할 수 있어, 주어진 클럭 속도에서 더 많은 CPU 처리량을 낼 수 있다. 단계가 많을수록 각 단계의 작업량이 줄어들어 논리 게이트 지연이 감소하고, 더 높은 클럭 속도로 실행할 수 있다.

파이프라인 모델은 비용 대비 효율이 높다. 각 순간에 하나의 명령어만 한 단계에 있으며, 평균적으로 파이프라인 단계는 멀티 사이클 컴퓨터보다 비용이 적게 든다. 또한, 대부분의 논리가 사용되어 에너지 효율도 좋다.

하지만 파이프라인 컴퓨터는 비슷한 멀티 사이클 컴퓨터보다 복잡하고 비용이 많이 들 수 있다. 더 많은 논리 게이트, 레지스터, 복잡한 제어 장치가 필요하며, 명령어당 에너지는 적게 사용하지만 전체 에너지 사용량은 더 많을 수 있다.

파이프라인 컴퓨터의 제어 장치는 프로그램 명령에 따라 흐름을 시작, 계속, 중지하며, 각 단계의 명령어가 서로 방해하지 않도록 보장한다. 효율적으로 작동하면 각 단계마다 명령어가 있어 동시에 모든 명령어를 처리하고, 클럭 사이클마다 하나의 명령어를 완료할 수 있다. 그러나 프로그램이 다른 명령어 시퀀스로 전환되면 처리 중인 데이터를 폐기하고 다시 시작해야 하는 "스톨"이 발생할 수 있다. 이를 방지하기 위해 단계 간 간섭을 줄이는 설계가 필요하다.

명령어 파이프라인의 기본 아이디어는 명령어 처리를 독립적인 단계로 분할하고, 각 단계의 결과를 저장하여 제어 장치가 시간을 기준으로 명령어를 처리하도록 하는 것이다. 이는 모든 단계를 통합 처리하는 것보다 속도를 높여준다. 파이프라인은 각 단계가 동시에 데이터를 전송하고, 각 단계가 파이프처럼 다음 단계를 연결하는 것을 의미한다.

명령어 파이프라인의 기원은 ILLIAC II 프로젝트나 IBM 스트레치 프로젝트에서 찾을 수 있다. IBM 스트레치 프로젝트에서 "페치(fetch)", "디코드(decode)", "실행(execute)"이라는 용어가 생겨났다.

최근 CPU는 클럭 신호로 구동되며, 내부에는 논리 회로와 메모리(플립플롭)가 있다. 클럭 신호에 따라 플립플롭이 새로운 값을 받아들이고, 논리 회로가 이를 디코딩하는 데 시간이 걸린다. 논리 회로를 작은 부분으로 나누고 플립플롭을 삽입하면 각 회로의 처리 시간을 줄여 클럭 주기를 단축할 수 있다. 예를 들어, RISC 파이프라인은 명령어 페치, 명령어 디코드 및 레지스터 페치, 실행, 메모리 접근, 레지스터에 라이트백의 5단계로 나뉜다.

프로그래머나 컴파일러는 명령어가 순차적으로 실행된다고 가정하지만, 명령어 파이프라인에서는 이 가정이 옳지 않을 수 있다. 이로 인해 프로그램 동작이 잘못될 수 있는데, 이를 파이프라인 해저드라고 한다.

명령어 파이프라인은 명령어 완료 시간을 단축하는 것이 아니라, 동시에 처리하는 명령어 수를 늘려 처리량을 개선한다. 파이프라인 단계 수를 늘리면 동시에 처리하는 명령어 수가 늘어나 지연 시간을 줄일 수 있다. 현재 마이크로프로세서는 최소 2단계 파이프라인을 가지며(예: Atmel AVR, PIC), 인텔 Pentium 4 프로세서는 20단계 파이프라인을 가진다.

4단 파이프라인의 실행 예시는 다음과 같다.

시간(클럭)실행 내용
04개의 명령이 실행되기를 기다림.
1녹색 명령을 메모리에서 페치.
2
3
4
5
6
7
8빨간색 명령 완료.
9모든 명령 실행 완료.


2. 1. 파이프라인 단계 수

의존적인 단계의 수는 머신 아키텍처에 따라 다르다. 예를 들면 다음과 같다.

  • 1956–61년 IBM 스트레치 프로젝트는 인출, 디코딩, 실행 단계를 제안했다.
  • 클래식 RISC 파이프라인은 다음과 같이 구성된다.
  • * 명령어 인출
  • * 명령어 디코딩 및 레지스터 인출
  • * 실행
  • * 메모리 접근
  • * 레지스터 쓰기 백
  • Atmel AVR과 PIC 마이크로컨트롤러는 각각 2단계 파이프라인을 가지고 있다.
  • 많은 설계는 7, 10, 심지어 20단계(인텔 펜티엄 4와 같이)의 파이프라인을 포함한다.
  • 인텔의 후기 "Prescott" 및 "Cedar Mill" NetBurst 코어는 마지막 펜티엄 4 모델과 해당 펜티엄 D제온 파생 제품에 사용되었으며 31단계의 긴 파이프라인을 가지고 있다.
  • Xelerated X10q 네트워크 프로세서는 천 단계 이상으로 긴 파이프라인을 가지고 있지만, 이 경우 이 단계 중 200개는 개별적으로 프로그래밍된 명령어를 가진 독립적인 CPU를 나타낸다. 나머지 단계는 메모리 및 온칩 기능 유닛에 대한 접근을 조정하는 데 사용된다.[1][2]


파이프라인이 "더 깊게" (더 많은 수의 의존적인 단계로) 만들어지면, 주어진 단계는 더 간단한 회로로 구현될 수 있으며, 이는 프로세서 클럭이 더 빠르게 작동하도록 할 수 있다.[3] 이러한 파이프라인을 ''슈퍼파이프라인''이라고 부를 수 있다.[4]

프로세서가 매 사이클마다 명령어를 인출할 수 있다면 ''완전 파이프라인''이라고 한다. 따라서 일부 명령어 또는 조건이 새로운 명령어 인출을 방해하는 지연을 필요로 하는 경우, 프로세서는 완전 파이프라인이 아니다.

위 그림은 일반화된 4단 파이프라인을 나타낸다.

# 페치(Fetch): 읽기

# 디코드(Decode): 해석, 해독

# 실행(Execute)

# 라이트백(Write-back)

그림 위에 있는 회색 직사각형에는 실행을 기다리는 명령이 나열되어 있다. 아래 회색 직사각형에는 실행이 완료된 명령이 나열되어 있다. 가운데 직사각형이 파이프라인을 나타낸다.

실행은 다음과 같다.

시간(클럭)실행 내용
04개의 명령이 실행되기를 기다리고 있다.
1
2
3
4
5
6
7
8
9모든 명령을 실행했다.


3. 장점 및 단점

파이프라인 컴퓨터는 각 클럭 사이클마다 명령어를 완료할 수 있어, 주어진 클럭 속도에서 멀티 사이클 컴퓨터보다 더 많은 CPU 처리량을 허용한다. 하지만 파이프라인 프로세스 자체의 추가 오버헤드로 인해 지연 시간이 증가할 수 있다.[8] 파이프라인의 단계 수를 변경하여 성능을 조절할 수 있는데, 단계가 많을수록 각 단계의 논리 게이트 지연이 줄어들어 더 높은 클럭 속도로 실행할 수 있다.[8]

파이프라인 모델은 초당 명령어당 논리 게이트 수로 측정하는 비용 측면에서 경제적이다. 파이프라인 단계는 멀티 사이클 컴퓨터보다 비용이 적게 들고, 대부분의 논리가 지속적으로 사용된다. 반면, 아웃오브오더 컴퓨터는 많은 양의 유휴 논리를 가지는 경향이 있다. 파이프라인 컴퓨터는 명령어당 더 적은 에너지를 사용하는 경향도 있다.[8]

그러나 파이프라인 컴퓨터는 일반적으로 더 복잡하고 비용이 많이 든다. 더 많은 논리 게이트, 레지스터, 복잡한 제어 장치가 필요하며, 명령어당 에너지 소비는 적지만 전체 에너지 소비는 더 많을 수 있다. 아웃오브오더 CPU는 여러 명령어를 동시에 실행하여 초당 더 많은 명령어를 처리할 수 있다.[8]

파이프라인 컴퓨터는 각 단계에 명령어를 배치하여 동시에 처리하고, 클럭 사이클마다 하나의 명령어를 완료한다. 하지만 프로그램이 다른 명령어 시퀀스로 전환되면 처리 중인 데이터를 폐기하고 다시 시작해야 하는 "스톨"이 발생할 수 있다.[8]

3. 1. 장점


  • 프로세서의 사이클 시간을 단축할 수 있으며, 많은 경우 명령어 처리 속도를 향상시킨다.[1]
  • 가산기곱셈기 등의 조합 논리 회로는 회로 규모가 클수록 고속화할 수 있다. 대신 파이프라인을 사용하면 회로 규모는 작게 유지하면서 고속화할 수 있다.[1]

3. 2. 단점

파이프라인은 모든 상황에서 유리한 것은 아니며, 다음과 같은 단점도 가지고 있다.

  • 해저드 발생: 해저드가 발생하여 추가 비용이 발생한다. 파이프라인이 없는 프로세서는 한 번에 하나의 명령어만 실행하므로 해저드가 발생하지 않아 제어가 단순해지고, 더 저렴하게 제조할 수 있다.[8]
  • 명령어 지연 시간 증가: 명령어 지연 시간(1개의 명령어 실행에 걸리는 시간)이 파이프라인이 없는 경우보다 약간 길어진다. 이는 파이프라인이 각 단계 사이에 플립플롭을 삽입하기 때문이다.[8]
  • 성능 예측의 어려움: 파이프라인이 없는 프로세서에 비해 성능을 예측하기 어렵다. 명령어 파이프라인이 있는 프로세서는 프로그램(명령어의 배열)에 따라 성능이 달라지기 때문이다.[8]
  • 복잡성 증가: 파이프라인 컴퓨터는 일반적으로 비슷한 멀티 사이클 컴퓨터보다 더 복잡하고 비용이 많이 든다. 일반적으로 더 많은 논리 게이트, 레지스터 및 더 복잡한 제어 장치를 가지고 있다.[8]
  • 전력 소비 증가: 명령어당 더 적은 에너지를 사용하면서 전체 에너지를 더 많이 사용할 수 있다.[8]

4. 해저드(Hazard)

파이프라인의 속도가 느려지는 경우를 해저드라고 한다. 해저드에는 데이터 해저드, 컨트롤 해저드(명령어 해저드), 구조적 해저드가 있다.

순차적 실행 모델에서는 각 명령어가 다음 명령어가 시작되기 전에 완료된다고 가정하지만, 파이프라인 프로세서에서는 이 가정이 참이 아니다. 예상 결과에 문제가 있는 상황을 위험이라고 한다.

프로그래머나 컴파일러가 어셈블리 언어 코드를 작성할 때, 명령어는 쓰여진 순서대로 순차적으로 실행된다고 가정한다. 즉, 어떤 명령어가 완료된 후에 다음 명령어가 실행된다고 생각한다. 그러나 명령어 파이프라인이 있는 경우, 이 가정은 옳지 않을 수 있다. 이 때문에 프로그램의 동작이 잘못될 수 있는데, 이러한 상황을 파이프라인 해저드라고 한다.

4. 1. 데이터 해저드

파이프라인의 속도가 느려지는 경우를 해저드라고 한다. 해저드에는 데이터 해저드, 컨트롤 해저드, 구조적 해저드 등 여러 종류가 있다.

데이터 해저드는 예상된 시각에 연산자를 사용할 수 없을 때 발생한다. 예를 들어, 나눗셈 연산을 처리 중일 때는 그 다음 명령어는 처리할 수 있는 연산자가 없기 때문에 실행이 연기될 수밖에 없다.

순차적 실행 모델에서는 각 명령어가 다음 명령어가 시작되기 전에 완료된다고 가정하지만, 파이프라인 프로세서에서는 이 가정이 참이 아니다. 예상 결과에 문제가 있는 상황을 위험이라고 한다.

예를 들어, 가상 프로세서에서 다음과 같은 두 개의 레지스터 명령어를 생각해보자.

1. R5에 1 더하기

2. R5를 R6에 복사

프로세서에 5단계(명령어 페치, 명령어 디코드 및 레지스터 페치, 실행, 메모리 접근, 레지스터 쓰기 백)가 있는 경우, 명령어 1은 시간 ''t''1에 페치되고 실행은 ''t5''에 완료된다. 명령어 2는 ''t2''에 페치되고 ''t6''에 완료된다. 첫 번째 명령어는 다섯 번째 단계(''t5'')에 증가된 숫자를 R5에 저장할 수 있지만, 두 번째 명령어는 두 번째 단계(''t3'')에 R5에서 숫자(R6에 복사)를 가져올 수 있다. 이때 첫 번째 명령어가 아직 값을 증가시키지 않았기 때문에 위험이 발생한다.

이론적인 3단계 파이프라인(Load, Execute, Store)을 사용하는 예시는 다음과 같다.

단계의미
Load명령어를 메모리에서 읽어온다.
Execute명령어를 실행한다.
Store결과를 메모리나 레지스터에 저장한다.



어셈블리 언어의 다음과 같은 의사 코드를 실행한다고 가정한다.

```assembly

LOAD #40, A ; 40을 A에 로드

MOVE A, B ; A를 B로 복사

ADD #20, B ; 20을 B에 더함

STORE B, 0x300 ; B를 메모리 셀 0x300에 저장

```

이 코드의 실행 과정은 다음과 같다.


  • 클럭 1: LOAD 명령어가 메모리에서 페치된다.
  • 클럭 2: LOAD 명령어가 실행되고, 동시에 MOVE 명령어가 메모리에서 페치된다.
  • 클럭 3: LOAD 명령어는 Store 단계에 있으며, 그 결과(40)는 레지스터 A에 저장된다. 동시에 MOVE 명령어가 실행되려 한다. A에서 B로 내용을 옮기는 명령이므로, 바로 앞의 LOAD 명령어의 완료를 기다려야 한다. 이때 포워딩이라는 기법을 사용한다. 즉, LOAD 명령어에서 A에 저장해야 할 값은 Execute 단계에서 이미 구해져 있으므로, MOVE 명령어는 Execute 단계의 입력으로 이전 명령어의 Execute 단계의 결과를 직접 이용한다.
  • 클럭 4: STORE 명령어가 로드되고, MOVE 명령어는 완료되며, ADD 명령어를 계산 중이다. ADD 명령어 역시 포워딩에 의해 이전 명령어의 Execute 단계의 결과를 이용한다.


이와 같이 명령어에는 다른 명령어의 결과에 의존하는 경우가 있다. 여러 명령어가 피연산자로서 특정 위치(메모리, 레지스터)를 참조하는 경우, 프로그램상의 순서와 다른 순서로 실행하면 해저드가 발생할 수 있다.

4. 1. 1. 해결 방법

파이프라인 프로세서에서 명령어 간의 의존성 때문에 발생하는 해저드(Hazard)를 해결하기 위한 여러 기술이 있다. 이러한 해저드는 데이터, 컨트롤, 구조적 해저드로 나뉜다.

  • 데이터 해저드: 연산에 필요한 데이터를 특정 시점에 사용할 수 없을 때 발생한다.
  • 컨트롤 해저드: 명령어를 즉시 사용할 수 없을 때 발생한다.
  • 구조적 해저드: 두 명령어가 동시에 특정 하드웨어에 접근하려 할 때 발생한다.


이러한 해저드를 해결하기 위해 다음과 같은 세 가지 주요 기술이 사용된다.

  • 파이프라인 중단 (Pipeline Stall): 필요한 값을 사용할 수 있을 때까지 새로운 명령어의 실행을 중단시킨다. 이로 인해 파이프라인에 빈 슬롯, 즉 '버블'이 발생하여 일시적으로 작업이 수행되지 않는다.[6][7]
  • 피연산자 전달 (Operand Forwarding): 계산된 값을 생성한 명령어가 완료되기 전에, 파이프라인의 다른 위치에 있는 미래의 명령어에 전달하는 추가 데이터 경로를 사용한다. 이를 통해 명령어 실행 지연을 줄일 수 있다.[6][7]
  • 비순차적 실행 (Out-of-Order Execution): 현재 명령어에 종속되지 않고 즉시 실행 가능한 다른 명령어를 찾아 실행하는 최적화 기법이다.

예시다음은 3단계 파이프라인(Load, Execute, Store)을 사용하는 이론적인 예시다.

단계의미
Load메모리에서 명령어를 읽어온다.
Execute명령어를 실행한다.
Store결과를 메모리나 레지스터에 저장한다.



다음 의사 코드를 실행하는 과정을 통해 설명한다.

```assembly

LOAD #40, A ; 40을 A에 로드

MOVE A, B ; A를 B로 복사

ADD #20, B ; 20을 B에 더함

STORE B, 0x300 ; B를 메모리 셀 0x300에 저장

```
실행 과정


  • 클럭 1: LOAD 명령어가 메모리에서 읽혀진다(Load).
  • 클럭 2: LOAD 명령어가 실행(Execute)되고, 동시에 MOVE 명령어가 메모리에서 읽혀진다(Load).
  • 클럭 3: LOAD 명령어는 저장(Store) 단계에서 레지스터 A에 결과(40)를 저장한다. MOVE 명령어는 A의 내용을 B로 옮기기 위해 이전 LOAD 명령어의 완료를 기다려야 한다. 이때, 피연산자 전달을 사용하여 LOAD 명령어의 Execute 단계에서 이미 계산된 값을 MOVE 명령어의 Execute 단계 입력으로 직접 사용한다.
  • 클럭 4: STORE 명령어가 로드(Load)되고, MOVE 명령어는 완료되며, ADD 명령어가 계산 중이다. ADD 명령어 역시 피연산자 전달을 통해 이전 명령어의 Execute 단계 결과를 사용한다.


이처럼, 명령어 간의 의존성이 존재할 때, 위에서 설명한 여러 기법을 통해 해저드를 방지하거나 처리한다. 초기 DSP 및 RISC 프로세서에서는 프로그래머가 이러한 종속성을 피하도록 권고하거나, NOP을 삽입하여 파이프라인의 이점을 부분적으로 무효화하는 방식으로 해결하기도 했다.

4. 2. 컨트롤 해저드 (명령어 해저드)

컨트롤 해저드(명령어 해저드)는 명령어를 당장 사용할 수 없을 때 발생한다. 캐시에 명령어가 저장되어 있으면 빠르게 실행할 수 있지만, 해당 명령어가 없으면 메모리에서 가져와야 하므로 시간이 오래 걸려 파이프라인 속도가 느려진다.[8]

일반적인 명령어 순서에서 벗어나는 분기는 프로세서가 단일 시간 주기로 처리할 수 없을 때 파이프라인에서 순차적으로 명령어를 계속 가져오는 문제를 야기한다. 프로그래머가 프로그램의 다른 부분으로 제어를 전환하면, 이미 가져온 명령어는 실행될 수 없다.

조건부 분기는 아직 발생하지 않은 계산에 따라 분기 여부가 결정되므로 더 큰 문제를 일으킨다. 다양한 프로세서는 분기 예측을 시도하여 분기가 실행될지 여부를 예측하고, 두 가지 경우의 프로그램 시퀀스(적극적 실행)를 실행한다. 예측이 실패하면 잘못된 추측과 관련된 작업을 파이프라인에서 플러시해야 한다.

정확한 분기 예측을 하는 프로세서는 분기로 인한 성능 저하를 최소화할 수 있지만, 예측이 실패하면 잘못된 코드 경로를 플러시하는 추가 작업이 필요하다.

파이프라인 프로세서용 프로그램은 속도 손실을 최소화하기 위해 의도적으로 분기를 피한다. 프로그래머는 순차적 실행으로 일반적인 경우를 처리하고, 비정상적인 경우에만 분기한다. gcov와 같은 코드 커버리지 분석 도구는 특정 분기의 실행 빈도를 측정하여 코드를 최적화하는 데 도움을 준다. 분기 없는 코드로 일반적인 경우와 비정상적인 경우를 모두 처리할 수도 있다.

실행 코드에 조건 분기 명령이 많으면 파이프라인의 처리량 향상을 기대하기 어렵다. 프로세서는 다음에 실행할 명령을 알 수 없어 조건 분기 명령 실행 후 분기 대상이 결정될 때까지 파이프라인이 비워진다. 분기 대상 계산이 완료되면 다음 명령이 결정되고 파이프라인이 다시 작동한다. 극단적인 경우, 파이프라인의 대부분이 비워지면 파이프라인이 없는 프로세서보다 성능이 저하될 수 있다.

4. 2. 1. 해결 방법

명령어 파이프라인에서 발생하는 속도 저하, 즉 해저드(Hazard)를 해결하기 위한 여러 방법이 있다.
분기 예측:일반적인 명령어 실행 순서에서 벗어나는 분기는 성능 저하를 유발할 수 있다. 프로세서가 분기 명령어를 처리할 때, 다음 명령어를 즉시 가져올 수 없기 때문이다. 특히 조건부 분기는 아직 발생하지 않은 계산 결과에 따라 분기 여부가 결정되므로 더욱 문제가 된다.

이러한 문제를 해결하기 위해 다양한 프로세서들은 분기 예측 기술을 사용한다. 분기 예측은 분기가 실제로 일어날지, 아니면 일어나지 않을지를 미리 예측하여 두 가지 경우의 명령어 실행을 모두 준비한다(적극적 실행). 만약 예측이 맞으면 성능 저하 없이 바로 다음 명령어를 실행할 수 있다. 예측이 실패하면 잘못 실행된 명령어들을 파이프라인에서 플러시하고 올바른 위치에서 실행을 다시 시작해야 한다.

분기 예측의 정확도가 높을수록 분기로 인한 성능 저하는 최소화된다. 하지만 예측이 실패하면 프로세서가 추가적인 작업을 해야 하므로 성능에 부정적인 영향을 미칠 수 있다.
분기 없는 코드 작성:파이프라인 프로세서를 위한 프로그램을 작성할 때, 속도 손실을 최소화하기 위해 의도적으로 분기를 피하는 경우가 많다. 일반적인 경우는 순차적으로 실행하고, 예외적인 경우에만 분기하도록 코드를 작성하는 것이다.

gcov와 같은 코드 커버리지 분석 도구를 사용하면, 프로그래머는 특정 분기가 실제로 얼마나 자주 실행되는지 측정하고 코드를 최적화할 수 있다. 경우에 따라 분기 없는 코드를 사용하여 일반적인 경우와 예외적인 경우를 모두 처리할 수도 있다.
슈퍼 파이프라인:파이프라인의 각 단계를 더 세분화하여 여러 단계로 나누는 슈퍼 파이프라인 기법도 있다. 예를 들어, 3단계 파이프라인을 각 단계별로 2개씩 나누어 6단계로 만들 수 있다. 이렇게 하면 동시에 여러 명령어를 처리할 수 있어 성능 향상을 기대할 수 있다.
기타:

  • 코드 최적화: 코드 커버리지 분석 결과를 바탕으로, 분기가 자주 발생하는 부분을 최적화하여 분기 횟수를 줄일 수 있다.
  • 자기 수정 코드 지양: 명령어 파이프라인에서는 읽어들인 명령어가 즉시 실행되지 않으므로, 프로그램 카운터에 매우 가까운 명령어를 수정하는 자기 수정 코드는 문제를 일으킬 수 있다. 캐시 메모리는 이러한 현상을 더욱 악화시키므로, 자기 수정 코드는 사용하지 않는 것이 좋다.

4. 3. 구조적 해저드

구조적 해저드는 두 명령어가 동시에 특정 하드웨어에 접근하려 할 때 발생한다. 예를 들어, 어떤 명령어가 실행이나 쓰기를 위해 메모리에 접근하는 동안 다른 명령어가 메모리에서 읽혀지는 경우가 있다.[1]

4. 3. 1. 해결 방법

파이프라인이 느려지는 경우를 해저드라고 한다. 해저드의 종류는 다음과 같다.

  • 데이터 해저드: 예상된 시각에 연산자가 사용 불가능할 경우에 발생한다. 예를 들어, 나눗셈 연산을 처리 중이라면 그 다음 명령어는 처리할 수 있는 연산자가 없기 때문에 실행이 연기될 수밖에 없다.
  • 컨트롤 해저드 (명령어 해저드): 명령어를 당장 사용할 수 없을 때 발생한다. 캐시에 명령어가 저장되어 있을 경우 빠르게 명령어를 실행할 수 있지만, 해당 명령어가 없을 경우 메모리로부터 가져와야 하기 때문에 오랜 시간이 걸리고 결국 파이프라인의 속도가 떨어진다.
  • 구조적 해저드: 두 명령어가 동시에 어떤 하드웨어에 접근해야 할 때 발생한다. 예를 들어, 어떤 명령어가 실행이나 쓰기를 위해서 메모리에 접근해야 할 때, 다른 명령어가 메모리에서 읽혀지는 경우 이런 해저드가 발생한다.

5. 파이프라인 붕괴

명령어 수행 과정 중 분기가 발생하면, 분기 전에 명령 수행 과정에 있던 명령어들(파이프라인의 5단계를 진행 중인)은 버려진다. 이후 분기가 종료되면 예외 처리 복귀 명령을 통해 복구시켜야 한다. 버려지는 명령어의 기준은 예외 상황마다 다르다.[8]

파이프라인 프로세서는 파이프라인을 중단시키고 버블을 생성하여 해저드(hazard)를 처리할 수 있다. 이로 인해 유용한 작업이 수행되지 않는 하나 이상의 사이클이 발생한다.

오른쪽 그림에서 사이클 3에서 프로세서는 보라색 명령어를 디코딩할 수 없다. 이는 프로세서가 디코딩이 녹색 명령어의 실행으로 생성된 결과에 의존한다고 판단하기 때문일 수 있다. 녹색 명령어는 예정대로 실행 단계와 쓰기 단계로 진행될 수 있지만, 보라색 명령어는 페치 단계에서 한 사이클 동안 중단된다. 사이클 3 동안 페치될 예정이었던 파란색 명령어는 한 사이클 동안 중단되고, 그 뒤의 빨간색 명령어 역시 마찬가지이다.

버블(그림에서 파란색 타원) 때문에, 프로세서의 디코딩 회로는 사이클 3 동안 유휴 상태가 된다. 실행 회로는 사이클 4 동안, 쓰기 회로는 사이클 5 동안 유휴 상태가 된다.

버블이 파이프라인에서 벗어나면(사이클 6에서), 정상적인 실행이 재개된다. 하지만 모든 것이 한 사이클 늦어진다. 색상으로 표시된 네 개의 명령어를 완전히 실행하는 데 7 사이클이 아닌 8 사이클(사이클 1부터 8까지)이 걸린다.

실행 중에 어떤 중단이 발생하면 파이프라인에 "버블"이라고 불리는 아무것도 하지 않는 부분이 생긴다. 사이클 2에서 보라색 명령의 페치에 지연이 발생하여 사이클 3의 디코드 스테이지에 버블이 발생했다. 보라색 이후의 명령은 모두 1클록 사이클만 지연되지만, 보라색 명령 이전의 명령은 정상적으로 처리가 계속된다.

위의 그림과 비교하면 버블이 발생했기 때문에 실행에 걸리는 클록 사이클 수가 7에서 8로 증가했다.

버블은 스톨(stall)과 비슷하며, 각 스테이지에서는 아무것도 하지 않는다. 그러나 NOP 명령을 버블 부분에 삽입하면 버블을 제거할 수 있다.

파이프라인이 길어지면 프로그램 상의 분기가 발생했을 때 불리하며, 파이프라인 전체를 플러시할 필요가 있지만, 분기 예측으로 어느 정도 대처할 수 있다. 분기 예측이 불충분하면 상황은 악화된다. 고성능 컴퓨팅 등의 특정 분야에서는 좀처럼 분기하지 않는 프로그램을 작성할 수 있으며, 파이프라인이 길수록 성능 향상이 기대된다. 분기가 빈번하게 발생하는 경우, 가장 분기할 것 같은 방향의 명령을 파이프라인에 공급함으로써, 분기 예측 실패로 인한 파이프라인 플러시로 발생하는 성능 손실을 줄일 수 있다.

실행 코드에 다수의 조건 분기 명령이 있으면, 파이프라인에 의한 처리량 향상은 기대할 수 없다. 프로세서가 다음에 실행해야 할 명령을 알 수 없기 때문에, 조건 분기 명령을 실행하여 분기 대상이 결정될 때까지, 파이프라인은 비어(버블)진다. 분기 대상의 계산이 완료되면, 다음에 실행해야 할 명령이 결정되고, 파이프라인이 다시 기능하게 된다. 극단적인 경우, 파이프라인의 1 스테이지 외 모든 스테이지가 비어(버블)진다면, 파이프라인이 없는 프로세서와 성능에 큰 차이가 없는 상황이 되며, 오히려 파이프라인이 없는 프로세서보다 성능이 저하된다 (스테이지 간 오버헤드가 있기 때문에).

6. 역사

파이프라인의 선구적인 사용은 ILLIAC II 프로젝트와 IBM Stretch 프로젝트에서 이루어졌지만, 더 간단한 버전은 1939년 Z1과 1941년 Z3에서 더 일찍 사용되었다.[5]

1970년대 후반 벡터 프로세서 및 배열 프로세서와 같은 슈퍼컴퓨터에서 파이프라인이 본격적으로 시작되었다. 초창기 슈퍼컴퓨터 중 하나는 Control Data Corporation에서 제작한 Cyber 시리즈였다. Cyber 시리즈의 수석 설계자인 세이무어 크레이는 나중에 Cray Research의 수장이 되었다. 크레이는 곱셈 및 덧셈/뺄셈 기능 모두에 파이프라인을 사용하여 XMP 계열의 슈퍼컴퓨터를 개발했다. 이후 Star Technologies는 로저 첸(Roger Chen)이 개발한 병렬 처리(병렬로 작동하는 여러 파이프라인 기능)를 추가했다. 1984년, Star Technologies는 제임스 브래들리(James Bradley)가 개발한 파이프라인 분할 회로를 추가했다.

파이프라인은 슈퍼컴퓨터에만 국한되지 않았다. 1976년, Amdahl Corporation의 470 시리즈 범용 메인프레임은 7단계 파이프라인과 특허받은 분기 예측 회로를 가지고 있었다. 1961년의 IBM 7030(스트레치)는 마이크로 프로그램 방식으로 파이프라인과 분기 예측을 사용했다.[9] 이후의 메인프레임 대부분에서도 사용되고 있다.

1970년대에 벡터 컴퓨터를 시작으로 오늘날의 고성능 컴퓨팅에 직접 연결되는 머신 개발이 시작되었다. 하이엔드 고성능 컴퓨팅 머신에서는 특수한 설비와 코어 냉각이 필요했다. 초기의 대표적인 슈퍼컴퓨터로는 CDC사의 CDC 6600과 CDC 7600이 있는데, 그 중심적인 설계자인 시모어 크레이는 후에 CDC를 나와 크레이사를 설립했다. 크레이는 X-MP 계열의 슈퍼컴퓨터를 개발했으며, 곱셈과 덧셈 모두에 파이프라인을 사용했다. 후에 Star Technologies사가 파이프라인을 다른 레벨의 병렬 처리에 사용했다. 이는 여러 파이프라인화된 기능이 병렬적으로 가동되는 것으로, 동사 기술자인 Roger Chen이 개발했다.

현재 파이프라인은 개인용 컴퓨터용 대부분의 마이크로프로세서를 비롯해, 임베디드 프로세서에서도 일부(특수한 인터럽트 응답 성능을 요구하는 경우 등)를 제외하고 사용되고 있다.

참조

[1] 간행물 Xelerated's Xtraordinary NPU — World's First 40Gb/s Packet Processor Has 200 CPUs http://www.linleygro[...] 2017-03-20
[2] 웹사이트 Xelerated Brings Programmable 40 Gbits/S Technology to the Mainstream Ethernet https://www.eetimes.[...] 2003-05-31
[3] 서적 Modern Processor Design https://books.google[...] McGraw-Hill Professional
[4] 서적 Design of Computers and Other Complex Digital Devices https://books.google[...] Prentice Hall
[5] 간행물 Konrad Zuse's Legacy: The Architecture of the Z1 and Z3 http://ed-thelen.org[...] 2022-07-03
[6] 웹사이트 CMSC 411 Lecture 19, Pipelining Data Forwarding http://www.csee.umbc[...] University of Maryland Baltimore County Computer Science and Electrical Engineering Department 2020-01-22
[7] 웹사이트 High performance computing, Notes of class 11 http://hpc.serc.iisc[...] hpc.serc.iisc.ernet.in 2014-02-08
[8] 뉴스 Best Extrime Processor: Xelerated X10q http://www.linleygro[...] Microprocessor Report
[9] 문서 IBM Stretch (7030) -- Aggressive Uniprocessor Parallelism http://www.cs.clemso[...]



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com