Pipeline의 의미
작업을 여러 단계로 나누어 순차적이거나 병렬적으로 처리하는 방식을 의미해. 파이프라인은 각 단계를 거쳐 데이터를 처리하여 효율적으로 작업을 완료할 수 있게 도와주며, 다양한 분야에서 중요한 개념으로 활용
동일 시간 대비 처리량(Throughput) 이 크게 향상
Instruction 처리에서의 Pipeline

작업 분리
- IF (Instruction Fetch)
- ID (Instructino Decode)
- EX (Excute)
- MEM (Access Memory)
- WB (Write Back)
IF: 200ps
ID: 100ps
EX: 200ps
MEM: 200ps
WB: 100ps
1개의 Instruction 처리 시
Single-Cycle: 800ps
Pipeline: 1000ps (Clock cycle를 맞추기 위해서 단위 작업마다 가장 긴(200ps) 시간을 적용
N개의 Instructino 처리 시
Single-Cycle: 800 * N PS
Pipeline: 1000 + 200 (N-1) PS
성능 향상:
800 * N / 1000 + 200(N-1) = 4 (N이 매우 크다고 가정, 근사치)
Hazard
- Structure Hazard:
여러 명령어가 동시에 같은 하드웨어 자원을 사용하려고 할 때 발생함. 예를 들어, CPU 파이프라인에서 두 개의 명령어가 동시에 메모리 접근을 시도할 때 구조적 충돌이 발생하여 파이프라인 처리가 지연됨.
- 해결법: Instruction Memory와 일반 Memory를 분리해서 해결 (구조적으로 해결 가능)
- Data Hazard:
한 명령어가 사용할 데이터가 다른 명령어의 연산 결과에 의존할 때 발생함. 예를 들어, 이전 명령어의 연산 결과를 다음 명령어가 필요로 할 때, 연산이 완료되지 않아서 생기는 데이터 충돌임.
- Forwarding: 이전 작업에서 완료된 결과를 즉각적으로 활용함. (이전 Instruction이 완료될 때까지 기다리지 않음) 하지만 완전히 피하지 못할 때가 있음 (LDUR -> ADD 시 ADD가 LDUR 결과에 의존적일 때 해당 방법으로는 해결할 수 없음. 해당 공백을 Bubble이라고 함.)
- Code Scheduling: 코드 순서를 재배치하여 Bubble 발생을 최소화.
다른 명령어의 결과에 의존적인 명령어를 적절히 배치하여 Bubble 발생이 안나도록 함.
- Control Hazard: 분기 명령어로 인해 프로그램의 제어 흐름이 예측할 수 없는 방향으로 변경될 때 발생함. 이로 인해 CPU가 어떤 명령어를 다음에 실행할지 확정할 수 없어서 파이프라인이 지연됨.
- Branch Prediction: 다음 작업에 대해 어떤 결과가 나올 것이라고 예측하고 실행. 만약 예측에 실패할 경우 해당 작업을 무효화 시킴.
- static: for-loop의 경우 backward가 자주 발생하여 taken, if의 경우는 not taken.
- dynamic: 이전의 기록들을 기반으로 설정
Pipeline Register
- stage(작업)별 사이에 존재하는 Register. 상태, 이전값들을 저장하기 위해 필요
- naming: (이전 stage)/(이후 stage) ex) IF/ID, EX/MEM
LDUR X1, [X2, offset] 예시
IF
1. PC 값을 통해 Instruction Memory에서 Instruction를 불러온다.
2. PC값, 읽은 Instruction 값을 IF/ID에 저장한다.
ID
1. 저장된 Instruction을 통해 X2에 값을 얻는다. 또한 offset를 얻고 sign-extension을 한다.
2. 상기 값들을 저장하고, 이전에 저장했던 PC값, 그리고 X1 (write back하기 위함)을 ID/EX에 저장한다.
EX
1. 연산을 수행해서 타겟 주솟값을 구한다.
2. 타겟 주솟값, PC값 (Branch가 아니라서 그대로 옮김), X1 (Write back을 위함)을 EX/MEM에 저장한다.
MEM
1. 타겟 주솟값으로 메모리에 접근해서 읽는다.
2. 메모리에 읽힌 값, X1를 MEM/WB에 저장한다.
WB
1. X1에 Write back 한다.